在之前的18次文章中,我們實(shí)現(xiàn)了廣告系統(tǒng)的廣告投放
,廣告檢索
業(yè)務(wù)功能,中間使用到了 服務(wù)發(fā)現(xiàn)Eureka
,服務(wù)調(diào)用Feign
,網(wǎng)關(guān)路由Zuul
以及錯(cuò)誤熔斷Hystrix
等Spring Cloud
組件。
簡(jiǎn)單調(diào)用關(guān)系:
公司主營業(yè)務(wù):成都做網(wǎng)站、網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出寧武免費(fèi)做網(wǎng)站回饋大家。
但是系統(tǒng)往往都會(huì)報(bào)錯(cuò),我們之前定義了一些容錯(cuò)類和方法,但是只是在控制臺(tái)可以看到錯(cuò)誤信息,我們想要統(tǒng)計(jì)一些數(shù)據(jù),怎么才能更直觀的看到我們的服務(wù)調(diào)用情況呢,接下來,和大家討論一個(gè)新的熔斷監(jiān)控組件Hystrix Dashboard
,顧名思義,從名字上我們就能看出來,它是監(jiān)控的圖形化界面。
在我們實(shí)際的項(xiàng)目當(dāng)中,使用的最多的就是結(jié)合FeignClient#fallback
和Hystrix
一起來實(shí)現(xiàn)熔斷,我們看一下我們?cè)?code>mscx-ad-feign-sdk中的實(shí)現(xiàn)。
@FeignClient(value = "mscx-ad-sponsor", fallback = SponsorClientHystrix.class)
public interface ISponsorFeignClient {
@RequestMapping(value = "/ad-sponsor/plan/get", method = RequestMethod.POST)
CommonResponse> getAdPlansUseFeign(@RequestBody AdPlanGetRequestVO requestVO);
@RequestMapping(value = "/ad-sponsor/user/get", method = RequestMethod.GET)
/**
* Feign 埋坑之 如果是Get請(qǐng)求,必須在所有參數(shù)前添加{@link RequestParam},不能使用{@link Param}
* 會(huì)被自動(dòng)轉(zhuǎn)發(fā)為POST請(qǐng)求。
*/
CommonResponse getUsers(@RequestParam(value = "username") String username);
}
在上述代碼中,我們自定義了一個(gè)feignclient,并且給了這個(gè)client一個(gè)fallback的實(shí)現(xiàn)類:
@Component
public class SponsorClientHystrix implements ISponsorFeignClient {
@Override
public CommonResponse> 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.");
}
}
這個(gè)fallback類實(shí)現(xiàn)了我們自定義的ISponsorFeignClient
,那是因?yàn)閒allback的方法必須和原始執(zhí)行類的方法簽名保持一致,這樣在執(zhí)行失敗的時(shí)候,可以通過反射映射到響應(yīng)的降級(jí)方法/容錯(cuò)方法。
在mscx-ad-search
服務(wù)中,我們通過注入ISponsorFeignClient
來調(diào)用我們的mscz-ad-sponsor
服務(wù)。
@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
其實(shí)Hystrix本身提供了一種直接在方法中應(yīng)用的方式,就是使用@ com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand
,我們看一下這個(gè)類的源碼:
@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:
*
* @HystrixCommand(fallbackMethod = "getByIdFallback")
* public String getById(String id) {...}
*
* private String getByIdFallback(String id) {...}
*
* Also a fallback method can be annotated with {@link HystrixCommand}
*
* default => see {@link com.netflix.hystrix.contrib.javanica.command.GenericCommand#getFallback()}
*
* @return method name
*/
String fallbackMethod() default "";
...
}
我們主要關(guān)注2個(gè)點(diǎn):
@Target({ElementType.METHOD})
表明當(dāng)前的注解只能應(yīng)用在方法上面。fallbackMethod
來保證容錯(cuò)。這個(gè)方法有一個(gè)缺陷,就是必須和執(zhí)行方法在同一個(gè)類文件中,這就會(huì)造成我們的方法在實(shí)現(xiàn)的時(shí)候,顯得特別的冗余和不夠優(yōu)雅。以我們的mscx-ad-search
中的廣告查詢?yōu)槔?/p>
@Service
@Slf4j
public class SearchImpl implements ISearch {
/**
* 查詢廣告容錯(cuò)方法
*
* @param e 第二個(gè)參數(shù)可以不指定,如果需要跟蹤錯(cuò)誤,就指定上
* @return 返回一個(gè)空map 對(duì)象
*/
public SearchResponse fetchAdsFallback(SearchRequest request, Throwable e) {
System.out.println("查詢廣告失敗,進(jìn)入容錯(cuò)降級(jí) : %s" + e.getMessage());
return new SearchResponse().builder().adSlotRelationAds(Collections.emptyMap()).build();
}
@HystrixCommand(fallbackMethod = "fetchAdsFallback")
@Override
public SearchResponse fetchAds(SearchRequest request) {
...
}
}
在我們請(qǐng)求出錯(cuò)的時(shí)候,會(huì)轉(zhuǎn)到我們的fallback方法,這個(gè)實(shí)現(xiàn)是通過在應(yīng)用啟動(dòng)的時(shí)候,我們開始了@EnableCircuitBreaker
注解,這個(gè)注解會(huì)通過AOP攔截所有的HystrixCommand
方法,將HystrixCommand
整合到springboot的容器中,并且將注解標(biāo)注的方法放入hystrix的線程中,一旦失敗,通過反射調(diào)用fallback方法來實(shí)現(xiàn)。
上述代碼我們看了Hystrix實(shí)現(xiàn)熔斷的2種方式,接下來我們來實(shí)現(xiàn)請(qǐng)求監(jiān)控的圖形化界面,創(chuàng)建mscx-ad-dashboard
,Let's code.
依然遵從我們springboot項(xiàng)目的三部曲:
加依賴
org.springframework.cloud
spring-cloud-starter-hystrix
1.2.7.RELEASE
org.springframework.cloud
spring-cloud-starter-hystrix-dashboard
1.2.7.RELEASE
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-actuator
加注解
/**
* AdDashboardApplication for Hystrix Dashboard 啟動(dòng)類
*
* @author Isaac.Zhang | 若初
* @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: "*"`
直接啟動(dòng),可以看到如下頁面:
添加要監(jiān)控的服務(wù)地址: