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

结束

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

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

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

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


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

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

  1. spring boot / cloud (二) 规范响应格式以及统一异常处理

    spring boot / cloud (二) 规范响应格式以及统一异常处理 前言 为什么规范响应格式? 我认为,采用预先约定好的数据格式,将返回数据(无论是正常的还是异常的)规范起来,有助于提高团队 ...

  2. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

  3. spring boot / cloud (十六) 分布式ID生成服务

    spring boot / cloud (十六) 分布式ID生成服务 在几乎所有的分布式系统或者采用了分库/分表设计的系统中,几乎都会需要生成数据的唯一标识ID的需求, 常规做法,是使用数据库中的自动 ...

  4. spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法

    spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法 前言 本篇接着<spring boot / cloud ...

  5. spring boot实战(第十二篇)整合RabbitMQ

    前言 最近几篇文章将围绕消息中间件RabbitMQ展开,对于RabbitMQ基本概念这里不阐述,主要讲解RabbitMQ的基本用法.Java客户端API介绍.spring Boot与RabbitMQ整 ...

  6. spring boot / cloud (十五) 分布式调度中心进阶

    spring boot / cloud (十五) 分布式调度中心进阶 在<spring boot / cloud (十) 使用quartz搭建调度中心>这篇文章中介绍了如何在spring ...

  7. spring boot / cloud (十八) 使用docker快速搭建本地环境

    spring boot / cloud (十八) 使用docker快速搭建本地环境 在平时的开发中工作中,环境的搭建其实一直都是一个很麻烦的事情 特别是现在,系统越来越复杂,所需要连接的一些中间件也越 ...

  8. spring boot / cloud (八) 使用RestTemplate来构建远程调用服务

    spring boot / cloud (八) 使用RestTemplate来构建远程调用服务 前言 上周因家里突发急事,请假一周,故博客没有正常更新 RestTemplate介绍: RestTemp ...

  9. spring boot / cloud (十九) 并发消费消息,如何保证入库的数据是最新的?

    spring boot / cloud (十九) 并发消费消息,如何保证入库的数据是最新的? 消息中间件在解决异步处理,模块间解耦和,和高流量场景的削峰,等情况下有着很广泛的应用 . 本文将跟大家一起 ...

随机推荐

  1. zabbix自定义key监控memcache状态及其他服务进程

    一.在客户端 1.到/usr/loca/zabbix/conf/zabbix_agentd.conf里添加         UserParameter=memcached_stats[*],(echo ...

  2. Nginx阻止对不明确主机名的请求

    在用户请求头中,有可能会有Host行不明确的情况,如果不想处理这类用户请求,那么可以定义一个默认的server来丢弃这类请求.例如 server{ listen default_server; ser ...

  3. Android权限Uri.parse的几种用法(转载)

    1,调web浏览器 Uri myBlogUri = Uri.parse("http://xxxxx.com"); returnIt = new Intent(Intent.ACTI ...

  4. 多线程 Synchronized关键字和Lock

    Synchronized  分为实例锁和全局锁. 实例锁为 synchronized(this) 和 非static synchronized方法.   也加对象锁. 只要一个线程访问这类的一个syn ...

  5. 关于Linux中文件,链接的一些思考

    在Unix系统中,操作系统为磁盘上的文本与图像,鼠标键盘操作,网络交互等IO操作设计了一组通用API. 使他们被处理的时候可统一用字节流的方式.所以说,除了进程之外,其他的一切均可看做文件. Linu ...

  6. HTTP协议----URI,URL,持久连接,管道与Cookie

    URI与URL有什么不同呢? URI:Universal Resource Identifier统一资源标志符 URL:Universal Resource Locator统一资源定位器 URI是用来 ...

  7. DirectSound---捕获音频、Qml/C++ 集成交互

    DirectSound的音频捕获原理和播放原理差不多,内部在一个缓冲区上循环写入捕获到的数据,并且提供notify通知功能. 1. 音频捕获 因为捕获流程和播放流程类似,我们就不在这里赘述了,只给出简 ...

  8. 集合源码(一)之hashMap、ArrayList

    HashMap 一.HashMap基本概念: HashMap是基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒 ...

  9. Storm概念讲解和工作原理介绍

    Strom的结构 Storm与传统关系型数据库     传统关系型数据库是先存后计算,而storm则是先算后存,甚至不存     传统关系型数据库很难部署实时计算,只能部署定时任务统计分析窗口数据   ...

  10. 顺企网 爬取16W数据保存到Mongodb

    import requests from bs4 import BeautifulSoup import pymongo from multiprocessing.dummy import Pool ...