在以前的18次文章中,咱们实现了广告系统的广告投放
,广告检索
业务功能,中间使用到了 服务发现Eureka
,服务调用Feign
,网关路由Zuul
以及错误熔断Hystrix
等Spring Cloud
组件。 简单调用关系: java
可是系统每每都会报错,咱们以前定义了一些容错类和方法,可是只是在控制台能够看到错误信息,咱们想要统计一些数据,怎么才能更直观的看到咱们的服务调用状况呢,接下来,和你们讨论一个新的熔断监控组件Hystrix Dashboard
,顾名思义,从名字上咱们就能看出来,它是监控的图形化界面。web
在咱们实际的项目当中,使用的最多的就是结合FeignClient#fallback
和Hystrix
一块儿来实现熔断,咱们看一下咱们在mscx-ad-feign-sdk
中的实现。spring
@FeignClient(value = "mscx-ad-sponsor", fallback = SponsorClientHystrix.class) public interface ISponsorFeignClient { @RequestMapping(value = "/ad-sponsor/plan/get", method = RequestMethod.POST) CommonResponse<list<adplanvo>> getAdPlansUseFeign(@RequestBody AdPlanGetRequestVO requestVO); @RequestMapping(value = "/ad-sponsor/user/get", method = RequestMethod.GET) /** * Feign 埋坑之 若是是Get请求,必须在全部参数前添加{@link RequestParam},不能使用{@link Param} * 会被自动转发为POST请求。 */ CommonResponse getUsers(@RequestParam(value = "username") String username); }
在上述代码中,咱们自定义了一个feignclient,而且给了这个client一个fallback的实现类:springboot
@Component public class SponsorClientHystrix implements ISponsorFeignClient { @Override public CommonResponse<list<adplanvo>> getAdPlansUseFeign(AdPlanGetRequestVO requestVO) { return new CommonResponse<>(-1, "mscx-ad-sponsor feign & hystrix get plan error."); } @Override public CommonResponse getUsers(String username) { return new CommonResponse<>(-1, "mscx-ad-sponsor feign & hystrix get user error."); } }
这个fallback类实现了咱们自定义的ISponsorFeignClient
,那是由于fallback的方法必须和原始执行类的方法签名保持一致,这样在执行失败的时候,能够经过反射映射到响应的降级方法/容错方法。 在mscx-ad-search
服务中,咱们经过注入ISponsorFeignClient
来调用咱们的mscz-ad-sponsor
服务。app
@RestController @Slf4j @RequestMapping(path = "/search-feign") public class SearchFeignController { /** * 注入咱们自定义的FeignClient */ private final ISponsorFeignClient sponsorFeignClient; @Autowired public SearchFeignController(ISponsorFeignClient sponsorFeignClient) { this.sponsorFeignClient = sponsorFeignClient; } @GetMapping(path = "/user/get") public CommonResponse getUsers(@Param(value = "username") String username) { log.info("ad-search::getUsersFeign -> {}", JSON.toJSONString(username)); CommonResponse commonResponse = sponsorFeignClient.getUsers(username); return commonResponse; } }
HystrixCommand
其实Hystrix自己提供了一种直接在方法中应用的方式,就是使用@ com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand
,咱们看一下这个类的源码:ide
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface HystrixCommand { ... /** * Specifies a method to process fallback logic. * A fallback method should be defined in the same class where is HystrixCommand. * Also a fallback method should have same signature to a method which was invoked as hystrix command. * for example: * <code> * @HystrixCommand(fallbackMethod = "getByIdFallback") * public String getById(String id) {...} * * private String getByIdFallback(String id) {...} * </code> * Also a fallback method can be annotated with {@link HystrixCommand} * <p></p> * default => see {@link com.netflix.hystrix.contrib.javanica.command.GenericCommand#getFallback()} * * @return method name */ String fallbackMethod() default ""; ... }
咱们主要关注2个点:spring-boot
@Target({ElementType.METHOD})
代表当前的注解只能应用在方法上面。fallbackMethod
来保证容错。这个方法有一个缺陷,就是必须和执行方法在同一个类文件中,这就会形成咱们的方法在实现的时候,显得特别的冗余和不够优雅。以咱们的mscx-ad-search
中的广告查询为例:fetch
@Service @Slf4j public class SearchImpl implements ISearch { /** * 查询广告容错方法 * * @param e 第二个参数能够不指定,若是须要跟踪错误,就指定上 * @return 返回一个空map 对象 */ public SearchResponse fetchAdsFallback(SearchRequest request, Throwable e) { System.out.println("查询广告失败,进入容错降级 : %s" + e.getMessage()); return new SearchResponse().builder().adSlotRelationAds(Collections.emptyMap()).build(); } @HystrixCommand(fallbackMethod = "fetchAdsFallback") @Override public SearchResponse fetchAds(SearchRequest request) { ... } }
在咱们请求出错的时候,会转到咱们的fallback方法,这个实现是经过在应用启动的时候,咱们开始了@EnableCircuitBreaker
注解,这个注解会经过AOP拦截全部的HystrixCommand
方法,将HystrixCommand
整合到springboot的容器中,而且将注解标注的方法放入hystrix的线程中,一旦失败,经过反射调用fallback方法来实现。ui
上述代码咱们看了Hystrix实现熔断的2种方式,接下来咱们来实现请求监控的图形化界面,建立mscx-ad-dashboard
,Let's code. 依然听从咱们springboot项目的三部曲:this
加依赖
<dependencies> <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-hystrix</artifactid> <version>1.2.7.RELEASE</version> </dependency> <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-hystrix-dashboard</artifactid> <version>1.2.7.RELEASE</version> </dependency> <!--eureka client--> <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-netflix-eureka-client</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-actuator</artifactid> </dependency> </dependencies>
加注解
/** * AdDashboardApplication for Hystrix Dashboard 启动类 * * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a> * @since 2019/8/15 */ @SpringBootApplication @EnableDiscoveryClient @EnableHystrixDashboard public class AdDashboardApplication { public static void main(String[] args) { SpringApplication.run(AdDashboardApplication.class, args); } }
改配置
server: port: 1234 spring: application: name: mscx-ad-dashboard eureka: client: service-url: defaultZone: http://server1:7777/eureka/,http://server2:8888/eureka/,http://server3:9999/eureka/ management: endpoints: web: exposure: include: "*"`
直接启动,能够看到以下页面:
添加要监控的服务地址: </list<adplanvo></list<adplanvo>