Spring cloud gateway的三个核心概念
route 路由
可以理解为一条转发规则,包含:
- id
- 目标url
- 断言(predicate)
- 过滤器(filter)
若断言为true,则请求将经由 filter 被路由到目标 url。
predicate 断言
可以理解为一个条件判断,对当前的http请求进行指定规则的匹配,当匹配上规则时,断言才为true,此时请求会被路由到目标地址,服务或者过滤器
filter 过滤器
对请求进行处理的逻辑部分。当请求的断言为true 时,会被路由到设置好的过滤器, 以对请求进行处理。例如,可以为请求添加一个请求头,或添加一个请求参数,或对请求URI 进行修改等。
Nacos作为路由规则的配置中心
nacos的配置和运行如下
- MySQL配置运行
运行MySQL
docker run -p 3306:3306 --name mysql \ -v /Users/wangbin/dockerall/mysql/log:/var/log/mysql \ -v /Users/wangbin/dockerall/mysql/data:/var/lib/mysql \ -v /Users/wangbin/dockerall/mysql/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD=root \ -d mysql:5.7 docker exec -it mysql bash mysql -proot create database nacos_config; use nacos_config;
- 执行SQL
SQL内容 新建/xxxxx/nacos_docker/init.d/目录并生成custom.properties文件。文件内容如下
management.endpoints.web.exposure.include=* server.contextPath=/nacos server.servlet.contextPath=/nacos server.port=8848 spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=root db.password=root nacos.cmdb.dumpTaskInterval=3600 nacos.cmdb.eventTaskInterval=10 nacos.cmdb.labelTaskInterval=300 nacos.cmdb.loadDataAtStart=false management.metrics.export.elastic.enabled=false management.metrics.export.influx.enabled=false server.tomcat.accesslog.enabled=true server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health/**,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**,/v1/console/server/** nacos.naming.distro.taskDispatchThreadCount=1 nacos.naming.distro.taskDispatchPeriod=200 nacos.naming.distro.batchSyncKeyCount=1000 nacos.naming.distro.initDataRatio=0.9 nacos.naming.distro.syncRetryDelay=5000 nacos.naming.data.warmup=true nacos.naming.expireInstance=true
- 新建logs目录
运行Nacos
docker run --name nacos -d -p 8848:8848 --privileged=true --restart=always -e JVM_XMS=256m -e JVM_XMX=256m -e MODE=standalone -e PREFER_HOST_MODE=hostname -v /xxxxx/nacos_docker/init.d/custom.properties:/home/nacos/init.d/custom.properties -v /xxxxx/nacos_docker/logs:/home/nacos/logs nacos/nacos-server
- 访问 http://localhost:8848
- 输入 nacos/nacos登陆
新建配置内容
内容如下
[{
"id":"user-router",
"predicates":[
{
"args":{
"pattern": "/usr/**"
},
"name": "Path"
}
],
"filters": [
{
"name": "StripPrefix",
"args": {
"parts": "1"
}
}
],
"uri": "lb://user-service"
}]
对应的yml内容如route部分
spring:
application:
name: dynamicgateway
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
config:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true
routes:
- id: user-router
uri: lb://user-service
predicates:
- Path=/usr/**
filters:
- StripPrefix=1 # 表示在转发时去掉usr
新建项目
因为使用了Spring cloud,Spring Cloud Alibaba,Nacos之间的版本依赖关系如下
版本依赖关系
新建DynamicGatewayRouteConfig
@Component
public class DynamicGatewayRouteConfig implements ApplicationEventPublisherAware {
private String dataId = "gateway-router";
private String group = "DEFAULT_GROUP";
@Value("${spring.cloud.nacos.config.server-addr}")
private String serverAddr;
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher applicationEventPublisher;
private static final List<String> ROUTE_LIST = new ArrayList<String>();
@PostConstruct
public void dynamicRouteByNacosListener() {
try {
ConfigService configService = NacosFactory.createConfigService(serverAddr);
configService.getConfig(dataId, group, 5000);
configService.addListener(dataId, group, new Listener() {
public void receiveConfigInfo(String configInfo) {
clearRoute();
try {
List<RouteDefinition> gatewayRouteDefinitions = JSONObject.parseArray(configInfo, RouteDefinition.class);
for (RouteDefinition routeDefinition : gatewayRouteDefinitions) {
addRoute(routeDefinition);
}
publish();
} catch (Exception e) {
e.printStackTrace();
}
}
public Executor getExecutor() {
return null;
}
});
} catch (NacosException e) {
e.printStackTrace();
}
}
private void clearRoute() {
for (String id : ROUTE_LIST) {
this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
}
ROUTE_LIST.clear();
}
private void addRoute(RouteDefinition definition) {
try {
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
ROUTE_LIST.add(definition.getId());
} catch (Exception e) {
e.printStackTrace();
}
}
private void publish() {
this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this.routeDefinitionWriter));
}
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
}
在nacos的route内容发生变化时会自动调用更新
bootstrap.yml内容如下
spring:
application:
name: dynamicgateway
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
config:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
具体代码
代码
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。