之前在springcloud项目整合过了dubbo,现在需要加上sentinel实现熔断降级功能,dubbo本身提供降级功能,但是不完善,没有熔断功能,因此,引入sentinel来实现熔断降级
在网上搜了很多关于dubbo+sentinel熔断降级的资料,基本没搜到关于全局fallback如何配置的方法,因此编写这篇文章作为分享
感兴趣的话,可以下载demo,https://download.csdn.net/download/weixin_45973130/84219325
这篇文章需要读者对sentinel熔断功能了解、了解使用nacos、了解使用sentinel-dashboard使用和配置规则、了解配置dubbo,在这里就不详细介绍了
dubbo版本2.7.8
sentinel版本1.8.0
springcloud版本
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<file.encoding>UTF-8</file.encoding>
<spring-cloud.version>Hoxton.SR4</spring-cloud.version>
<spring-boot.version>2.2.10.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version>
<gson.version>2.6</gson.version>
</properties>
<!-- spring-cloud所有项目依赖包 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
</dependency>
sentinel-apache-dubbo-adapter依赖不引入也没问题,因为spring-cloud-starter-alibaba-sentinel包会引入这个依赖的
server.port=8701
spring.application.name=nacos-server
spring.cloud.nacos.discovery.server-addr=192.168.88.9:8848
spring.cloud.nacos.discovery.namespace=dev
spring.cloud.nacos.config.server-addr=192.168.88.9:8848
spring.cloud.nacos.config.namespace=dev
spring.cloud.nacos.config.extension-configs[0].data-id=${spring.application.name}
spring.cloud.nacos.config.extension-configs[0].group=springclouddemo
spring.cloud.nacos.config.extension-configs[0].refresh=true
spring.cloud.nacos.config.group=${spring.application.name}
# dubbo配置
dubbo.scan.base-packages=com.tp.service
main.allow-bean-definition-overriding=true
dubbo.cloud.subscribed-services=nacos-server
dubbo.protocols.dubbo.name=rmi
dubbo.protocols.dubbo.port=-1
dubbo.registry.address=spring-cloud://192.168.88.9:8848
dubbo.provider.cluster=failfast
dubbo.provider.retries=0
dubbo.provider.timeout=600000
dubbo.provider.token=false
dubbo.provider.dynamic=true
dubbo.provider.delay=-1
dubbo.provider.version=1.0.0
dubbo.provider.filter=dubboProviderFilter
dubbo.consumer.check=true
dubbo.consumer.validation=true
dubbo.consumer.version=1.0.0
dubbo.consumer.filter=dubboConsumerFilter
# sentinel配置
spring.cloud.sentinel.transport.port=8719
spring.cloud.sentinel.transport.dashboard=192.168.88.53:8080
到这里我们的配置已经好了,我们的项目可以启动测试了
以上配置好之后,项目就可以正常运行,当我们在sentinel-dashboard配置熔断规则也可以正常使用,但是熔断后会抛出异常,这个的话,就需要配置全局的fallback了。fallback定义是修改DubboAdapterGlobalConfig(来源于sentinel-apache-dubbo-adapter)中的ConsumerFallback变量。
我们在springcloud项目启动后,再配置fallback代码如下:
@SpringBootApplication
@EnableDiscoveryClient
@Slf4j
public class NacosServerApplication {
public static void main(String[] args) {
SpringApplication.run(NacosServerApplication.class, args);
DubboAdapterGlobalConfig.setConsumerFallback(new DubboFallback() {
@Override
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException e) {
log.error("降级了,参数:{}, 服务名:{}, 方法:{}", invocation.getArguments(), invocation.getServiceName(), invocation.getMethodName());
Object obj = null;
return AsyncRpcResult.newDefaultAsyncResult(obj, invocation);
}
});
}
}
由于我们一般使用dubbo调接口的话就是直接传输对象,不会像http那样定义一个result封装结果的类,因此,我们在这里的话,就全局定义熔断降级后接口均返回null,如代码上定义的Object obj = null
编写HelloCotroller,接收测试请求
@RestController
@RequestMapping("/hello")
public class HelloController {
@DubboReference()
private HelloService helloService;
@RequestMapping("/getword")
public Hello getword(){
Hello hello = new Hello();
hello.setHello("Hi");
hello.setSay("say");
return helloService.getword(hello);
}
}
编写Hello实体
@Slf4j
@Data
public class Hello {
private String hello;
private String say;
}
编写HelloSerice接口
public interface HelloService {
Hello getword(Hello hello);
}
编写HelloSericeImpl实现类
@DubboService
public class HelloServiceImpl implements HelloService {
@Override
public Hello getword(Hello hello) {
try {
Thread.sleep(200);
}catch (Exception e){
e.printStackTrace();
}
return hello;
}
}
启动服务,疯狂调用接口http://localhost:8701/hello/getword,接口返回:
在sentinel-dashboard配置降级规则如下:
疯狂点击,我们来看看日志,以上日志是我们配置的全局fallback方法中的内容一样,证明全局降级生效了
看看sentinel-dashboard,如下图:
之前使用openfeign构建过一套基于springcloudalibaba的微服务架构项目,虽然说已经够用了,但是还是想使用dubbo来代替openfeign来构建一套微服务,据说dubbo会比openfeign效率高点,请各位看官多多指点。