快速上手几个SpirngCloud组件(Feign/熔断降级/监控)

SpringCloud

1 Feign组件

1.1 基本使用

  1. 依赖
<!--springcloud整合的openFeign-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 开启Feign
@SpringBootApplication
@EnableEurekaClient
// 下面是关键注解
@EnableFeignClients
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
}
  1. 编写feign接口
@FeignClient(name = "product-service")
public interface ProductFeignClient {

    @GetMapping(value = "/product/{id}")
    Product findById(@PathVariable("id") Long id);
}
  1. 远程调用
Product product = productFeignClient.findById(id);

1.2 Feign配置

feign:
    client:
        config:
            feignName: ##定义FeginClient的名称
                connectTimeout: 5000 # 相当于Request.Options
                readTimeout: 5000 # 相当于Request.Options
                # 配置Feign的日志级别,相当于代码配置方式中的Logger
                loggerLevel: full
                # Feign的错误解码器,相当于代码配置方式中的ErrorDecoder
                errorDecoder: com.example.SimpleErrorDecoder
                # 配置重试,相当于代码配置方式中的Retryer
                retryer: com.example.SimpleRetryer
                # 配置拦截器,相当于代码配置方式中的RequestInterceptor
                requestInterceptors:
                    - com.example.FooRequestInterceptor
                    - com.example.BarRequestInterceptor
                decode404: false
  • feignName:FeginClient的名称
  • connectTimeout : 建立链接的超时时长
  • readTimeout : 读取超时时长
  • loggerLevel: Fegin的日志级别
  • errorDecoder :Feign的错误解码器
  • retryer : 配置重试
  • requestInterceptors : 添加请求拦截器
  • decode404 : 配置熔断不处理404异常

1.3 Feign与Ribbon区别

Ribbon是一个客户端的负载均衡器,Feign是在Ribbon的基础上进行了封装

1.4 日志打印

feign:
 client:
   config:
     service-product:
       loggerLevel: FULL
logging:
 level:
   cn.itcast.order.fegin.ProductFeginClient: debug
image-20220611005635258

2 高并发问题

​ 传统Web服务的线程都是由tomcat统一管理的,这样其实会产生一个巨大的并发故障。

image-20220612170053906

比如这种情况,突然某个接口的访问量占满了线程池,那么这样同时会导致整个服务体系瘫痪,所以我们为此提出了俩种解决方案:

  1. 线程隔离
image-20220612170312216

每个接口独立线程池,即使某个接口遇到了流量洪水,其他接口一样可以正常访问。

  1. 服务限流

当某个服务达到访问阈值后直接进行报错,限流操作可以使用Redis嵌Lua脚本进行实现。

  1. 熔断降级

当下游服务器因为访问压力过大而响应变慢或失败时,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用,这种牺牲局部,保全整体的措施就叫熔断

3 熔断配置

3.1 RestTemplate

  1. 导入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
  1. 激活
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class OrderApplicationRest {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplicationRest.class,args);
    }
}
  1. 配置降级策略
   @GetMapping("/buy/{id}")
   @HystrixCommand(fallbackMethod = "orderFallBack")
   public Product buy(@PathVariable("id") Long id){

       Product product = restTemplate.getForObject("http://product-service/product/1", Product.class);

       return product;
   }


   public Product orderFallBack(Long id){
       System.out.println("id:  "+ id  );
       Product product = new Product();
       product.setProductName("熔断降级触发");
       return product;
   }

上面的配置实现了一个简单的熔断反馈方法处理,这种处理在于可以接受参数进行细节处理,但是Hystrix提供了一个全局的熔断降级方案。

@RestController
@RequestMapping("/order")
@DefaultProperties(defaultFallback = "orderFallBack")
public class OrderController {
    
    private RestTemplate restTemplate;

    @Autowired
    public OrderController(RestTemplate restTemplate){
        this.restTemplate = restTemplate;
    }

    @GetMapping("/buy/{id}")
    @HystrixCommand
    public Product buy(@PathVariable("id") Long id){
        Product product = restTemplate.getForObject("http://product-service/product/1", Product.class);
        return product;
    }
    
    public Product orderFallBack(){
        Product product = new Product();
        product.setProductName("统一熔断降级触发");
        return product;
    }

}
  1. 设置熔断时间阈值
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000 # 设置hystrix的超时时间为5000ms

3.2 Feign

  1. 引入依赖

开个玩笑,不需要,Feign已经继承了Hystrix

  1. 实现方法

这里的实现方法其实就是实现了熔断降级方法

@Component
public class ProductFeignClientFallBack implements ProductFeignClient{
    @Override
    public Product findById(Long id) {
        Product product = new Product();
        product.setProductName("触发熔断措施");
        return product;
    }
}
  1. 配置熔断类
@FeignClient(name = "product-service",fallback = ProductFeignClientFallBack.class)
public interface ProductFeignClient {

    @GetMapping(value = "/product/{id}")
    Product findById(@PathVariable("id") Long id);
}

3.3 监控

3.3.1 dashboard

  1. 引入依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
  1. 暴露端口
management:
  endpoints:
    web:
      exposure:
        include: '*'
  1. 访问Web
http://localhost:9002/actuator/hystrix.stream
image-20220614124644480

监控结果如图:

image-20220614124719437

3.3.2 Turbine

在微服务架构体系中,每个服务都需要配置Hystrix DashBoard监控。如果每次只能查看单个实例的监控数据,就需要不断切换监控地址,这显然很不方便。要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix Turbine。Turbine是一个聚合Hystrix 监控数据的工具,他可以将所有相关微服务的Hystrix 监控数据聚合到一起,方便使用。

建议独立工程

  1. 引入依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
  1. 开启服务
@SpringBootApplication
@EnableHystrix
@EnableHystrixDashboard
public class TurbineServerApplication {

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

  1. 服务配置
server:
  port: 8031

spring:
  application:
    name: turbine-server

eureka:
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka

  instance:
    prefer-ip-address: true

turbine:
  app-config: order-service
  cluster-name-expression: "'default'"
  1. 数据监控

​ 本方法与 3.3.1 操作类似,所以不再赘述

3.4 断路器

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. Closed:关闭状态(断路器关闭),所有请求都正常访问。代理类维护了最近调用失败的次数,如果某次调用失败,则使失败次数加1 如果最近失败次数超过了在给定时间内允许失败的阈值,则代理类切换到断开(Open)状态。此时代理开启了一个超时时钟,当该时钟超过了该时间,则切换到半断开(Half-Open)状态。该超时时间的设定是给了系统一次机会来修正导致调用失败的错误。

  2. Open:打开状态(断路器打开),所有请求都会被降级。Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全关闭。默认失败比例的阈值是50%,请求次数最少不低于20次。

  3. Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放1次请求通过,若这个请求是健康的,则会关闭断路器,否则继续保持打开,再次进行5秒休眠计时。

环境准备:

  1. 在订单系统中加入逻辑:

判断请求的id:

如果id=1 :正常执行(正常调用微服务)

否则 :抛出异常

2.默认Hystrix中有触发断路器状态转换的阈值

触发熔断的最小请求次数:20

触发熔断的最小失败比率:50%

熔断器开启的时长:5s

3.4.1 配置熔断策略

circuitBreaker.requestVolumeThreshold=5 
circuitBreaker.sleepWindowInMilliseconds=10000 
circuitBreaker.errorThresholdPercentage=50

解读:

  • requestVolumeThreshold:触发熔断的最小请求次数,默认20

  • errorThresholdPercentage:触发熔断的失败请求最小占比,默认50%

  • sleepWindowInMilliseconds:熔断多少秒后去尝试请求

3.4.2 隔离策略

​ 微服务使用Hystrix熔断器实现了服务的自动降级,让微服务具备自我保护的能力,提升了系统的稳定性,也较好的解决雪崩效应。其使用方式目前支持两种策略:

**线程池隔离策略:**使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)

**信号量隔离策略:**使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)

image-20220614131323310
  • hystrix.command.default.execution.isolation.strategy : 配置隔离策略
    ExecutionIsolationStrategy.SEMAPHORE 信号量隔离
    ExecutionIsolationStrategy.4.THREAD 线程池隔离
  • hystrix.command.default.execution.isolation.maxConcurrentRequests : 最大信号量上限

4 用Sentinel替换Hystrix

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Cloud Alibaba提供了一个名为Sentinel的熔断降级框架,可以方便地与Spring Cloud集成。下面是使用Spring Cloud Alibaba Sentinel进行熔断降级的步骤: 1. 添加依赖 在`pom.xml`文件中添加以下依赖: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.3.RELEASE</version> </dependency> ``` 2. 配置Sentinel 在`application.yml`文件中添加以下配置: ```yaml spring: cloud: sentinel: transport: dashboard: localhost:8080 #Sentinel Dashboard地址 port: 8719 #Sentinel客户端监听端口号 ## 开启Sentinel熔断降级 feign: sentinel: enabled: true ``` 3. 配置熔断降级规则 在`resources`目录下创建一个名为`META-INF`的文件夹,然后在该文件夹下创建一个名为`flowrule`的文件,文件名可以自己定义。在该文件中添加以下内容,这里以配置一个`Hello World`的熔断降级规则为例: ```json [ { "resource": "hello", //资源名称,可以是方法名或URL "count": 5, //阈值 "grade": 0, //熔断策略,0表示平均响应时间,1表示异常比率 "timeWindow": 5, //时间窗口,单位是秒 "minRequestAmount": 5, //最小请求数量 "slowRatioThreshold": 0 //慢调用比例阈值 } ] ``` 4. 使用@SentinelResource注解 在需要进行熔断降级的方法上添加`@SentinelResource`注解,并指定资源名称,例如: ```java @SentinelResource(value = "hello", fallback = "fallback") public String hello() { return "Hello World"; } public String fallback() { return "fallback"; } ``` 其中`fallback`方法为熔断降级时的备选方法。 5. 启动Sentinel Dashboard 在命令行中输入以下命令启动Sentinel Dashboard: ```bash java -jar sentinel-dashboard-1.8.2.jar ``` 访问`http://localhost:8080`即可进入Sentinel Dashboard。 6. 启动应用程序 启动应用程序后,可以在Sentinel Dashboard中看到应用程序的熔断降级情况。当资源的请求次数超过阈值时,Sentinel将自动触发熔断降级策略,调用`fallback`方法,返回备选结果。 以上就是使用Spring Cloud Alibaba Sentinel进行熔断降级的步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沈自在-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值