目前主流的服務熔斷降級方案,主要有兩種:springcloud的Hystrix和Alibaba的Sentinel,目前不論是從整體熱度及使用體驗、功能額豐富而言,Sentinel都具有絕對的優勢。
爲什麼需要服務的熔斷呢?當前的微服務架構,擁有多個服務,相互間的調用複雜,當有一臺服務出現問題,導致服務無法調用,此時流量上來後,會造成整個系統的流量堆積,最終造成整個系統的不可用。所用服務的熔斷是很重要的,可以維護系統的問題及可用性。
熔斷主要注意兩點:啓動熔斷和恢復熔斷。
什麼是服務降級呢?當系統在某個時間段迎來了流量洪峯,整個系統的壓力倍增,此時爲了保證核心業務的運行,可以對某些無關緊要的服務和頁面進行流量限制或者停止訪問,從而釋放服務器的整體壓力。
下面我們分別演示如何進行服務的熔斷和降級。
一、Hystrix
引入依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
加入開啓熔斷器的註解@EnableCircuitBreaker,我此處演示項目使用gateway演示:
/**
* 啓動類
*
* @author weirx
*/
@EnableCircuitBreaker
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}, scanBasePackages = {"com.cloud.bssp.gateway"})
@EnableFeignClients(basePackages = {"com.cloud.bssp.gateway.feign"})
public class BsspGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(BsspGatewayApplication.class, args);
}
}
默認情況下FeignClient中默認情況下是禁用Hystrix的,所以如果需要在微服務中啓用Hystrix的熔斷功能,則需要通過配置手動開啓Hystrix功能:
#開啓hystrix
feign:
hystrix:
enabled: true
提供一個用戶服務的feignClient,重點是屬性fallbackFactory,後面配置當前feignClient的實現類。
@FeignClient(name = "bssp-user-service", path = "/user",fallbackFactory = UserClientImpl.class)
public interface UserClient {
@PostMapping("/login")
R login(@RequestBody UserDTO userDTO);
}
UserClientImpl代碼如,注意增加@Component註解,否則可能會報找不到服務的錯誤:
/**
* @author weirx
* @date 2021/07/08 11:10
**/
@Slf4j
@Component
public class UserClientImpl implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable throwable) {
return new UserClient() {
@Override
public R login(UserDTO userDTO) {
log.info("調用用戶服務失敗,對用戶服務降級處理。");
return R.failed("調用用戶服務失敗,對用戶服務降級處理");
}
};
}
}
模擬user服務宕機情況下,訪問登錄接口,之所以用登錄接口是圖方便。將user服務關閉,或者在註冊中心下線處理。查看結果:
Histrix提供了面板共我們直觀的查看:HystrixDashboard,引入依賴,需要注意的是,儘量不要在springcloudGateway中添加dashboard,因爲其依賴含有web組件,會和gateway衝突,所以下面的演示我換一個服務,這是自己踩得一個坑:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
啓動類增加註解@EnableHystrixDashboard
/**
* @author weirx
* @description: 數據服務啓動類
* <p>
* 註解@ServletComponentScan: 使Servlet,filter,listener 可以通過 @WebServlet,@WebFilter,@WebListener
* 等註解直接註冊,無需其他代碼
* @date 2020/6/17
*/
@EnableHystrixDashboard
@EnableCircuitBreaker
@SpringBootApplication
@ServletComponentScan
@EnableFeignClients
public class BsspAdminServiceApplication {
public static void main(String[] args) {
SpringApplication.run(BsspAdminServiceApplication.class, args);
}
}
訪問http://localhost:8080/hystrix
下面是我的client和fallback實現:
/**
* Description: 用戶表
* Create Date: 2021-03-17T13:53:59.025
* Modified By:<br>
* Modified Date:<br>
* Why & What is modified:<br>
*
* @author weirx
* @version 1.0
*/
@FeignClient(name = "bssp-user-service", path = "/user", fallbackFactory = UserClientImpl.class)
public interface UserClient {
/**
* 分頁列表
*
* @param params
* @return
*/
@PostMapping("/pageList")
R pageList(@RequestBody Map<String, Object> params);
/**
* list列表
*
* @param userDTO
* @return
*/
@PostMapping("/list")
R list(@RequestBody UserDTO userDTO);
/**
* 根據主鍵查詢
*
* @param id
* @return
*/
@GetMapping("/info/getById")
R info(@RequestParam("id") Long id);
/**
* 新增
*
* @param userDTO
* @return
*/
@PostMapping("/save")
R save(@RequestBody UserDTO userDTO);
/**
* 更新
*
* @param userDTO
* @return
*/
@PostMapping("/update")
R update(@RequestBody UserDTO userDTO);
}
import java.util.Map;
/**
* @author weirx
* @date 2021/07/08 14:38
**/
@Component
public class UserClientImpl implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable throwable) {
return new UserClient() {
@Override
public R pageList(Map<String, Object> params) {
return R.failed("調用用戶服務失敗,服務已被降級處理");
}
@Override
public R list(UserDTO userDTO) {
return R.failed("調用用戶服務失敗,服務已被降級處理");
}
@Override
public R info(Long id) {
return R.failed("調用用戶服務失敗,服務已被降級處理");
}
@Override
public R save(UserDTO userDTO) {
return R.failed("調用用戶服務失敗,服務已被降級處理");
}
@Override
public R update(UserDTO userDTO) {
return R.failed("調用用戶服務失敗,服務已被降級處理");
}
};
}
}
測試controller:
@Api(tags = "測試Hystrix")
@RestController
@RequestMapping("/test")
public class TestController {
/**
* SysMenuService
*/
@Autowired
private UserClient userClient;
/**
* list列表
* @return
*/
@GetMapping("/list")
public R list() {
return userClient.list(new UserDTO());
}
}
顏色說明:
現在通過dashboard監控服務,當用戶服務正常啓動是,我們多次訪問端口看結果:
當我們將服務關閉後訪問看結果:
下一章節演示alibaba sentinel的安裝及使用過程。