在前面几篇,我们学习了gateway的断言、过滤、自定义断言过滤以及跨域请求这些,现在我们来进行跟sentinel的整合。
准备
1、我们首先要搭建sentinel环境
七、springCloudAlibaba-sentinel的控制台搭建
这里只需要搭建控制台即可。
2、搭建gateway环境
二十四、springCloudAlibaba-gateway整合nacos
整合sentinel
1、引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2、加上控制台配置
server:
port: 8088
spring:
application:
name: api-gateway
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
username: nacos
password: nacos
namespace: public
#gateway配置
gateway:
#路由规则
routes:
- id: order_route # 路由的唯一标识
uri: lb://order-service #需要转发的地址.lb本地负载均衡策略
#断言规则 用于路由规则的匹配
predicates:
- Path=/order-service/**
#- Query=green,hel.
#- MyCustomize=test
#- After=2023-11-13T21:05:39.811+08:00[Asia/Shanghai]
#匹配请求http://localhost:8088/order-service/order/add
#过滤器 用于过滤请求
filters:
- StripPrefix=1 #转发之前去掉第一层路径
- AddRequestHeader=X-Request-red, blue
#- AddRequestParameter=red, blue
#- MyCustomize=from,suibibk.com
#http://localhost:8010/order/add
#- id: stock_route
#globalcors:
#cors-configurations:
#'[/**]': #允许跨域访问的资源
#allowedOrigins: "*" #跨域来源
#allowedMethods:
# - GET
#- POST
sentinel:
transport:
dashboard: localhost:8084
其实就是这个
sentinel:
transport:
dashboard: localhost:8084
3、启动测试 105
启动后我们需要先请求下http://localhost:8088/order-service/order/add ,才会在控制太看到。
可以看到跟之前的sentinel控制台还是有点区别的,有对gateway进行适配
我们设置个限流规则。访问测试发现,成功限流了。
我们还可以根据API分组来对某些请求统一控制
我们也可以设置对参数进行限流,以及各种规则
更多控制规则可以自行尝试
自定义异常
这里我们进行自定义异常在网关加上如下代码即可
package com.suibibk.springCloud.gateway;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
@Configuration
public class GatewayConfig {
@PostConstruct
public void init(){
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Result r = null;
if(throwable instanceof FlowException){
r = Result.error(100,"接口被限流了");
}else if (throwable instanceof DegradeException){
r = Result.error(101,"服务降级了");
}else if (throwable instanceof ParamFlowException){
r = Result.error(102,"热点参数限流了");
}else if (throwable instanceof SystemBlockException){
r = Result.error(103,"系统规则");
}else if (throwable instanceof AuthorityException){
r = Result.error(104,"授权规则不通过");
}
if(r==null){
r = Result.error(105,"当前请求人数过多,请稍后再试");
}
//自定义异常处理
return ServerResponse.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(r));
}
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
}
package com.suibibk.springCloud.gateway;
public class Result<T> {
private Integer code;
private String msg;
private T data;
public Result(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Result(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static Result error(Integer code,String msg){
return new Result(code,msg);
}
}
然后就会按我们定义的返回了
gateway篇完结!
ok!