这一篇我们主要来介绍下Spring-cloud与Sentinel的整合使用,主要是对feign、gateway的控制。feign我们知道其是用来调用另一个微服务的。
一、feign调用demo介绍
1、属性配置&引用依赖
这是我们的项目,我们现在模拟的是spring-cloud-consumer
调用spring-cloud-producer
:
我们整合sentinel
,需要在consumer
项目中添加依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
同时在配置文件添加sentinel
控制台的地址以及开始feign
与sentinel
的整合控制:
spring:
application:
name: spring-cloud-consumer
cloud:
sentinel:
transport:
dashboard: localhost:9000
feign:
sentinel:
enabled: true
2、FeignServiceClient
然后关于FeignServiceClient
@FeignClient(value = "spring-cloud-producer",fallback = SentinelBackService.class)
public interface FeignServiceClient {
@RequestMapping(value = "producer/simple",method = RequestMethod.GET)
String producerSimpleMethod();
}
这里与hystrix
的降级控制是类似的,都有一个回调来返回限制后的信息返回。这里我们配置的就是去请求spring-cloud-producer
的producer/simple
-api接口。
3、SentinelBackService
@Component
public class SentinelBackService implements FeignServiceClient {
@Override
public String producerSimpleMethod() {
return "Error SentinelBackService !!!";
}
}
这个就是限制生效后的返回信息。
4、ConsumerController
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private FeignServiceClient feignServiceClient;
@RequestMapping(value = "simple",method = RequestMethod.GET)
public String consumerSimple(){
System.out.println("--------ConsumerController--------");
return feignServiceClient.producerSimpleMethod();
}
}
我我们将eureka
、producer
、consumer
这3个服务都启动。然后去访问ConsumerController
的API。
5、feign调用限制
1、限流
我们可以看到资源的key
生成的方式变了:其是请求方式:协议:服务名称/请求路径
组成了。
我们添加控制就能看到对应的控制了。
这里我们同样可以添加熔断降级
的限制。
2、熔断降级
要测试熔断降级我们改下producer
的逻辑,我们抛出异常,让feign
不能调用成功。
@RestController
@RequestMapping("producer")
public class ProducerController {
private int index=0;
@RequestMapping(value = "simple",method = RequestMethod.GET)
public String simpleMethod(){
if (index++%2 == 0){
throw new NullPointerException();
}
return "Hello Producer Simple";
}
}
然后我们添加降级规则
:
然后我们可以看到其的调用控制生效了(已经将原来的限流规则
删除了),在3S
(界面应该由于统计间隔的问题,只要2s
体现)没有通过请求。
二、gateway网关流控demo
下面我们来看下sentinel
与gateway
的整合使用
首先我们来看下基础使用,整个项目我们有介绍,目前是spring-cloud-consumer
调用spring-cloud-producer
。
1、项目介绍
1)、spring-cloud-consumer
我们来看下consumer
项目的controller
整个我们前面上面有讲过了,然后我们来看下zuul项目。
2)、spring-cloud-producer
3)、spring-cloud-gateway
我们引入sentinel
对于gateway
的adapter
相关的依赖,注意这里的版本号要与你本身引入的cloud
的依赖相关联。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.7.2</version>
</dependency>
server:
port: 9100
spring:
application:
name: spring-cloud-gateway
cloud:
gateway:
routes:
- id: sentinel-gateway-consumer
uri: lb://spring-cloud-consumer
predicates:
- Path=/consumer/**
- id: sentinel-gateway-producer
uri: lb://spring-cloud-producer
predicates:
- Path=/producer/**
sentinel:
transport:
dashboard: localhost:9000
port: 9000
可以看到我们目前是有写了两个路由,一个是producer-server
,例如我们能通过http://localhost:9100/producer/simple
就直接路由到了spring-cloud-producer
服务了:
同时我们也可以通过gateway->consumer->producer
来调用,通过http://localhost:9100/consumer/simple
也能到spring-cloud-producer
。
现在我们就来看下在gateway
中集成sentinel
:
@Component
public class SentinelConfiguration {
@PostConstruct
public void sentinelGateway(){
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
return ServerResponse.status(200).syncBody("Blocked Error Gateway");
}
});
}
}
我们这里主要是配置了一个当限流成功后供返回的提示信息。
@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudGatewayApplication {
public static void main(String[] args) {
System.setProperty(SentinelConfig.APP_TYPE,"1");
SpringApplication.run(SpringCloudGatewayApplication.class, args);
}
}
二、sentinel相关配置
1)、API分组
然后们启动并访问路由相关的请求就能在控制台看到当前项目了,例如访问http://localhost:9100/consumer/simple
我们来配置api分组
相关的流控:
这里是与我们配置文件配置的路由相关的;
routes:
- id: sentinel-gateway-consumer
uri: lb://spring-cloud-consumer
predicates:
- Path=/consumer/**
- id: sentinel-gateway-producer
uri: lb://spring-cloud-producer
predicates:
- Path=/producer/**
我们配置文件路由是前缀
已及对应的路由路径/consumer/**
。然后再进行流控信息设置:
之后我们请求就能看到:
这个就是与api
分组相关的流控。
2)、Route-ID
下面我们就来看下Route-ID
分组的处理。
我们访问http://localhost:9100/consumer/simple
默认生成了两个名称,其中sentinel-gateway-consumer
就是根据配置文件中的id
生成的,我们可以用它来配置Route-ID
相关的控制:
我们新增控制:
可以看到我们的规则生效了。