W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Hello,大家好,我是 V 哥。最近寫到 使用 Nacos 實現(xiàn)動態(tài)路由的問題,整理了一下思路和案例,分享給大家。
使用 Nacos 實現(xiàn) Spring Cloud Gateway 的動態(tài)路由,主要涉及到以下幾個步驟:
pom.xml
文件中添加 Nacos 相關(guān)依賴。application.yml
或 application.properties
文件中配置 Nacos 服務(wù)地址。下面是具體的實現(xiàn)步驟和代碼案例,來看一下:
在 pom.xml
文件中添加 Spring Cloud Gateway 和 Nacos 相關(guān)依賴:
<dependencies>
<!-- Spring Cloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Nacos Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
在 application.yml
文件中配置 Nacos 服務(wù)地址:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # Nacos 服務(wù)地址
config:
server-addr: 127.0.0.1:8848 # Nacos 配置中心地址
file-extension: yml # 配置文件格式
group: DEFAULT_GROUP # 配置分組
namespace: # 配置命名空間
在 application.yml
文件中啟用 Nacos 動態(tài)路由功能:
spring:
cloud:
gateway:
discovery:
locator:
enabled: true # 開啟從注冊中心動態(tài)創(chuàng)建路由的功能
lower-case-service-id: true # 使用小寫服務(wù)名,默認(rèn)是大寫
在 Nacos 配置中心創(chuàng)建一個配置文件,例如 gateway-routes.yml
,內(nèi)容如下:
spring:
cloud:
gateway:
routes:
- id: my-service-route
uri: lb://MY-SERVICE
predicates:
- Path=/my-service/**
filters:
- StripPrefix=1
在 Spring Cloud Gateway 應(yīng)用中,創(chuàng)建一個配置類來監(jiān)聽 Nacos 配置變化,并刷新路由規(guī)則:
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class DynamicRouteService {
private final RouteDefinitionWriter routeDefinitionWriter;
private final RouteDefinitionLocator routeDefinitionLocator;
public DynamicRouteService(RouteDefinitionWriter routeDefinitionWriter,
RouteDefinitionLocator routeDefinitionLocator) {
this.routeDefinitionWriter = routeDefinitionWriter;
this.routeDefinitionLocator = routeDefinitionLocator;
}
@EventListener
public void onEnvironmentChange(EnvironmentChangeEvent event) {
if (event.getKeys().contains("spring.cloud.gateway.routes")) {
routeDefinitionLocator.getRouteDefinitions()
.subscribe(routeDefinitions -> {
routeDefinitionWriter.delete("*").subscribe();
routeDefinitionWriter.save(routeDefinitions).subscribe();
});
}
}
}
這個類會監(jiān)聽環(huán)境變化事件,當(dāng)檢測到 spring.cloud.gateway.routes
配置項發(fā)生變化時,會重新加載和刷新路由規(guī)則。
我們通過使用 Nacos 實現(xiàn) Spring Cloud Gateway 的動態(tài)路由。通過在 Nacos 配置中心維護路由配置,可以實現(xiàn)不重啟網(wǎng)關(guān)服務(wù)的情況下動態(tài)更新路由規(guī)則,這對于微服務(wù)架構(gòu)中的服務(wù)治理非常有用。
在使用 Nacos 動態(tài)路由時,如果服務(wù)下線了,Spring Cloud Gateway 會如何響應(yīng)?
當(dāng)使用 Nacos 動態(tài)路由時,如果服務(wù)下線,Spring Cloud Gateway 會通過 Nacos 的服務(wù)發(fā)現(xiàn)機制感知到這一變化,并根據(jù)配置的動態(tài)路由規(guī)則進(jìn)行調(diào)整。如何配置 Spring Cloud Gateway 以響應(yīng)服務(wù)下線的情況呢?來,上代碼:
首先,確保咱們的項目中已經(jīng)添加了 Spring Cloud Gateway 和 Spring Cloud Alibaba Nacos Discovery 的依賴。
1. application.yml 配置
在 application.yml
中配置 Nacos 服務(wù)發(fā)現(xiàn)和動態(tài)路由:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # Nacos 服務(wù)地址
gateway:
routes:
- id: my-service-route
uri: lb://MY-SERVICE
predicates:
- Path=/my-service/**
filters:
- StripPrefix=1
discovery:
locator:
enabled: true
lower-case-service-id: true
2. Nacos 配置中心的動態(tài)路由配置
在 Nacos 配置中心創(chuàng)建一個名為 gateway-routes.json
的配置文件,內(nèi)容如下:
{
"spring": {
"cloud": {
"gateway": {
"routes": [
{
"id": "my-service-route",
"uri": "lb://MY-SERVICE",
"predicates": [
{
"name": "Path",
"args": {
"_genkey_0": "/my-service/**"
}
}
],
"filters": [
{
"name": "StripPrefix",
"args": {
"_genkey_1": "1"
}
}
]
}
]
}
}
}
}
3. 動態(tài)路由配置監(jiān)聽
創(chuàng)建一個配置類來監(jiān)聽 Nacos 配置變化,并刷新路由規(guī)則:
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.model.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.route.RoutesRefreshedEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import java.util.Properties as JavaProperties;
@Component
public class NacosDynamicRoute implements ApplicationRunner {
@Autowired
private RouteDefinitionRepository routeDefinitionRepository;
@Autowired
private ApplicationEventPublisher publisher;
private ConfigService configService;
public NacosDynamicRoute(NacosConfigProperties properties) throws NacosException {
JavaProperties javaProperties = new JavaProperties();
javaProperties.setProperty("serverAddr", properties.getServerAddr());
javaProperties.setProperty("namespace", properties.getNamespace());
configService = NacosFactory.createConfigService(javaProperties);
}
@Override
public void run(ApplicationArguments args) {
try {
String routeJson = configService.getConfig("gateway-routes.json", "DEFAULT_GROUP", 5000);
refreshRoutes(routeJson);
configService.addListener("gateway-routes.json", "DEFAULT_GROUP", s -> refreshRoutes(s));
} catch (NacosException e) {
e.printStackTrace();
}
}
private void refreshRoutes(String routeJson) {
SpringCloudRouteDefinition routeDefinition = JsonUtils.deserialize(routeJson, SpringCloudRouteDefinition.class);
routeDefinitionRepository.delete("*").subscribe();
routeDefinitionRepository.save(routeDefinition.getRouteDefinitions()).subscribe();
publisher.publishEvent(new RoutesRefreshedEvent(this));
}
// 內(nèi)部類,用于反序列化 Nacos 配置
static class SpringCloudRouteDefinition {
private RouteDefinition[] routeDefinitions;
// getter 和 setter 省略
}
}
NacosDynamicRoute
類會在應(yīng)用啟動時從 Nacos 配置中心加載路由配置,并注冊一個監(jiān)聽器來監(jiān)聽配置變化。當(dāng)配置發(fā)生變化時,它會重新加載路由配置并刷新路由規(guī)則。點贊+關(guān)注,學(xué)習(xí) Java 不迷路。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: