First, basic logic
The service is requested through 8001. In the gray rule, the service list of the next request is read. According to the version number parameter rule, the route service is selected.
Configure the version number to distinguish the grayscale version from the default normal version. Custom interceptors that manage version numbers or other identifying parameters passed in requests; User-defined Service Select a policy to route services based on version identification. If the grayscale service does not exist, the default service is selected based on the rule.
2. Version configuration
Configure two services on the Node12-Server cluster: v7.0.0 on port 8002 and v7.0.1 on port 8003 to test grayscale version selection.
8002 service
Eureka: metadata - map: version: v7.0.0Copy the code
8003 service
Eureka: metadata - map: version: v7.0.1Copy the code
Eureka Registry, List of services:
Parameter transfer
Microservices manage Feign RequestInterceptor between services by implementing the RequestInterceptor interface. Before routing the request to the service, it can perform some processing operations on the request, such as passing the version number, user Token and other request attributes.
/** * Request interceptor */
@Component
public class GrayReqInterceptor implements RequestInterceptor {
private static final String VERSION_KEY = "versionId" ;
/** * handle request header parameter carrying problem */
@Override
public void apply(RequestTemplate requestTemplate) {
HttpServletRequest request =
((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
String versionId = request.getHeader(VERSION_KEY);
if(StringUtils.isNotEmpty(versionId)){ requestTemplate.header(VERSION_KEY,versionId); }}}Copy the code
Here a versionId parameter is passed as the core identity of the routing service for the next request.
Four, gray scale rules
Add the version number to be accessed to the Header of the request Header, route all requested grayscale services if there is a match, and return the default service if there is none.
@Configuration
public class GrayRule extends ZoneAvoidanceRule {
@Bean
public GrayReqInterceptor grayReqInterceptor(a){
return new GrayReqInterceptor();
}
private static final String VERSION_KEY = "versionId" ;
@Override
public Server choose(Object key) {
HttpServletRequest request =
((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
String versionId = request.getHeader(VERSION_KEY);
// Service match
List<Server> serverList = this.getPredicate().getEligibleServers(this.getLoadBalancer().getAllServers(), key);
Server toServer = getServer(serverList,versionId);
if(toServer ! =null) {return toServer ;
} else {
returngetServer(serverList,GrayConstant.VERSION_DEF); }}private Server getServer (List<Server> serverList,String version){
Server toServer = null ;
for (Server server : serverList) {
Map<String, String> metadata = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata();
String metaVersion = metadata.get("version");
if(! StringUtils.isEmpty(metaVersion)) {if(metaVersion.equals(version)) { toServer = server; }}}returntoServer ; }}Copy the code
In the actual process, the selection of services is very complicated. If there is no gray service, the rules of service matching need to be formulated according to the actual situation, such as by response time or default polling.
More importantly, once secondary encapsulation of the underlying API is used, the project as a whole is affected by the framework version upgrade, requiring constant attention to the framework environment.
Five, the test process
1. Start related services and view the registry service list.
2. Request the interface of service 8001 with the version number.
3. View routing services of different versions.
4. Check the default service selection without the version number.