Invited to enjoy science classroom Author: Gu old
reprint please state the source!
Preface
After the development of our Gateway program is completed, it needs to be deployed to the production environment. At this time, your program cannot be run at a single point. It must be started on multiple nodes (independent deployment or container deployment such as docker) to prevent single node failure from causing the entire service Inaccessible, the gateway is the entrance and exit to the client, which is extremely important in production and operation . Even a simple restart will cause the loss of some requests.
The routing configuration of the gateway is a big problem at this time . Is it written in the code or configured in a configuration file? They all have a fatal shortcoming. When a new program needs to be connected to the gateway for routing or when a service needs to go offline, the code or configuration needs to be modified, and then the entire gateway program is restarted , causing other normal service routing to be affected.
Therefore, in the actual production environment, in order to ensure high reliability and high availability, it is necessary to avoid restarting the gateway as much as possible, so it is very necessary to implement dynamic routing;
This article mainly introduces the idea of Spring Cloud Gateway implementation, and stores the routing information in an external source , this one uses Nacos as the data source to explain.
Implementation points
To achieve dynamic routing, just pay attention to the following 4 points
- How to load dynamic routing data when the gateway is started
- Static routing and dynamic routing are subject to that
- Monitor data source changes for dynamic routing
- How to notify the gateway to refresh the route when the data changes
ps: Static routing refers to the hard-coded routing configuration in the configuration file
Implementation
The following classes are responsible for loading routing information in Spring Cloud Gateway
- PropertiesRouteDefinitionLocator : read routing information from the configuration file (such as YML, Properties, etc.)
- RouteDefinitionRepository : Read routing information from storage (such as memory, configuration center, Redis, MySQL, etc.)
- DiscoveryClientRouteDefinitionLocator : Read routing information from the registry (such as Nacos, Eurka, Zookeeper, etc.)
We can achieve the purpose of dynamic routing by customizing the implementation class of RouteDefinitionRepository
Realize dynamic road
Loaded by the data we can view the implementation class of the source RouteDefinitionRepository , only InMemoryRouteDefinitionRepository , this implementation class is stored in memory.
We can redefine a nacos as a storage implementation, see the following code
The core of the above code is to rewrite the getRouteDefinitions method to read routing information ; this method involves the Api method of the ConfigService object .
Management Api method, this old customer will not go into details here; friends can be understood as the object of operating nacos config
To configure the Nacos listener to monitor changes in routing configuration information , you also use the api method, that is, the addListener method; this method is known at a glance, and is used to monitor changes in config information.
The routing changes in this addListener method only need to push a RefreshRoutesEvent event to ApplicationEventPublisher, and the gateway will automatically monitor the event and call the getRouteDefinitions method to update the routing information .
In this way, the routing is dynamically updated.
Configuration class
In order to better use this dynamic routing as a public core, we need to use the configuration class to achieve the way to enable it; developers can configure it themselves.
The above configuration class has two important **@ConditionalOnProperty, this is used to control whether to enable dynamic routing, and whether to use nacos as storage. **
There are also @Value annotations that define the DataId and Group where we store routing information. If application.yml is not configured, the default values are scg-routes and SCG_GATEWAY
Add Nacos routing configuration
Create scg-routes and SCG_GATEWAY in the same namespace
The format is json, the format in the json body is actually the attribute of the RouteDefinition class
Note that the json of the above configuration is in array format, that is, there can be many routes
[{
"id": "baidu",
"order": 0,
"predicates": [{
"args": {
"pattern": "/baidu/**"
},
"name": "Path"
}],
"uri": "https://www.baidu.com"
},{
"id": "sina",
"order": 2,
"predicates": [{
"args": {
"pattern": "/sina/**"
},
"name": "Path"
}],
"uri": "http://www.sina.com.cn"
}]
test
Configure in application.yml in the gateway project
rainbow:
gateway:
dynamicRoute:
enabled: true
Start the gateway, that's it; in order to see the current routing information of the gateway, we need to import
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
And configure in application.yml
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
gateway:
enabled: true
health:
show-details: always
So we can visit http://localhost:8081/actuator/gateway/routes, we can see the routing information
Friends can try to modify the dataId in nacos to scg-routes, we can find that the route has been changed in time.
Old Gu only modified the name of route_id, and the route was updated in time
We have also seen the corresponding changes in the console log
to sum up
The dynamic routing of gateway is a very practical function, it is a necessary function in the production environment, you must master it. Of course, you can also use other data sources. Thank you! ! !