您的位置:首页 > Web前端

Sentinel 服务熔断降级 及 整合openfeign

2020-08-18 14:29 148 查看

1.启动sentinel dashboard 及nacos

在这里sentinel 我使用的是 1.7.0的windows版本

在文件目录下 启动cmd 输入命令

java -jar sentinel-dashboard-1.7.0.jar

访问 http://localhost:8080 登录即可(默认账户密码都是

sentinel

启动nacos ,我使用的是1.1.4 的windos版本 运行bin目录下的

startup.cmd

访问 http://localhost:8848/nacos/ 登录即可(默认账户密码都是

nacos

2.熔断降级

要使用熔断降级,必须先了解

@SentinelResource
注解

2.1 @SentinelResource

该注解通常用在服务熔断降级的业务方法上(为了方便代码演示,我写在了接口上)

参数:

  • value:自定义资源名
  • blockHandler:请求触发sentinel配置规则时,调用的方法
  • blockHandlerClassblockHandler单独集中配置的类
  • fallbackHandler:java代码发生运行时异常时,调用的方法
  • fallbackHandlerClass:将fallbackHandler:单独集中配置的类
  • exceptionsToIgnore: 忽略的异常类型(出现了该异常不会调用fallbackHandler以及blockHandler)

2.2创建订单微服务84

pom

在这里

springcloud-alibaba
使用的是
2.1.0.RELEASE
版本,
spring-boot
使用的是
2.2.2.RELEASE
版本

<dependencies>
<!--SpringCloud openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

yml

server:
port: 84

spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
sentinel:
transport:
#配置Sentinel dashboard地址
dashboard: localhost:8080
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
port: 8719

# 激活Sentinel对Feign的支持
feign:
sentinel:
enabled: true

主启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
* @author Xkuna
* @date 2020/8/17 20:29.
*/
@SpringBootApplication
@EnableDiscoveryClient //nacos
@EnableFeignClients  //feign
public class OrderNacosMain84 {
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain84.class, args) ;
}
}

创建controller

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
* @author Xkuna
* @date 2020/8/17 20:32.
*/
@RestController
public class OrderController {
@GetMapping("/fallback/{id}")
@SentinelResource(value = "fallback", blockHandler = "blockHandler1",fallback = "fallbackHandler",
exceptionsToIgnore = IllegalArgumentException.class
)
public String fallback(@PathVariable("id") Long id){
if(id == 4){
throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
}else if(id > 4){
throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
}else{
return "ok-------id: " + id ;
}
}
public String blockHandler1(@PathVariable("id") Long id, BlockException blockException){
return "---blockHandler" ;
}

public String fallbackHandler(@PathVariable Long id){
return "----fallbackHandler" ;
}
}

解释下上面配置的接口:

​ 接口传入一个Lone类型的id,id < 4,正常访问,id =4 会报

IllegalArgumentException
,但是
exceptionsToIgnore
配置了这个异常,所以我们传入id =4 时,那么会直接出现 errorPage而不会调用fallbackhandler, 如果id > 4,会调用 fallbackHandler

启动 订单服务84,进行测试:

​ 访问 http://localhost:84/fallback/3

访问 http://localhost:84/fallback/4

访问 http://localhost:84/fallback/5

以上是我们还没有配置降级规则,接下来我们在sentinel控制台配置 降级规则(如果不显示服务,先多次访问下 http://localhost:84/fallback/3)

降级规则: RT 异常比例 异常数

  1. RT

  1. 异常比率

  1. 异常数

在这里我们只演示下异常比例

这里我们配置含义是:

​ 当一秒内请求数 >= 5,且出现异常的请求 >= 30 %,那么在5s内 发生降级(返回blockHandler),5s后恢复,但是在异常请求达到30%之前,不会触发降级规则,所以如果未配置fallbackHandler,则会出现errorpage(这里就不演示了)

我们快速多次访问 http://localhost:84/fallback/3

快速多次访问 http://localhost:84/fallback/4

因为我们id=4时报的异常我们已经忽略了,所以blockHandlerfallbackHandler 都不会返回

快速多次访问 http://localhost:84/fallback/5

会发现前几次返回的是 fallbackHandler 然后慢慢的变为blockHandler 大约5

s后再次变为 fallbackHandler ,这就证明了我们上面的结论

3.Sentinel整合OpenFeign

在这里我们创建两个支付微服务,订单服务通过OpenFeign调用订单微服务 并且实现负载均衡(在这里就不写支付微服的sentinel熔断降级了)

3.1 创建支付微服务 9003

pom

<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

yml

server:
port: 9003

spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址

management:
endpoints:
web:
exposure:
include: '*'

主启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
* @author Xkuna
* @date 2020/8/17 20:59.
*/
@SpringBootApplication
@EnableDiscoveryClient //nacos
public class PaymentMain9003 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9003.class, args) ;
}
}

