Hystix

当某个服务阻塞时,大量客户线程就会消耗完Tomcat的链接,从而其他服务也不可使用。这个现象就是服务雪崩。解决方案有两种:服务降级和服务熔断。

服务降级是消费者端进行的,服务熔断的服务生产者进行的。

服务降级

服务降级,就是服务超时后立刻返回给客户一个失败的信息,不让它在占用Tomcat的链接。

1、导入jar

   <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

2、yml

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000  
#配置服务降级的时长,不配置也可以,默认是1s,这里配置成了3s,这是全局的配置

3、ConsumerController

@RestController
@RequestMapping("consumer")
@DefaultProperties(defaultFallback = "defaultFallback") //默认的返回降级的方法
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("{id}")
    //@HystrixCommand(fallbackMethod = "queryByIdFallback")//可以独立配置降级方法
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000")//独立配置降级时间
    })
    public String queryById(@PathVariable("id") Long id) {
        String url="http://user-service/user/"+id;//ip+端口 用服务id代替了,默认是轮询
        String user = restTemplate.getForObject(url, String.class);
        return  user;
    }

    public String queryByIdFallback(Long id){
        return "服务太拥挤了";
    }
    public String defaultFallback(){
        return "默认服务太拥挤了";
    }

服务熔断

默认情况下,20次服务请求,50%的失败率就会触发服务熔断。此时熔断器就会打开,打开后5s后会进入半开状态,会允许少量的请求通过,测试服务是否可用,可用熔断器就会变为关闭状态,否则继续等5s继续测试。

这个很难演示出来,所以用id模拟这个熔断。

@RestController
@RequestMapping("consumer")
@DefaultProperties(defaultFallback = "defaultFallback")
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("{id}")
    //@HystrixCommand(fallbackMethod = "queryByIdFallback")
    @HystrixCommand(commandProperties = {
            //请求次数不小于10次
            @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"),
//10s进入半开状态

@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"),
//60%的错误熔断熔断器
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="60")
    })
    public String queryById(@PathVariable("id") Long id) {
        //抛出异常表明服务失败
        if(id%2==0){
            throw new RuntimeException("异常");
        }
        String url="http://user-service/user/"+id;//ip+端口 用服务id代替了,默认是轮询
        String user = restTemplate.getForObject(url, String.class);
        return  user;
    }

    public String queryByIdFallback(Long id){
        return "服务太拥挤了";
    }
    public String defaultFallback(){
        return "默认服务太拥挤了";
    }
}

开发状态下,这些参数不用调,这里为了演示效果。

连续点击id为16的链接

快速点击id为17的链接

过几秒后再次点击id为17的链接

 它就又变好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值