天天看點

[Spring cloud 一步步實作廣告系統] 19. 監控Hystrix Dashboard

在之前的18次文章中,我們實作了廣告系統的

廣告投放

廣告檢索

業務功能,中間使用到了

服務發現Eureka

服務調用Feign

,

網關路由Zuul

以及

錯誤熔斷Hystrix

Spring Cloud

元件。

簡單調用關系:

[Spring cloud 一步步實作廣告系統] 19. 監控Hystrix Dashboard
但是系統往往都會報錯,我們之前定義了一些容錯類和方法,但是隻是在控制台可以看到錯誤資訊,我們想要統計一些資料,怎麼才能更直覺的看到我們的服務調用情況呢,接下來,和大家讨論一個新的熔斷監控元件

Hystrix Dashboard

,顧名思義,從名字上我們就能看出來,它是監控的圖形化界面。

Hystrix 在服務中的使用

結合openfeign使用

在我們實際的項目當中,使用的最多的就是結合

FeignClient#fallback

Hystrix

一起來實作熔斷,我們看一下我們在

mscx-ad-feign-sdk

中的實作。

@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的實作類:

@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

服務。

@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

,我們看一下這個類的源碼:

@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/>
     * default => see {@link com.netflix.hystrix.contrib.javanica.command.GenericCommand#getFallback()}
     *
     * @return method name
     */
    String fallbackMethod() default "";

    ...
}           

我們主要關注2個點:

  1. @Target({ElementType.METHOD})

    表明目前的注解隻能應用在方法上面。
  2. 可直接定義

    fallbackMethod

    來保證容錯。這個方法有一個缺陷,就是必須和執行方法在同一個類檔案中,這就會造成我們的方法在實作的時候,顯得特别的備援和不夠優雅。

以我們的

mscx-ad-search

中的廣告查詢為例:

@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方法來實作。

建立dashboard project

上述代碼我們看了Hystrix實作熔斷的2種方式,接下來我們來實作請求監控的圖形化界面,建立

mscx-ad-dashboard

,Let's code.

依然遵從我們springboot項目的三部曲:

  1. 加依賴
    <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>           
  2. 加注解
    /**
    * AdDashboardApplication for Hystrix Dashboard 啟動類
    *
    * @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
    * @since 2019/8/15
    */
     @SpringBootApplication
     @EnableDiscoveryClient
     @EnableHystrixDashboard
     public class AdDashboardApplication {
    
     public static void main(String[] args) {
         SpringApplication.run(AdDashboardApplication.class, args);
     }
     }           
  3. 改配置
    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: "*"`           

直接啟動,可以看到如下頁面:

[Spring cloud 一步步實作廣告系統] 19. 監控Hystrix Dashboard

添加要監控的服務位址:

[Spring cloud 一步步實作廣告系統] 19. 監控Hystrix Dashboard