快速迭代,持续交付是互联网和微服务开发的核心理念。 这需要大量完善的基础设施的支撑。 对支付系统开发来说,这些基础设施尤为重要。近年来随着互联网公司在金融领域上的发力,竞争越来越激烈,新产品推出速度也在加快,而对安全的要求却是越来越高,不断的有系统或者业务的安全问题爆发。如何在快速完成业务支持任务的同时,保证开发质量,是支付系统开发面临的难题。 微服务架构是解决这个问题的利器,不过也需要强大的基础设施的支持。 “没有金刚钻别揽瓷器活”, 基础设施不完善,会反而影响微服务的开发实施效率。 这里介绍微服务开发中需要准备的一些基础设施。
一、概览
微服务基础设施可以从软件过程支持、运行支撑环境和软件架构支持三个方面来建设。 所涉及到的系统以及主要相关软件如下:
二、软件过程支持
相对传统软件,微服务的开发在软件过程上,更强调敏捷。 每个开发任务控制在1-2周以内完成,一般不会超过一个月。 这就得在软件过程上实现高度的自动化。参考微服务开发的软件过程。在软件过程支持上,主要考虑如下软件。
2.1 任务管理
或者软件过程管理,这是整个系统的核心,通过这个软件可以将整个流程自动化运行起来。 一般用Jira来支持,也有公司用Redmine。
2.2 版本控制
版本控制所有自动化工作的基础。国内大部分公司已经完成了从subversion到git的改造,git也成为版本控制的标配了。支付系统在版本控制上和其他系统并无太多的差异。这里需要介绍的是针对微服务架构的版本控制。 我们知道对版本控制来说,代码合并是一个很难避免的噩梦。 而微服务化可以很好的解决这个问题,由于服务的粒度小,每次变更一个人就可以搞定。每个服务有都可以独立上线,避免修改冲突。 这样版本控制就相对来说比较简单:
2.3 代码审核
支付系统的每一行代码都要执行审核!代码审核对支付来说意义重大,是避免恶意代码不可缺少的一个环节。 一般来说,支付代码要求至少是2人审核通过。代码需要执行日常审核,而不是到快发布时的统一审核。审核的工具一般是需要和版本控制相集成的。 subversion上用reviewboard, git上用gerrit或者gitlab。虽然说gitlab是比较新的系统,不过还是推荐gerrit,可以强制代码审核以及控制代码审核流程,确保两个人都OK后才能入库。
对于使用gitlab的系统而言,它的优势在于可扩展性强。gitlab默认不支持强制代码评审。但如果不强制执行代码评审,那会出现开发人员未经code view就提交自己merge代码。而reviewer 未能够及时review代码,也会影响进度。此外,开发人员没有执行代码审计(sonar)就提交代码,也是常见的事情。 好在gitlab有非常好的可扩展性,通过webhook可以根据需要实现各种额外功能。 webhook是gitlab的一个扩展点,通过用户提供的回调HTTP请求来监听git的push、comments、merge等事件。比如可以要求必须至少两个LGFM(LooksGoodForMe)才可以merge。通过webhook来监听comments,汇总两个LGFM之后,自动将代码merge到trunk上。
2.4 代码审计
或者说是静态代码审查。Apache PMD, FindBugs都是常用的工具,推荐用Codehaus Sonar系统,即可以实现和Maven的集成,也可以有Web UI可以查看代码质量。提供的审核规则也比较全面,并且可以根据公司的需求来定制。
2.5 自动部署
毫无疑问,Jenkins就是CI的不二之选。 但是这也只是一个工具,怎么用还得结合业务来实现。而上面列出来的这么多工具和使用要求,如何确保开发人员安规范来实现,并且尽可能地自动化,一个解决方案就是用集成工具将这些活动串起来。这里不详细介绍Jenkins的原理或者它和hudson的恩恩怨怨,重点描述如何使用。 Jenkins使用的要点是设置各个Job。而Job的设置,又分为线上和测试的Job。测试环境的Job分为 部署、启动、停止三个群组。线上分为 预部署、部署、启动和停止四个群组。 在每个群组中,每个项目对应一个可执行Job。
三、运行环境
3.1 虚拟化
从物理机、虚拟机到docker,虚拟化程度越高,管理难度也越高,但所支撑的服务规模也相应的会增加。 并不是所有的微服务都需要使用docker,如果服务数量不多、高峰期和低估期的QPS差异不大,那普通的虚机就可以了。
3.2 系统监控
现在基本上 Zabbix 成为监控的标配了。 一个常规的 Zabbix 监控实现, 是在被监控的机器上部署Zabbix Agent,从日志中收集所需要的数据,分析出监控指标,发送到zabbix服务器上。 这种方式要求每个机器上部署 Zabbix 客户端,并配置数据收集脚本。Zabbix的部署可以作为必装软件随操作系统一起安装。
3.3 消息机制
异步消息是微服务必不可少的一个组件。 常用的如下消息机制:
- RabbitMQ: 这是一个面向企业应用的重型的消息机制。他实现了消息机制的broker架构,即消息在发送到客户端之前需要先放到中心队列中。 虽然RabbitMQ很容易部署和使用,但也显得笨重、性能差。
- ZeroMQ 是一个轻量级的消息系统,它的设计目标是为了实现高吞吐、低延迟,但使用并不方便,有大量的机制需要自己实现。
- ActiveMQ,这是一个介于RabbitMQ和ZeroMQ之间的消息机制,既有ZeroMQ的性能,也有RabbitMQ的稳定性和易用性。
- Kafka: 严格说,Kafka设计初衷是为了处理日志,后来被应用到高性能的消息处理上。 Kafka可以通过Hadoop或者Spark来消费,性能也远比ActiveMQ、ZeroMQ高。
日志搜集与分析
开发同学不碰线上系统,这是支付系统的原则。那线上系统出问题了怎么办?开发人员总是依赖日志来排查问题,一个日志汇总系统是支付平台必备的基础设施。考虑到日志最终都需要归并到一个日志仓库中,这个仓库可以有很多用途,特别是日常维护中的日志查询工作。多数指标可以在日志上完成计算的。 借助这个系统,也可以完成监控:
日志通过Apache Flume来收集,通过Apache Kafka来汇总,一般最后日志都归档到Elastic中。 统计分析工作也可以基于Elastic来做,但这个不推荐。 使用Apache Spark 的 Streaming组件来接入Apache Kafka 完成监控指标的提取和计算,将结果推送到Zabbix服务器上,就可以实现可扩展的监控。 Apache Flume和Logstash都可以用于日志收集,从实际使用来看,两者在性能上并无太大差异。Flume是java系统,Logstash是ruby系统。使用中都会涉及到对系统的扩展,这就看那个语言你能hold住了。 Apache Flume和Logstash都支持日志直接入库,即写入HDFS,Elastic等,有必要中间加一层Kafka吗?太有必要了,日志直接入库,以后分析就限制于这个库里面了。接入Kafka后,对于需要日志数据的应用,可以在Kafka上做准实时数据流分析,并将结果保存到需要的数据库中。
持续集成
毫无疑问,Jenkins就是CI的不二之选。 但是这也只是一个工具,怎么用还得结合业务来实现。而上面列出来的这么多工具和使用要求,如何确保开发人员安规范来实现,并且尽可能地自动化,一个解决方案就是用集成工具将这些活动串起来。这里不详细介绍Jenkins的原理或者它和hudson的恩恩怨怨,重点描述如何使用。 Jenkins使用的要点是设置各个Job。而Job的设置,又分为线上和测试的Job。测试环境的Job分为 部署、启动、停止三个群组。线上分为 预部署、部署、启动和停止四个群组。 在每个群组中,每个项目对应一个可执行Job。
在测试环境部署执行如下工作:
-
获取受控代码。如果有指定版本号,则下载该版本号对应的代码;否则获取最新的Tag分支并下载该代码。集成是必须从代码开始构建,目的是保证线上运行的系统和版本控制服务器上的代码是一致的,而不是从某人机器上修改后的代码直接传上去的。 如果出现问题,只要获取该版本的代码即可定位到出问题的地方;
-
执行代码审计
-
执行maven deploy命令,执行编译、单元测试、版本发布等工作。 注意,这个阶段发布的包,都是SNAPSHOT版本的包。
-
生成javadoc, 接口文档,发布到测试服务器上,测试人员将对这个文档做验证。
-
生成单元测试覆盖率报告、代码质量报告。
-
发布系统到测试环境上。
在线上环境部署执行如下工作:
-
如果有指定版本号,则下载该版本号对应的代码;否则获取最新的Tag分支并下载该代码;
-
执行mvn setVersion命令, 将所有SNAPSHOT版本依赖修改为正式版本依赖。
-
执行代码审计
-
执行maven deploy命令,执行编译、单元测试、版本发布等工作。 注意,这个阶段发布的包,都是RELEASE版本的包。
-
生成javadoc, 接口文档,这是正式版本的文档。
-
发布系统到线上环境上。
以上支付系统中涉及的主要的基础设施,本文仅完成初稿,后续将会逐步再完善其他的基础设置。 也欢迎大家补充完善。
修订记录
- 2016年11月12日 完成初稿