<< 返回文章列表

基于支付场景下的微服务改造与性能优化(一)

2019年6月17日
程超等
1347


导读:本文节选自《高可用可伸缩微服务架构:基于Dubbo、Spring Cloud和Service Mesh》一书,程超 等著,由电子工业出版社博文视点出版,已获得授权。近年来微服务架构已经成为大规模分布式架构的主流技术,越来越多的公司已经或开始转型为微服务架构。本书不以某一种微服务框架的使用为主题,而是对整个微服务生态进行系统性的讲解,并结合工作中的大量实战案例为读者呈现一本读完即可实际上手应用的工具书。


一、支付场景的介绍



本章主要介绍基于支付场景下的微服务实践,微服务体现的真谛最终还是要理解业务,只有深入理解了业务才能结合领域来重新定义微服务,下面就简单介绍一下互联网支付。

常见的互联网支付的使用场景主要有以下几种。

刷卡支付:用户展示微信钱包内的“刷卡条码/二维码”给商户系统,扫描后直接完成支付,适用于线下面对面收银的场景,如超市、便利店等(被扫,线下)。
扫码支付:商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”来完成支付,适用于PC网站支付、实体店单品等场景(主扫,线上)。
公众号支付:用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调用微信支付模块来完成支付,适用于在公众号、朋友圈、聊天窗口等微信内完成支付的场景。
WAP支付:基于公众号基础开发的一种非微信内浏览器支付方式(需要单独申请支付权限),可以满足在微信外的手机H5页面进行微信支付的需求!简单来说,就是通过PC、手机网页来实现下单支付(俗称H5支付)。
App支付:商户通过在移动端应用App中集成开放SDK调用微信支付模块来完成支付。
网关支付:用户需要开通网上银行后在线完成支付,主要对象是国内银行借记卡和信用卡,是银行系统为企业或个人提供的安全、快捷、稳定的支付服务。
快捷支付:快捷支付指用户购买商品时,不需开通网银,只需提供银行卡卡号、户名、手机号码等信息,银行验证手机号码正确性后,第三方支付发送手机动态口令到用户手机号上,用户输入正确的手机动态口令即可完成支付。

在支付场景下实现微服务的最终目标:能够将单体支付系统按业务进行解耦,利用微服务生态来实施支付系统,并且能够保证系统的可靠性和并发能力,建设完整的运维体系以支撑日益庞大的微服务系统。


二、支付业务建模和服务划分



我们在第2章介绍了领域建模的相关知识,由此可以知道几个关键词:领域、子域、限界上下文。有些读者对领域、子域的概念比较容易理解,但是限界上下文就理解得比较模糊,这里再对这个关键词简单做一下介绍。


可以把限界上下文理解为:一个系统、一个应用、一个服务或一个组件,而它又存在于领域之中。举个生活中的例子:我每天上班都会坐地铁,从家里出发到单位需要换乘三次地铁,分别是5号线、8号线和2号线。那么地铁就可以理解为限界上下文,从5号线走到8号线这个过程就是领域事件,而为了到达目的地中间换乘地铁,这个过程叫作上下文切换。


再回到支付业务中,该如何根据业务和领域相关知识来划分服务呢?我们以一个业务架构示例来讲解,如图11-1所示。


当我们在工作中遇到一个完整的业务场景时,首先需要识别出一共有哪些领域,根据大的领域再来划分子域,最后将具有相同领域或子域的限界上下文进行归类。正确识别出领域其实是比较难的,需要设计人员前期对业务有大量的调研,有比较深入的了解后才能识别领域。


从图11-1中可以看到整个业务架构图分两大部分,中间的是业务核心领域,两边的是支撑子域。


我们重点介绍中间的部分,每一层就是一个领域,领域中又包括特定子域。

(1)对接业务层:主要是一些业务系统对接支付系统,包括电商业务、互金业务和一键支付三个限界上下文。


(2)统一接入网关层:主要功能是对请求入口进行加解密、分流、限流和准入控制等。


微信图片_20190617112132.jpg


图11-1

(3)产品服务层。


     收银台:包括两个限界上下文,分别是PC收银台和手机手银台。

     商户:包括四个限界上下文,分别是分账、鉴权、担保和代扣。
     个人:包括两个限界上下文,分别是充值和提现。


(4)业务服务层:包括五个限界上下文,分别是交易服务、支付服务、退款服务、计费服务和风控服务。