创建controller

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @author Xkuna
* @date 2020/8/17 21:01.
*/
@RestController
public class PaymentController {
@Value("${server.port}")
private String port ;

@GetMapping("/port")
public String getPort(){
return port ;
}
}

3.2 创建支付微服务 9004

copy 支付微服务9003 修改端口为9004 即可

3.3修改订单微服务

创建 openfeign调用接口以及fallback实现类

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

/**
* @author Xkuna
* @date 2020/8/17 21:09.
*/
@Service
@FeignClient(value = "nacos-payment-provider", fallback = PaymentServiceImpl.class)
public interface PaymentService {
@GetMapping("/port")
public String getPort() ;
}
import org.springframework.stereotype.Component;

/**
* @author Xkuna
* @date 2020/8/17 21:10.
*/
@Component //注意注入ioc容器
public class PaymentServiceImpl implements PaymentService{
@Override
public String getPort() {
return "支付服务 fallback";
}
}

修改controller(在下面添加了一个接口和fallbackHandler blockHandler

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import top.xkuna.springboot.service.PaymentService;

import javax.annotation.Resource;

/**
* @author Xkuna
* @date 2020/8/17 20:32.
*/
@RestController
public class OrderController {
@GetMapping("/fallback/{id}")
@SentinelResource(value = "fallback", blockHandler = "blockHandler1",fallback = "fallbackHandler",
exceptionsToIgnore = IllegalArgumentException.class
)
public String fallback(@PathVariable("id") Long id){
if(id == 4){
throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
}else if(id > 4){
throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
}else{
return "ok-------id: " + id ;
}
}
public String blockHandler1(@PathVariable("id") Long id, BlockException blockException){
return "---blockHandler" ;
}

public String fallbackHandler(@PathVariable Long id){
return "----fallbackHandler" ;
}

//---openfeign

@Resource
private PaymentService paymentService ;

@GetMapping("/getPaymentPort")
@SentinelResource(value = "getPaymentPort", blockHandler = "blockHandler2",fallback = "fallbackHandle2")
public String getPaymentPort(){
return paymentService.getPort() ;
}

public String blockHandler2(BlockException blockException){
return "调用payment---blockHandler" ;
}

public String fallbackHandler2(){
return "调用payment----fallbackHandler" ;
}

}

注意在yml中开启feign支持sentinel的熔断降级(上面在搭建的时候已经配置了)

此时启动 支付微服务9003 9004

3.4测试

访问 http://localhost:84/getPaymentPort

多刷新几次发现,实现了负载均衡

那么此时我们停掉 9004

多次访问 http://localhost:84/getPaymentPort

发现都是 9003,访问正常

我们再停掉 9003(此时支付微服务全部下线)

说明我们配置openfeign接口的实现类成功 😄

4.修改openfeign调用时限

​ 使用过openfeign的小伙伴都知道在用它调用其他微服务的时候,默认的超时时长是 1s;如何修改这个时长呢?

​ 在hystrix与openfeign整合的时候,需要调用端要开启feign对hystrix的支持,设置调用端hystrix的超时时长,还要设置ribbon的超时时长。

​ 在sentinel中,调用者要修改openfeign的默认超时时长,需要两点

  • 开启feign对sentinel的支持
  • 设置ribbon的超时时长

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: