spring cloud gateway和nacos整合
期望結果:
- 通過輸入http://127.0.0.1:8080/first,跳到嗶哩嗶哩主頁。然后通過修改nacos的配置中心里面gateway的配置,使得再次輸入地址,跳到百度主頁
- 整合nacos和spring cloud gateway。使得spring cloud gateway能讀取到naco的服務注冊信息,通過這些服務注冊信息進行分發。
spring cloud gateway配置
yml依賴:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
</dependencies>
注意:Hoxton.SR4這個版本是需要添加spring-boot-starter-validation的,不然會報錯的。其他版本不清楚會不會
bootstrap.yml配置:
spring:
application:
name: gateway-nacos
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
enabled: true
config:
file-extension: yaml
server-addr: 127.0.0.1:8848
server:
port: 8080
java代碼實現:
啟動類:
@SpringBootApplication
@EnableDiscoveryClient //開啟服務注冊
public class NacosGatewayApp {
public static void main(String[] args) {
SpringApplication.run(NacosGatewayApp.class,args);
}
}
nacos動態路由實現類:
/**
* @Author: gyc
* @Date: 2020/12/4 16:18
*/
@Component
public class NacosRouteDefinitionRepository implements RouteDefinitionRepository , ApplicationContextAware {
@Autowired
private NacosConfigProperties nacosConfigProperties;
private String dataId = "gatewayId";
private String groupId = "gatewayGroup";
public Flux<RouteDefinition> getRouteDefinitions() {
List<RouteDefinition> list = new ArrayList();
try {
//獲取組名是gatewayGroup,dataId是gatewayId的配置。5000代表超時時間
String content = nacosConfigProperties.configServiceInstance().getConfig(dataId,groupId,5000);
List<RouteDefinition> tmpList = JSONObject.parseArray(content, RouteDefinition.class);
if(tmpList != null){
list = tmpList;
}
} catch (Exception e) {
e.printStackTrace();
}
return Flux.fromIterable(list);
}
public Mono<Void> save(Mono<RouteDefinition> route) {
return null;
}
public Mono<Void> delete(Mono<String> routeId) {
return null;
}
/**
* 項目啟動的時候會觸發這個方法。
* 方法實現: 監聽節點的變化,如果節點變化就發送RefreshRoutesEvent事件。
* gateway收到RefreshRoutesEvent事件的話,就會觸發getRouteDefinitions方法了
* @param applicationContext
* @throws BeansException
*/
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
try {
nacosConfigProperties.configServiceInstance().addListener(dataId, groupId, new Listener() {
public Executor getExecutor() {
return null;
}
public void receiveConfigInfo(String s) {
//如果節點變化就發送RefreshRoutesEvent事件。
applicationContext.publishEvent(new RefreshRoutesEvent(this));
}
});
} catch (NacosException e) {
e.printStackTrace();
}
}
}
整體實現:
-
因為
NacosRouteDefinitionRepository
實現了ApplicationContextAware
接口,所以項目啟動的時候會觸發setApplicationContext
方法。 -
setApplicationContext: 監聽節點的變化,如果節點變化就發送RefreshRoutesEvent事件。
-
gateway收到RefreshRoutesEvent事件的話,就會觸發getRouteDefinitions方法了(這里需要實現RouteDefinitionRepository接口,才會觸發方法)
下面在下個圖就是程序的走向。
nacos-client的配置
yml的依賴:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
application.yml配置文件:
server:
port: 8061
spring:
application:
name: nacos-client
cloud:
nacos:
discovery:
register-enabled: true
server-addr: 127.0.0.1:8848
代碼實現:
/**
* @author gyc
* @date 2020/12/6
*/
@SpringBootApplication
@EnableDiscoveryClient
public class NacosClientApp {
public static void main(String[] args) {
SpringApplication.run(NacosClientApp.class,args);
}
}
@RestController
@RequestMapping
public class HelloController {
@GetMapping("/sayHello")
public String sayHello(){
return "sayHello";
}
}
nacos的一些配置
由上面的gateway的配置來看,我們是沒有給gateway配置路由信息的。這時候我們是要通過nacos的統一的配置中心來做個配置。
注意: 我們這個是通過讀取json的方式,來做解析的,這里斷言和過濾器的的配置方式需要是使用Fully Expanded Arguments
可以看會我之前的有一篇叫做Spring Cloud Gateway入門demo博文里面的斷言和過濾器配置方式章節,地址如下:
新增一個配置信息:
配置內容如下:
[{
"id": "first_route",
"predicates": [{
"name": "Path",
"args": {"_genkey_0":"/first"}
}],
"filters": [{
"name" : "StripPrefix",
"args":{"parts":"1"}
}],
"uri": "https://www.bilibili.com/",
"order": 0
},
{
"id":"nacos-client",
"predicates": [{
"name": "Path",
"args": {"_genkey_0":"/nacos/**"}
}],
"filters": [{
"name" : "StripPrefix",
"args":{"parts":"1"}
}],
"uri": "lb://nacos-client",
"order": 0
}
]
這個配置包括兩個路由的信息
- 第一個路由first_route: 當輸入127.0.0.1:8080/first_route 路徑的時候會跳到https://www.bilibili.com/頁面
- 第二個路由nacos-client: 當輸入127.0.0.1:8080/nacos/say/**的路徑的時候會跳到lb://nacos-client/**頁面。
效果展示
通過輸入http://127.0.0.1:8080/first,跳到嗶哩嗶哩主頁。然后通過修改nacos的配置中心里面gateway的配置,使得再次輸入地址,跳到百度主頁
如果加載不出gif圖請訪問:https://gitee.com/gzgyc/blogimage/raw/master/gatewayAndNacos20201209.gif