spring boot / cloud (20) The same service, different versions are released to support parallel business requirements

spring boot / cloud (20) The same service, different versions are released to support parallel business requirements

It has not been updated for more than half a year. According to the regular script, it should be said that the project is very busy, the work is very busy, and there is no time to update.

But think about it carefully, is it true? Are you too busy to type these few words? After all, everyone is busy, so there is no reason to be busy.

Why is that? I feel that there is only one reason to stand up, and that is because of "lazy". Haha...

We chatted awkwardly for a while, to activate the atmosphere, let's get to the point

Scenes

In actual work, everyone may have encountered such a situation:

A project in the process of updating and iterating will receive a large number of requirements from business departments, and these requirements may come from different business departments or different product managers

The onwer of the project needs to receive these requirements, conduct preliminary analysis and scheduling of these requirements, but in the process of scheduling, there will be such an embarrassing situation.

For example, there are two product managers who are different from each other. For the same function point, they put forward two different business transformation requirements. The two requirements are required to be launched at a very close time, but for some reason, they cannot be used at the same time. Go online, or the product manager can't determine the launch time at all, and tells you to complete the development/testing as soon as possible, he will determine the release time of business requirements according to the actual situation

Then, in this case, the development of open branches is usually adopted, that is, the development of parallel requirements of different versions is developed at the same time on different branches, then the team members (development/testing) can carry out work at the same time, Some are responsible for A's needs, some are responsible for B's needs, without affecting each other

In the initial development stage, everything went smoothly, but after the development was completed, the test was intervened, and the system was about to enter the test environment for integration testing, then the problem came.

Version A and Version B currently belong to different branches. If integration testing is to be performed at the same time, how should the system be deployed?

plan

According to the above scenario, in fact, the core problem is that it is possible to test different versions of the same service at the same time without adding multiple sets of integration tests.

Our project is built based on spring cloud, so the solution is to judge according to different version numbers at the gateway layer and reassign the serviceId of the gateway route, then look at the relevant implementation below:

Architecture diagram

Enter image description

Related implementation

First, define different version numbers on different branches, and then splicing the application name with the version number, so that when the application is registered to eureka, due to the different version numbers, it will be recognized as a different service

info.app.version=v1 # 其他分支上定义其他版本号
spring.application.name=service-a-${info.app.version}

Secondly, add a routing interceptor to the zuul layer, mainly to grab the version number (of course, this version number does not have to be placed in the header), obtain the serviceId matched by zuul in advance according to the url root, and then splicing the version number to let it route To the correct service, to achieve the purpose of changing the agent's behavior

@Component
public class VersionChangeFilter extends ZuulFilter {
    
    @Autowired
    private DiscoveryClient discoveryClient;


    @Override
    public String filterType() {
        return ROUTE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 9;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return ctx.sendZuulResponse();
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String version=request.getHeader("version");
        if(StringUtils.isNotBlank(version)){
            String serviceId=String.valueOf(ctx.get("serviceId")).concat(version).toLowerCase();
            List<String> services = discoveryClient.getServices();
            if(services.contains(serviceId)){
                ctx.set("serviceId",serviceId);
            }
        }
        return null;
    }
}

end

In this way, on the premise of not adding any environmental resources, services of different versions can be released at the same time. It meets the needs of parallel integration testing

Of course, again, there are many ways to solve the same problem, and the method I mentioned above is not necessarily the best. If you have better experience, you are welcome to discuss it.

Regarding the content of this article, your comments and suggestions are welcome

Code repository (blog supporting code)


If you want to get the fastest update, please pay attention to the public number

Enter image description

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324464947&siteId=291194637