(一)springcloud服务熔断降级解决方案之Hystrix

作者: 我犟不过你 | 来源:发表于2021-07-08 15:26 被阅读0次

    目前主流的服务熔断降级方案,主要有两种: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

    hystrix-dashboard

    下面是我的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的安装及使用过程。

    相关文章

      网友评论

        本文标题:(一)springcloud服务熔断降级解决方案之Hystrix

        本文链接:https://www.haomeiwen.com/subject/qjizultx.html