一、查看SringCloud Gateway 官方文档,Gateway 工作原理如下图:
客户端请求,首先会被
Gateway Handler Mapping
处理,用以在 路由表 中查找一个与请求匹配的 路由 ,然后将请求交由Web Handler
处理,Web Handler
维护了一个过滤器链,链式执行这些过滤器,这些过滤器在逻辑上存在两个执行阶段pre
与post
二、Nacos官方简介
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。主要特性如下:
1. 服务发现和服务健康监测
2. 动态配置服务
3. 动态 DNS 服务
4. 服务及其元数据管理
三、实现思路
四、代码
1、依赖
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<!--负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!--nacos-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、yml配置
server:
port: 8001
spring:
application:
name: springcloud-alibaba-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
#网关配置
gateway:
discovery:
locator:
#服务名小写
lower-case-service-id: true
####################
##nacos动态路由配置格式##
#[{
# "id": "b-service-user",
# "uri": "lb://b-service-user", # lb协议表示启用负载均衡功能,然后后面跟着微服务名称
# "predicates": [{
# "name": "Path",
# "args": {
# "pattern":"/user/**"
# }
# }],
# "filters": [{
# "name": "StripPrefix",
# "args": {
# "pattern": 1
# }
# }]
# }]
# 配置
config:
# 动态
dynamic-route:
# nacos 配置dataId
dataId: gateway-routes
# 分组
group: GATEWAY_GROUP
# nacos服务地址
server-addr: 127.0.0.1:8848
3、NacosDynamicRouteService
package com.llj.config;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
/**
* @PakcageName:com.llj.config
* @ClassName:NacosDynamicRouteService
* @Description: 监听nacos配置
* @Author:liulianjia
* @Date:2022/9/20 23:04
*/
@Component
public class NacosDynamicRouteService implements ApplicationEventPublisherAware {
@Value("${config.dynamic-route.dataId}")
private String dataId;
@Value("${config.dynamic-route.group}")
private String group;
@Value("${config.dynamic-route.server-addr}")
private String serverAddr;
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher applicationEventPublisher;
private static final List<String> ROUTE_LIST = new ArrayList<>(16);
@PostConstruct
public void dynamicRouteByNacosListener() {
try {
ConfigService configService = NacosFactory.createConfigService(serverAddr);
configService.getConfig(dataId, group, 5000);
configService.addListener(dataId, group, new Listener() {
@Override
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();
}
}
@Override
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));
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
}
4、启动类
package com.llj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @PakcageName:com.llj
* @ClassName:GatewayApplication
* @Description:
* @Author:liulianjia
* @Date:2022/9/20 22:40
*/
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
System.out.println("----- 服务网关启动 -----");
}
}
5、测试,Nacos添加路由配置,注意"Data ID" 和 “Group”要和配置一一对应
通过actuator的接口测试下(可以看到已经路由已经加载到本地内存)
文章来源:https://www.toymoban.com/news/detail-456613.html
文章来源地址https://www.toymoban.com/news/detail-456613.html
到了这里,关于Gateway基于Nacos动态路由实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!