(5)基础服务层。


     网关:包括三个限界上下文,分别是支付网关、鉴权和支付路由。
     资金处理平台:包括四个限界上下文—对账、清结算、备付金和会计。



三、支付场景下微服务架构的详解与分析



使用微服务的核心是业务,没有业务进行支撑的微服务是“虚的”,但只有业务与微服务相结合的思想而没有微服务的架构体系也是无法将微服务落地的,所以本章重点介绍要做好微服务还需要完善哪些技术架构。


下面我们将以一个实际工作中的案例为出发点,分析在中小公司中如何落地微服务。如图11-2所示,左半部分是微服务的业务架构,右半部分是微服务的基础技术架构。


微信图片_20190617112138.jpg


图11-2

3.1 业务架构分析


根据前面介绍的如何根据业务来划分领域可以看到,整个业务架构部分已经完成了领域的划分,我们重点来看服务层。服务层是一个核心域里面包含了多个子域,每个子域都是按功能进行划分的,比如支付中心子域里面包括支付服务、路由系统和银行渠道等限界上下文,这些限界上下文是一个服务,还是一个系统呢?这就要结合康威定律来综合考量团队的规模,小公司创业初期研发人员少,可以将支付中心子域定义为限界上下文,里面包括三个独立模块,分别是支付服务模块、路由模块和银行渠道模块,待人员逐步增加到一定规模后,多个项目组同时修改一个支付中心限界上下文会导致互相影响的时候,就需要将支付中心上升为一个业务领域,而将之前的三个独立模块拆分为独立系统,由不同的项目组分别接管,各自维护各自部署,如图11-3所示。


微信图片_20190617112141.jpg


图11-3


可以看出左边是未拆分前的结构,交易服务想要调用支付模块就必须统一调用支付系统,然后才能调用支付模块,而右边是经过拆分后的结构,这时交易服务可以直接调用支付服务系统、路由系统和银行渠道系统中的任意一个,当然从业务流来讲肯定要先调用支付服务系统。


而数据层是根据业务进行数据库的拆分,拆分原则与应用拆分相同,如图11-4所示。


微信图片_20190617112144.jpg


图11-4

可以看到业务、应用和数据库三者一体,物理上与其他业务隔离,不同应用服务的数据库是不能直接访问的,只能通过服务调用进行访问。


3.2 技术平台详解


当我们将整个支付业务根据微服务理念做了合理划分之后,业务架构的各层次就逐步清晰起来,而微服务架构的成功建设除了业务上面的划分,技术平台和运维体系的支撑也是非常重要的,图11-2的右半部分共分为三个层次,分别是统一平台业务层、微服务基础中间件层和自动化运维层。


1) 统一业务平台层
这一层主要是通用的平台业务系统,包括数据分析服务、商户运营服务、运维管控服务和进件报备服务,它们无法根据业务被归类到某一业务系统中,只能作为支撑域存在,所以放到统一业务平台层供所有业务线共同使用。


2)微服务基础中间件层

微服务本身是一个生态,为了支撑微服务这个庞大的体系,必须有很多基础中间件进行辅助才能使微服务平稳地运行。下面将根据笔者积累的实践经验对图中一些重要的组件进行技术选型方面的介绍,另外图中有很多组件在本书其他章节进行了详细介绍,这里就不再做说明。


微服务框架


目前市面上非常流行Spring Boot+Spring Cloud的微服务框架,这套框架确实是微服务的集大成者,涵盖的范围广,可以支持动态扩展和多种插件。但是作为公司的管理者来说,并不能因为出了新的技术就立刻将公司核心业务用新的技术进行更替,这样在生产上所带来的风险将会非常大。比较合理的做法是,如果公司或部门是新成立的,还没有做技术框架的选型,又想在公司内部推广微服务的时候,尝试使用Spring Boot和Spring Cloud框架,可以节省出公司或部门的很多时间来攻关前端业务,而不需要将更多精力放在如何进行微服务的建设上来。


目前很多互联网公司在生产过程中使用的微服务框架并不是Spring Boot和Spring Cloud,会使用如Dubbo、gRPC、Thrift等RPC框架进行服务治理,而公司内部自己研发出很多微服务的外围组件,比如APM监控系统、分库分表组件、统一配置中心、统一定时任务等。在这种情况下公司内部已经自建了比较完善的基础架构平台就没必要整体更换为Spring Boot和Spring Cloud,否则代价极大,甚至会对公司的业务造成严重的后果。公司发展的策略一般都是以客户(用户)稳定优先,但公司技术也需要更新,可以先尝试在公司边缘业务中使用,达到认可后逐步推广,循环渐进。


