Spring Cloud 之服务熔断问题 (四)

九、 服务熔断

1.服务熔断的相关概念

对于服务熔断来说,我们需要知道以下几个知识点:

  • 服务的扇出

服务非常的多,服务之间的调用像扇子一样打出来

  • 服务的雪崩

当服务D挂了后,服务B也一样会挂,服务A必然会A,此时访问服务A都是不成功的,导致Tomcat线程池的线程消耗殆尽,没有多余的线程访问其他服务,比如服务M,造成服务雪崩

  • 服务的熔断

在服务B调用服务D时,在服务B上设置断路器,当服务D挂了,有线程需要访问服务D时断路器开始工作,这样就可以避免服务雪崩,这就叫服务熔断。

  • 服务的降级

什么是服务降级?

比如电商大促,会迎来流量洪峰,为了应对流量洪峰,服务器不会被洪峰打垮,所以要保留(保护、保障)核心服务可用。比如登陆、交易、物流这样的核心服务是可用的,但注册、退货、评价等非核心服务暂时不可用,这就是把注册、退货、评价等这些服务降级了。

2.在Ribbon中实现Hystrix熔断器

1)引入依赖

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

2)在启动类上开启Hyxtrix注解

@EnableDiscoveryClient
@SpringBootApplication
@EnableHystrix
public class MyProductServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyProductServiceApplication.class, args);
    }

}

3)对需要进行熔断方法上设置熔断器,指明错误回调方法

@Override
    @HystrixCommand(fallbackMethod = "hiError")
    public String addUser(User user) {
        ResponseEntity<String> entity = restTemplate.postForEntity("http://user-service/addUser", user, String.class);
        return entity.getBody();
    }

    public String hiError(User user){
        return "当前你的网络出现了问题,请联系当地电信运营商";
    }

3.在Feign中实现Hystrix熔断器

feign默认集成了Hystrix,需要手动打开

1)在配置文件中添加如下配置:

feign:
  hystrix:
    enabled: true

注意:如果feign配置了拦截器,那么需要增加hystrix的配置:

#如果设置了拦截器,那么对hystrix线程的隔离级别做这个配置 To set thread isolation to SEMAPHORE
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: SEMAPHORE

2) 编写fallback实现类 实现Feign的接口层

重写接口中的方法,这些方法就是错误回调方法,当发生熔断,对应的方法会被调用

package com.qf.my.product.feign.service.api.fallback;

import com.qf.common.entity.User;
import com.qf.my.product.feign.service.api.ProductFeignAPI;
import org.springframework.stereotype.Component;

@Component
public class ProductFeignFallback implements ProductFeignAPI {
    @Override
    public String userShow() {
        return "当前网络有问题,请检查你的网络";
    }

    @Override
    public String addUser(User user) {
        return "当前网络有问题,请检查你的网络";
    }

    @Override
    public User getUserByMap(Long id, String name) {
        return null;
    }

    @Override
    public String addUserWithHeader(User user) {
        return "当前网络有问题,请检查你的网络";
    }
}

3)在Feign接口中配置该错误回调类

fallback = ProductFeignFallback.class

package com.qf.my.product.feign.service.api;

import com.qf.common.entity.User;
import com.qf.my.product.feign.service.api.fallback.ProductFeignFallback;
import com.qf.my.product.feign.service.interceptor.FeignInterceptor;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;

@FeignClient(value="USER-SERVICE",configuration = FeignInterceptor.class,fallback = ProductFeignFallback.class)
public interface ProductFeignAPI {


    @RequestMapping("/user/show")
    public String userShow();

    @PostMapping("/addUser")
    public String addUser(@RequestBody User user);

    @GetMapping("/getUserByMap")
    public User getUserByMap(@RequestParam(name = "id") Long id,@RequestParam(name = "name") String name);

    @PostMapping("/addUserWithHeader")
    public String addUserWithHeader(@RequestBody User user);


}

4.熔断器打开的条件

  • 服务宕机

服务提供者挂了,不在线。

  • 服务抛异常

当下游服务抛出了异常,上游熔断被触发

  • 服务超时

超出了默认的1s的时间。

配置:

#如果设置了拦截器,那么对hystrix线程的隔离级别做这个配置 To set thread isolation to SEMAPHORE
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: SEMAPHORE
          thread:
            timeoutInMilliseconds: 10000
  # 配置熔断器仪表盘
  dashboard:
    proxy-stream-allow-list: "localhost"
#feign配置hyxstrix超时时间,需要加上ribbon的超时时间配置
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 10000

5.熔断器的半开状态

熔断器被触发,即使下游服务恢复,但下游服务被熔断器降级了,也就是说默认5秒内该服务不能正常访问。熔断器的半开状态:五秒后熔断器会放行一个请求到下游,如果正常则熔断器回到关闭状态,如果不正常,则熔断器继续保持打开状态。

posted @ 2021-07-21 22:03  牛奶配苦瓜  阅读(377)  评论(0编辑  收藏  举报