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;
}
}
结束
这样一来,在不增加任何环境资源的前提下,可以实现不同版本服务的服务同时发布.满足了并行集成测试的需求
当然,还是那句话,解决同样问题的方法有多种,我上述的方法也不一定是最好的,如果有更好经验的同学,欢迎大家踊跃讨论.
关于本文内容 , 欢迎大家的意见跟建议
代码仓库 (博客配套代码)
想获得最快更新,请关注公众号

spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求的更多相关文章
- spring boot / cloud (二) 规范响应格式以及统一异常处理
spring boot / cloud (二) 规范响应格式以及统一异常处理 前言 为什么规范响应格式? 我认为,采用预先约定好的数据格式,将返回数据(无论是正常的还是异常的)规范起来,有助于提高团队 ...
- spring boot / cloud (十二) 异常统一处理进阶
spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...
- spring boot / cloud (十六) 分布式ID生成服务
spring boot / cloud (十六) 分布式ID生成服务 在几乎所有的分布式系统或者采用了分库/分表设计的系统中,几乎都会需要生成数据的唯一标识ID的需求, 常规做法,是使用数据库中的自动 ...
- spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法
spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法 前言 本篇接着<spring boot / cloud ...
- spring boot实战(第十二篇)整合RabbitMQ
前言 最近几篇文章将围绕消息中间件RabbitMQ展开,对于RabbitMQ基本概念这里不阐述,主要讲解RabbitMQ的基本用法.Java客户端API介绍.spring Boot与RabbitMQ整 ...
- spring boot / cloud (十五) 分布式调度中心进阶
spring boot / cloud (十五) 分布式调度中心进阶 在<spring boot / cloud (十) 使用quartz搭建调度中心>这篇文章中介绍了如何在spring ...
- spring boot / cloud (十八) 使用docker快速搭建本地环境
spring boot / cloud (十八) 使用docker快速搭建本地环境 在平时的开发中工作中,环境的搭建其实一直都是一个很麻烦的事情 特别是现在,系统越来越复杂,所需要连接的一些中间件也越 ...
- spring boot / cloud (八) 使用RestTemplate来构建远程调用服务
spring boot / cloud (八) 使用RestTemplate来构建远程调用服务 前言 上周因家里突发急事,请假一周,故博客没有正常更新 RestTemplate介绍: RestTemp ...
- spring boot / cloud (十九) 并发消费消息,如何保证入库的数据是最新的?
spring boot / cloud (十九) 并发消费消息,如何保证入库的数据是最新的? 消息中间件在解决异步处理,模块间解耦和,和高流量场景的削峰,等情况下有着很广泛的应用 . 本文将跟大家一起 ...
随机推荐
- 移动web开发之rem的使用
为什么要使用rem 移动端设备尺寸五花八门,单纯使用px这个单位无法轻易适配,rem就可以为我们解决这个问题! 如何使用rem 1rem默认等于16px,这是因为页面的默认字体大小就是16px.r 代 ...
- Algorithm --> 投资组和求最大利润
投资组和求最大利润 题目: 投资人出资一笔费用mount,投资给不同的公司(A,B,C....),求最大获取利润? 例如:投资400百万,给出两家公司A和B: 1.如果投资一百万给A公司,投资3百万给 ...
- 本地不安装oracle,PLsql远程连接
Oracle的Instant client工具包可以很好地解决本地不安装oracle,PLsql远程连接. 1.首先到Oracle网站下载Instant Client : http://www.ora ...
- opencv配置
1.安装opecv库 从官网http://opencv.org/下载OpenCV windows版 运行之后 2.配置环境变量 64位系统,可以将32位和64位两个都添加上,免得以后编译不同程序再来配 ...
- Android中文API (109) —— SimpleCursorTreeAdapter
前言 本章内容是android.widget.SimpleCursorTreeAdapter,版本为Android 3.0 r1,翻译来自"深夜未眠",含示例代码,欢迎访问它的博客 ...
- python 函数基础 定义
一.函数介绍 1.为什么要有函数? 没有函数的代码组织结构不清晰,可读性差. 代码冗余 管理维护难度大,扩展性 2.什么是函数? 具备某一个功能的工具就是程序中的函数. 事先准备工具的过程就是:函数的 ...
- java编程思想笔记(1)
java编程思想笔记(1) 一,对象的创建和生命周期 对象的数据位于何处?怎样控制对象的生命周期? 在堆(heap)的内存池中动态地创建对象. java完全采用了动态内存分配方式. 二,垃圾回收器 自 ...
- Beta预备
团队名称:稳住!我们能赢 Beta预备: 讨论组长是否重选的议题和结论 项目组长可以说是一个团队的灵魂和核心.一个好的领导者可以激发团队成员的工作热情,提高开发效率,保质保量的完成工作.虽然在Alph ...
- C语言的第0次作业
你认为大学的学习生活.同学关系.师生关系应该是怎样? 1.我觉得大学生活应该充实而富有意义,不荒废学业,合理分配时间,让自己有一技之长,与时代接轨. 2.同学之间应该顺其自然的相处,不做作,不矫情,真 ...
- MySQL的小Tips
交集和差集 MySQL中没有这两个运算,但是有并集运算,所以可以利用这个来间接实现. 差集: SELECT ID FROM ( SELECT DISTINCT A.AID AS ID FROM TAB ...