笔者在进行微服务改造的过程中实际上是基于原有的Dubbo做的改进,将Duboo和Spring Boot相结合形成服务治理框架。


消息服务


我们在谈技术选型的时候,不能脱离业务空谈选型,每种消息中间件必定有其优点和不足,我们可以根据自身的场景择优选择,下面笔者结合自己使用的两种类型的MQ简单说一下选型与使用场景。


RabbitMQ是使用Erlang编写的一个开源的消息队列,本身支持很多协议:AMQP、XMPP、SMTP、STOMP,也正是如此,使它变得非常重量级,更适合企业级的开发。RabbitMQ是AMQP协议领先的一个实现,它实现了代理(Broker)架构,意味着消息在发送到客户端之前可以在中央节点上排队。对路由(Routing)、负载均衡(Load balance)或数据持久化都有很好的支持。但是在集群中使用的时候,分区配置不当偶尔会有脑裂现象出现,总的来说,在支付行业用RabbitMQ还是非常多的。


Kafka是LinkedIn于2010年12月开发并开源的一个分布式MQ系统,现在是Apache的一个孵化项目,是一个高性能跨语言分布式Publish/Subscribe消息队列系统,其性能和效率在行业中是领先的,但是原先的版本经过大量测试,因为其主备Partition同步信息的机制问题,偶尔会造成数据丢失等问题,所以更多的应用场景还是在大数据、监控等领域。


目前市面上有很多支付公司都在使用RabbitMQ作为消息中间件,虽然很“重”但是却具有支付行业的不丢消息、MQ相对稳定等特点。缺点则是不像ActiveMQ那样可以使用Java实现定制化,比如想知道消息队列中有多少剩余消息没有消费,哪些通道获取过消息,共有多少条,是否可以手动或自动触发重试等,还有监控和统计信息,目前做得还不是太完善,只能满足基本功能的要求。


接下来我们再来说说消息队列在技术领域的使用场景。


(1)可以做延迟设计。
比如一些数据需要过五分钟后再使用,这时就需要使用延迟队列设计,比如在RabbitMQ中利用死信队列实现。


(2)异步处理。

主要应用在多任务执行的场景。


(3)应用解耦。

在大型微服务架构中,有一些无状态的服务经常考虑使用MQ做消息通知和转换。


(4)分布式事务最终一致性。

可以使用基于消息中间件的队列做分布式事务的消息补偿,实现最终一致性。


(5)流量削峰。

一般在秒杀或团抢活动中使用广泛,可以通过队列控制秒杀的人数和商品,还可以缓解短时间压垮应用系统的问题。


(6)日志处理。

我们在做监控或日志采集的时候经常用队列来做消息的传输和暂存。



统一配置中心


目前市面有很多种开源的统一配置中心组件可供使用,如携程开源的Apollo、阿里的Diamond、百度的Disconf,每种组件都各有特点,我们在使用的过程中还需要根据实际情况来综合考量。笔者公司目前采用的微服务架构是Spring Boot+Dubbo的方式,Apollo的架构使用了Spring Boot+SpringCloud的方式,在架构方式上正好可以无缝对接,同时Apollo可以解决同城双活方面的问题,所以从这些角度来看比较适合目前的场景。


银行通道监控与切换


由于每家银行提供的业务及产品不同,例如B2C、B2B、大额支付、银企直连、代收代付、快捷支付等,这些产品及服务并无统一的接口,要使用这些产品服务,支付机构只能一家家银行进行接入,当对接的银行通道过多时,每条通道的稳定性就是支付工作中的重中之重,这是涉及用户支付是否成功的关键,也是支付机构支付成功率的重要指标,基于此,要有针对性地进行银行通道稳定性的监控与故障切换系统的建设,如图11-5所示。



微信图片_20190617112146.jpg

图11-5

图11-5是通道监控与切换系统的整体架构,通过在相应组件或应用上面增加Agent监控代理拦截通道的请求情况,经过Collector进行数据汇总,然后将通道评分数据发送给Redis集群,而支付路由系统在进行通道选取的时候会从Redis集群中获取通道的评分及通道相应的配置项进行综合评定从而选取合适的通道,另外采集所有的监控数据都会存放到InfluxDB中,通过Grafana进行预警展示,如果通道不可用则自动将通道关闭,同时通知研发部门进行问题排查。