基于Nacos實(shí)現(xiàn)Spring Cloud Gateway實(shí)現(xiàn)動(dòng)態(tài)路由的方法
簡介
該文檔主要介紹以Nacos為配置中心,實(shí)現(xiàn)Spring Cloud GateWay 實(shí)現(xiàn)動(dòng)態(tài)路由的功能。Spring Cloud Gateway啟動(dòng)時(shí)候,就將路由配置和規(guī)則加載到內(nèi)存里,無法做到不重啟網(wǎng)關(guān)就可以動(dòng)態(tài)的對(duì)應(yīng)路由的配置和規(guī)則進(jìn)行增加,修改和刪除。通過nacos的配置下發(fā)的功能可以實(shí)現(xiàn)在不重啟網(wǎng)關(guān)的情況下,實(shí)現(xiàn)動(dòng)態(tài)路由。
集成
Spring Cloud GateWay集成
spring-cloud-starter-gateway:路由轉(zhuǎn)發(fā)、請(qǐng)求過濾(權(quán)限校驗(yàn)、限流以及監(jiān)控等)
spring-boot-starter-webflux:反應(yīng)式Web框架
spring-boot-starter-actuator:監(jiān)控系統(tǒng)健康
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
Nacos集成
nacos-client:nacos客戶端,現(xiàn)在用比較新的版本0.9.0
<dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>0.9.0</version> </dependency>
動(dòng)態(tài)路由
DynamicRouteServiceImpl:提供動(dòng)態(tài)路由的基礎(chǔ)方法,可通過獲取bean操作該類的方法。該類提供新增路由、更新路由、刪除路由,然后實(shí)現(xiàn)發(fā)布的功能。
@Service
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher publisher;
/**
* 增加路由
* @param definition
* @return
*/
public String add(RouteDefinition definition) {
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
}
/**
* 更新路由
* @param definition
* @return
*/
public String update(RouteDefinition definition) {
try {
this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
} catch (Exception e) {
return "update fail,not find route routeId: "+definition.getId();
}
try {
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
} catch (Exception e) {
return "update route fail";
}
}
/**
* 刪除路由
* @param id
* @return
*/
public String delete(String id) {
try {
this.routeDefinitionWriter.delete(Mono.just(id));
return "delete success";
} catch (Exception e) {
e.printStackTrace();
return "delete fail";
}
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
RouteDefinition: 提供路由實(shí)體類,主要有predicates匹配來自用戶的請(qǐng)求,filters服務(wù)路由
@Validated
public class RouteDefinition {
@NotEmpty
private String id = UUID.randomUUID().toString();
@NotEmpty
@Valid
private List<PredicateDefinition> predicates = new ArrayList<>();
@Valid
private List<FilterDefinition> filters = new ArrayList<>();
@NotNull
private URI uri;
private int order = 0;
public RouteDefinition() {}
public RouteDefinition(String text) {
int eqIdx = text.indexOf("=");
if (eqIdx <= 0) {
throw new ValidationException("Unable to parse RouteDefinition text '" + text + "'" +
", must be of the form name=value");
}
setId(text.substring(0, eqIdx));
String[] args = tokenizeToStringArray(text.substring(eqIdx+1), ",");
setUri(URI.create(args[0]));
for (int i=1; i < args.length; i++) {
this.predicates.add(new PredicateDefinition(args[i]));
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<PredicateDefinition> getPredicates() {
return predicates;
}
public void setPredicates(List<PredicateDefinition> predicates) {
this.predicates = predicates;
}
public List<FilterDefinition> getFilters() {
return filters;
}
public void setFilters(List<FilterDefinition> filters) {
this.filters = filters;
}
public URI getUri() {
return uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RouteDefinition routeDefinition = (RouteDefinition) o;
return Objects.equals(id, routeDefinition.id) &&
Objects.equals(predicates, routeDefinition.predicates) &&
Objects.equals(order, routeDefinition.order) &&
Objects.equals(uri, routeDefinition.uri);
}
@Override
public int hashCode() {
return Objects.hash(id, predicates, uri);
}
@Override
public String toString() {
return "RouteDefinition{" +
"id='" + id + '\'' +
", predicates=" + predicates +
", filters=" + filters +
", uri=" + uri +
", order=" + order +
'}';
}
}
NacosGatewayProperties:自定義屬性綁定值,可通過配置文件配置屬性。
@ConfigurationProperties(prefix="nacos", ignoreUnknownFields = true)
@Configuration
public class NacosGatewayProperties {
private String address;
private String dataId;
private String groupId;
private Long timeout;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public Long getTimeout() {
return timeout;
}
public void setTimeout(Long timeout) {
this.timeout = timeout;
}
}
DynamicRouteServiceImplByNacos: 實(shí)現(xiàn)runner,通過nacos下發(fā)動(dòng)態(tài)路由配置
@Component
public class DynamicRouteServiceImplByNacos implements CommandLineRunner{
@Autowired
private DynamicRouteServiceImpl dynamicRouteService;
@Autowired
private NacosGatewayProperties nacosGatewayProperties;
/**
* 監(jiān)聽Nacos Server下發(fā)的動(dòng)態(tài)路由配置
* @param dataId
* @param group
*/
public void dynamicRouteByNacosListener (){
try {
ConfigService configService=NacosFactory.createConfigService(nacosGatewayProperties.getAddress());
String content = configService.getConfig(nacosGatewayProperties.getDataId(), nacosGatewayProperties.getGroupId(), nacosGatewayProperties.getTimeout());
System.out.println(content);
configService.addListener(nacosGatewayProperties.getDataId(), nacosGatewayProperties.getGroupId(), new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
List<RouteDefinition> list = JsonUtils.toList(configInfo, RouteDefinition.class);
list.forEach(definition->{
dynamicRouteService.update(definition);
});
}
@Override
public Executor getExecutor() {
return null;
}
});
} catch (NacosException e) {
e.printStackTrace();
}
}
@Override
public void run(String... args) throws Exception {
dynamicRouteByNacosListener();
}
}
nacos配置下發(fā)
nacos配置
nacos: address: 127.0.0.1:8848 data-id: dhap-gateway # group-id: AAA timeout: 5000
nacos屬性文件定義
新建dataID為
groupID為AAA

[
{
"filters": [],
"id": "blog1",
"order": 0,
"predicates": [{
"args": {
"pattern": "/z"
},
"name": "Path"
}],
"uri": "https://blog.csdn.net/zhangchangbin123"
},
{
"filters": [],
"id": "blog1",
"order": 0,
"predicates": [{
"args": {
"pattern": "/c"
},
"name": "Path"
}],
"uri": "https://blog.csdn.net/zhangchangbin123"
}
]
查看路由信息




到此這篇關(guān)于基于Nacos實(shí)現(xiàn)Spring Cloud Gateway實(shí)現(xiàn)動(dòng)態(tài)路由的方法的文章就介紹到這了,更多相關(guān)Spring Cloud Gateway動(dòng)態(tài)路由內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 詳解Spring Cloud Gateway 限流操作
- spring cloud gateway使用 uri: lb://方式配置時(shí),服務(wù)名的特殊要求
- 解決spring cloud gateway 獲取body內(nèi)容并修改的問題
- springcloud gateway如何實(shí)現(xiàn)路由和負(fù)載均衡
- springcloud gateway聚合swagger2的方法示例
- 詳解SpringCloud Gateway之過濾器GatewayFilter
- Spring Cloud Gateway全局異常處理的方法詳解
- spring cloud gateway整合sentinel實(shí)現(xiàn)網(wǎng)關(guān)限流
- Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)
相關(guān)文章
Jdk11使用HttpClient提交Http2請(qǐng)求的實(shí)現(xiàn)方法
這篇文章主要介紹了Jdk11使用HttpClient提交Http2請(qǐng)求的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
解決java.lang.NoClassDefFoundError:lombok/Data報(bào)錯(cuò)問題
在Java開發(fā)中,使用Lombok庫簡化代碼非常普遍,今天在啟動(dòng)拉取的git代碼時(shí),遇到了java.lang.NoClassDefFoundError:lombok/Data的報(bào)錯(cuò),經(jīng)過檢查,發(fā)現(xiàn)錯(cuò)誤的原因是將Date誤寫為Data,且錯(cuò)誤地引用了lombok.Data包2024-09-09
Java之idea @NotNull @Nullable 注解使用
這篇文章主要介紹了Java之idea @NotNull @Nullable 注解使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
新建springboot項(xiàng)目時(shí),entityManagerFactory報(bào)錯(cuò)的解決
這篇文章主要介紹了新建springboot項(xiàng)目時(shí),entityManagerFactory報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
java實(shí)現(xiàn)全局監(jiān)聽鍵盤詳解
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)全局監(jiān)聽鍵盤的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下2024-01-01
SpringBoot配置文件properties和yml的實(shí)現(xiàn)
本文主要介紹了SpringBoot配置文件properties和yml的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04

