服务限流、降级、熔断-SpringCloud
本文所使用的组件:Nacos(服务中心和注册中心)、OpenFeign(服务调用)、Sentinel(限流、降级)、Hystrix(熔断)
项目结构:
-
service-provider
:提供服务的微服务。 -
service-consumer
:消费服务的微服务。
1. 添加依赖
在两个服务的pom.xml
文件中添加Spring Cloud Alibaba、Nacos、Sentinel、Hystrix和OpenFeign的依赖。
<dependencies>
<!-- Spring Cloud Alibaba Nacos Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- Spring Cloud OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2. Docker-compose.yml文件
创建docker-compose.yml
文件,启动Nacos和Sentinel。
version: '3'
services:
nacos-server:
image: nacos/nacos-server:latest
container_name: nacos-server
ports:
- "8848:8848"
environment:
- MODE=standalone
- SPRING_DATASOURCE_PLATFORM=mysql
sentinel-server:
image: apache/incubating-sentinel-dashboard:latest
container_name: sentinel-server
ports:
- "8080:8080"
- "8719:8719"
-
部署在云服务中需要打开8080、8848端口,端口冲突可以更换端口。
3. service-provider(提供服务的微服务)
3.1 启动类
创建启动类并添加nacos注册客户端。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class ServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceProviderApplication.class, args);
}
}
3.2 控制器
创建控制器提供服务。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ServiceController {
@GetMapping("/provider")
public String provider() {
return "Hello from Service Provider";
}
}
4. service-consumer(消费服务的微服务)
4.1 OpenFeign客户端
创建Feign客户端用于调用service-provider
。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "service-provider", fallback = ServiceFallback.class)
public interface ServiceClient {
@GetMapping("/provider")
String provider();
}
@Component
public class ServiceFallback implements ServiceClient {
@Override
public String provider() {
// 服务降级逻辑
return "Fallback response from Service Consumer";
}
}
4.2 控制器
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.RestController;
@RestController
public class ConsumerController {
private final ServiceClient serviceClient;
public ConsumerController(ServiceClient serviceClient) {
this.serviceClient = serviceClient;
}
@GetMapping("/consumer")
@HystrixCommand(commandKey = "consumerCommand", fallbackMethod = "fallback")
@SentinelResource(value = "serviceClientCall", blockHandler = "blockHandler")
public String consumer() {
return serviceClient.provider();
}
public String fallback() {
// 熔断降级逻辑
return "Service is down, hystrix fallback";
}
public String blockHandler(BlockException ex) {
// Sentinel降级逻辑
return "Service is blocked by Sentinel";
}
}
-
@HystrixCommand
注解用于指定熔断器的命令键和降级方法,@SentinelResource
注解用于指定资源名和降级方法。
5. application.yml
在两个服务添加application.yml文件。
spring:
cloud:
nacos:
discovery:
server-addr: nacos-server:8848
config:
server-addr: nacos-server:8848
sentinel:
transport:
dashboard: sentinel-server:8080
datasource:
ds1:
type: file
file:
filePath: /path/to/your/sentinel/rules
hystrix:
command:
default:
execution:
isolation:
strategy: THREAD
thread:
timeoutInMilliseconds: 3000
-
filePath:文件路径
6. 配置规则
在Sentinel Dashboard(http://localhost:8080)中添加限流规则:
资源名:serviceClientCall
限流模式:QPS
阈值:10
总结:上述为一套完整的服务治理流程,对于某些场景下可以使用guava框架去实现单体限流。主要学习思想,本文所使用的组件可替换为其他具有相关功能的组件。
不积跬步,无以至千里 --- xiaokai