zoukankan      html  css  js  c++  java
  • spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求

    spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求

    有半年多没有更新了,按照常规剧本,应该会说项目很忙,工作很忙,没空更新,吧啦吧啦,相关的话吧,

    但是细想想,是真的么?,忙到这几个字都没时间打么?毕竟大家都很忙的,所以忙并不是啥理由.

    那是因为啥呢?感觉就只有一个理由能站得住脚了,就是因为"懒". 哈哈....

    尬聊了一段,活跃下气氛,下面进入正题

    场景

    在实际工作中,大家可能也都遇到过这样的情况 :

    一个正在更新迭代过程中项目,会收到大量业务部门的需求,这些需求可能会来自于不同业务部门,或者不同的产品经理

    而项目的onwer则需要接收到这些需求,对这些需求进行初步的分析和排期,但是在排期的过程中,会有这样一种尴尬的情况发生.

    比如,有两个互不嗒噶的产品经理,针对同一功能点,提出了两个不同业务改造的需求点,两个需求点要求上线的时间很接近,但是又出于某种原因,不能同时上线,或者产品经理根本无法确定上线时间,而告诉你尽快完成开发/测试,他则根据实际情况确定业务需求的发布时间

    那么,对于这种情况,通常会采用开分支的方式进行开发,即不同版本的并行需求的开发在不同分支上同时进行开发,那么,团队成员(开发/测试),则可以同时的开展工作,有的负责A需求,有的负责B需求,互不影响

    起初开发阶段的时候,一切很顺利,但是等到开发完毕提测后,测试介入,系统要打入测试环境进行集成测试的时候,那么问题就来了.

    A版本和B版本,目前所属在不同分支上,如果要同时进行集成测试,那系统应该如何部署呢?

    方案

    根据上述场景,其实核心问题是,在不添加多套集成测试的环境下,也能针对同一个服务的不同版本,同时进行测试.

    我们项目是基于spring cloud构建的,那么解决的思路就是,在网关层根据不同的版本号进行判断,重新指派网关路由的serviceId,那么下面看相关的实现:

    架构图

    输入图片说明

    相关实现

    首先,在不同的分支上定义不同的版本号,然后将应用名称拼接上版本号,这样应用在注册到eureka的时候,由于版本号不同,那么就会被认定为是不同的服务

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

    其次,在zuul层添加路由拦截器,主要是抓取版本号(当然,这个版本号不一定要放在header里面),获得zuul预先根据url根匹配的serviceId,然后拼接上版本号,让其路由到正确的服务中,达到改变代理行为的目的

    @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;
        }
    }
    

    结束

    这样一来,在不增加任何环境资源的前提下,可以实现不同版本服务的服务同时发布.满足了并行集成测试的需求

    当然,还是那句话,解决同样问题的方法有多种,我上述的方法也不一定是最好的,如果有更好经验的同学,欢迎大家踊跃讨论.

    关于本文内容 , 欢迎大家的意见跟建议

    代码仓库 (博客配套代码)


    想获得最快更新,请关注公众号

    输入图片说明

  • 相关阅读:
    Talend open studio数据导入、导出、同步Mysql、oracle、sqlserver简单案例
    Mysql彻底卸载
    .net图片快速去底(去除白色背景)
    .net图片自动裁剪白边函数案例
    .net图片裁剪抠图之性能优化
    .net图片压缩
    .net微软消息队列(msmq)简单案例
    SVM手撕公式
    算法效率分析
    模型稳定性
  • 原文地址:https://www.cnblogs.com/itkk/p/8855694.html
Copyright © 2011-2022 走看看