互联网:为什么必须在夜里发布新系统?

335 阅读5分钟

为什么大多数公司喜欢在夜里发布新系统?

呆过几家公司,发现每家公司都喜欢在晚上十点或更晚些才发布新系统。在发布系统的过程中,曾遇到过许许多多的问题,譬如数据库表结构不一致、某个服务连不上、核心数据误操作、缺少配置选项等等,导致许多开发人员与测试人员被迫加班到很晚甚至通宵达旦的修改所谓的BUG(其实这些都不应该算作是BUG,毕竟只有测试环境通过后才会发布生产的)。这些BUG详细研究统计后发现,大多是测试环境和生产环境的配置不一致导致的,但找BUG的过程是相当的艰难,很少会有开发人员在写代码时有认真对待过他所处的编程环境的。造成的后果就是,所有人都失去了本来应有的生活,而且情绪会很低落,从而会产生人员流失和失去工作热情,效率进一步的降低。

为什么大家都喜欢在夜里发布新系统呢?

有人美其名曰,为了不影响客户体验。真的不影响吗?众所周知,现在的夜猫子是越来越多了啊。白天一整天的工作筋疲力尽,本就打算夜里能嗨翻天的,结果打开APP发现提示:系统正在更新!人生真艰难~

如果白天发布新系统会怎样?

最明显的一个好处就是:你好我好大家好!

经过一夜的休息,开发和测试都头脑清晰思维敏捷,发现了BUG能短时间内迅速解决,大大缩短发布系统的时长,而且能快速解决新BUG指定新方案家庭和睦身体健康不会猝死balabala(自行脑补吧)

换个思路

一般情况下,真正的生产服务器都会做负载均衡,同时在线运行的相同机器不止一台,有的会达到数百上千台,譬如支付宝微信等等。那么想一下,如果能随机将其中的一台机器提取出来,做为pre服务器,专门作为发布代码用,是不是更好呢?

  1. 这台机器是随机选则的,而不是每次都固定某一个
  2. 由于是从生产集群中选的,所以环境跟其他生产服务器的环境是一致的
  3. 只要这一台能通过测试,其他的也能通过测试

具体实施(Spring全家桶为例)

1. 添加pre环境配置profile

修改context-path,区别真实生产地址,可以加个特有的前缀,例如:/api -> /pre/api

2. 负载服务修改

以最常见的Nginx作为例子,通过修改负载地址,将测试用的流量转发到指定的机器(假定名字为SA)上。

例如,正常的生产转发的接口地址为/api,那么我们可以将测试的流量转发到/pre/api上,并将SA从原来的location列表中转移到新的location中。

3. APP等前端修改

专门发布一个仅供内部测试用的版本(修改接口请求地址即可,即加个前缀)。由于前端对于服务器环境的要求不高甚至可以说是没啥要求,这个测试版可以发布到公司内部的服务器上,H5可以直接发版,APP本地打包安装即可,提供到测试部门。

以上,既可以白天发布新版本,又不会影响用户体验

BUT

但是,这里尚有一个问题需要解决:测试所用的数据该如何处理?

由于使用的是生产数据库,所以我曾遇到过测试人员不敢随便提交数据的情况,譬如下单支付等等操作,万一那个功能有BUG,产生的垃圾数据清理起来还是很麻烦的。所以,一个大胆的想法出来了:

为每个数据添加一个类型,标识此数据是属于测试还是生产。

这个想法不晓得是否够好或足够垃圾,但是为了整个流程的通畅可用,我觉着这么做还是值得的。

操作起来很简单,对于java而言,只需要在公共实体类中添加一个映射字段就行:

  1. insert时,在PrePersist中将此字段初始化成profile中定义的值
  2. select时,在公共查询接口中将此字段作为必须条件加入到where条件中
  3. 对于支付相关的逻辑,从profile中取一个开关值(true或false),区别是否为测试数据,如果为测试,则将支付金额设置为0(我曾遇到过,一个项目经理为了测试某个支付功能,误支付了4万多人民币,最后通过协调才返还的)

可能会有人认为加个字段会导致数据臃肿啦,性能降低啦balabala,我觉着这么个极度收敛的字段(可能的值大概只有1个字节1和0)对系统的整体影响可以忽略不计,如果有影响,您的系统该做优化了。

还有一个方案:指定专门的测试账号

然而这么做会有一个弊端,譬如你正在组野队上分,忽然来了个叫做测试1号的乱入,心里不慌么?