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配置规则时,调用的方法
- blockHandlerClass:blockHandler单独集中配置的类
- 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 异常比例 异常数
- RT:
- 异常比率
- 异常数
在这里我们只演示下异常比例
这里我们配置含义是:
当一秒内请求数 >= 5,且出现异常的请求 >= 30 %,那么在5s内 发生降级(返回blockHandler),5s后恢复,但是在异常请求达到30%之前,不会触发降级规则,所以如果未配置fallbackHandler,则会出现errorpage(这里就不演示了)
我们快速多次访问 http://localhost:84/fallback/3
快速多次访问 http://localhost:84/fallback/4
因为我们id=4时报的异常我们已经忽略了,所以blockHandler和fallbackHandler 都不会返回
快速多次访问 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的超时时长