(一)springcloud服務熔斷降級解決方案之Hystrix 一、Hystrix

目前主流的服務熔斷降級方案,主要有兩種: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的安裝及使用過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章