Hystrix解决雪崩问题-1.线程隔离

线程隔离示意图:在这里插入图片描述
解读:
Hystrix为每个依赖服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,默认不采用排队,加速失败判定时间。在这里插入图片描述
快速入门:
(都是在consumer-demo改)
都是基于上一篇博客的代码:https://blog.csdn.net/GLOAL_COOK/article/details/114272205

1)引入依赖
在 consumer-demo 消费端系统的pom.xml文件添加如下依赖:
(版本不对应可能爆错,我的springboot是2.4.3没错)

<!--Hystrix线程隔离-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>

2)开启熔断
在启动类 ConsumerApplication 上添加注解:@EnableHystrix在这里插入图片描述

3)编写降级逻辑
当目标服务的调用出现故障,我们希望快速失败,给用户一个友好提示。因此需要提前编写好失败时的降级处理逻辑,要使用HystrixCommand来完成。改造 consumer-demo\src\main\java\com\itheima\consumer\controller\ConsumerController.java 处理器
类,如下:

package com.itheima.consumer.controller;

import com.itheima.consumer.pojo.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @author QLBF
 * @version 1.0
 * @date 2021/3/1 23:12
 */
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("{id}")
    //这是指定下面那个降级方法
    @HystrixCommand(fallbackMethod ="queryByIdFallback")
    public User queryById(@PathVariable Long id){
        /*
        //String url="http://localhost:9091/user/"+id;
        //获取eureka中注册的user-service实例列表,这里写的user-service要和user-service工程里面application.yml定义的应用名一致
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("user-service");
        ServiceInstance serviceInstance = serviceInstances.get(0);//获取服务列表的第一个(0是第一个,一般一个服务一个)的意思,得根据你服务列表有多少
        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/user/" + id;
        */
        //负载均衡Ribbon的url方式,简单很多:
        String url="http://user-service/user/"+id;
        return restTemplate.getForObject(url,User.class);
    }


    /*降级方法
    和需要收到保护的方法的返回值一致
    方法参数一致*/
    public User queryByIdFallback(Long id){
        User user=new User();
        user.setUserName("触发降级方法了");
        return user;
    }
}

原本:
在这里插入图片描述要注意;因为熔断的降级逻辑方法必须跟正常逻辑方法保证:相同的参数列表和返回值声明。
测试:
当 user-service 正常提供服务时,访问与以前一致如上图。但是当将 user-service 停机时,会发现页面返回了降级处理信息:
在这里插入图片描述
4)默认的Fallback(还是用第三点好,在方法上加好)
刚才把fallback写在了某个业务方法上,如果这样的方法很多,那岂不是要写很多。所以可以把Fallback配置加在类上,实现默认fallback;再次改造 consumer-demo\src\main\java\com\itheima\consumer\controlle\ConsumerController.java:

package com.itheima.consumer.controller;

import com.itheima.consumer.pojo.User;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @author QLBF
 * @version 1.0
 * @date 2021/3/1 23:12
 */
@RestController
//2.统一的降低方法
@DefaultProperties(defaultFallback = "defaultFallback")
@RequestMapping("/consumer")
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("{id}")
    //1.在方法上的降低方法,这是指定下面那个降级方法
    //@HystrixCommand(fallbackMethod ="queryByIdFallback")
    @HystrixCommand  //就算是统一的方法也得加上
    public User queryById(@PathVariable Long id){
        /*
        //String url="http://localhost:9091/user/"+id;
        //获取eureka中注册的user-service实例列表,这里写的user-service要和user-service工程里面application.yml定义的应用名一致
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("user-service");
        ServiceInstance serviceInstance = serviceInstances.get(0);//获取服务列表的第一个(0是第一个,一般一个服务一个)的意思,得根据你服务列表有多少
        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/user/" + id;
        */
        //负载均衡Ribbon的url方式,简单很多:
        String url="http://user-service/user/"+id;
        return restTemplate.getForObject(url,User.class);
    }


    /*降级方法
    和需要收到保护的方法的返回值一致
    方法参数一致*/
    public User queryByIdFallback(Long id){
        User user=new User();
        user.setUserName("触发降级方法了");
        return user;
    }

    /*
    统一的降级方法
    和需要上面所以的方法的返回值一致
    方法参数要为空*/
    public User defaultFallback(){
        User user=new User();
        user.setUserName("触发统一的降级方法了");
        return user;
    }
}

```![在这里插入图片描述](https://img-blog.csdnimg.cn/20210303113536263.png)
再停掉user-service:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210303113521765.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0dMT0FMX0NPT0s=,size_16,color_FFFFFF,t_70)

测试成功!![在这里插入图片描述](https://img-blog.csdnimg.cn/20210303113624402.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0dMT0FMX0NPT0s=,size_16,color_FFFFFF,t_70)
就不演示了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值