手记

“某宝”支付服务架构演进之路,解决实际问题!

今天就说说支付服务的那些事吧。以此来对过去几年的创业经历做个小结。


系统演进


新的业务系统初建时,业务逻辑相对简单,业务量也比较小,为了能够快速实现功能,发布上线,多数团队都会把所有的逻辑都耦合在一个系统。这对于初期业务的快速迭代是有一定好处的。毫不例外,前公司的支付交易系统也采用了这样的方式。


单体架构简便快速,然而这种架构的缺点也很明显,姑且不说高并发访问,逻辑分散,随着需求的迭代,后期难以维护。初接项目,问题很多,每天就是排查问题,和第三方确认交易等。好在深陷泥泞不久,就开始着手新支付服务设计实现。那么,支付要解决的问题有哪些呢?


解决的问题


做支付服务也有两年多了,总结下支付服务要解决的有哪些问题。


  • 最原始和核心的需求,资金流动

  • 高可用。全天候提供服务。需要解决如下问题:


  • 多机。热发布。

  • 通信异常或超时。异常的交易如何保证交易最终一致性。

  • 防雪崩。渠道偶也会有抽风时,他们抽风了,我们可不能跟着抽风。快速熔断,防止大量资源(连接)被暂用。

  • 通知下游服务失败或异常时,重试通知。


  • 易用性。满足各种业务需求,各业务系统调用只需提供少量必要信息即可,接口简单、调用方便。

  • 简单风控。对交易做校验,识别并阻止误交易或恶意交易。

  • 防止重复交易。不用的业务场景,对重复扣款要求不一。对于同一用户下同一业务的扣款,交易发起方可能会有多个,如:用户自动发起、工作人员介入发起、系统定时扣款发起,即会下多个支付订单,然由于业务要求多个支付订单只能有一笔支付成功。如何保证不会多扣用户的钱,即需要防止对同一业务下的支付订单重复扣款。而有些业务(如充值)又没有此限制。

  • 支付路由。为保证服务的稳定可靠,一般会接入多个支付渠道互备。多个支付渠道,如何个性化选择?一般考虑路由的的因素有如下:


  • 不同业务对支付渠道有特殊要求。

  • 同一业务不同时期对支付渠道有特殊要求。

  • 支付渠道有个人问题(卡挂失、卡过期、交易金额超个人设置限额、未知异常等)和渠道问题(渠道下某个银行未开通或交易金额超渠道设置限额、渠道跪了、渠道对个人余额不足做次数限制等)导致不可用。

  • 不同渠道费率可能不尽相同,省钱省钱省钱。

  • 一般会将费率高的渠道作为备用,然而作为合作备胎也是有尊严的,你也是要时不时撩一下,给下希望,所以每天也得保证一定的交易量。


  • 需求迭代。由于业务的特殊性,需求一直在迭代,经常需要接入新渠道。如何满足快速的需求迭代?如何让新人快速高效投产?系统架构要合理,高内聚低耦合。自动化测试释放重复性的一些测试工作。

  • 监控与预警。要保证系统的高可靠和高可用,监控必不可少。业务上,监控异常的交易。监控银行和渠道的可用性。手续费预警,避免坐扣发生。系统运行情况监控等。

  • 资源分配。按交易来源的不同,交易可以分为两类:一类是用户发起,一类是系统定时批量交易。用户发起的交易一定得先得到保证,然后又要兼顾系统定时批量交易。



  • 异常交易快速发现及处理。系统难免有异常交易的情况发生。如交易超时、回超时、渠道或银行系统抽风、掉单等。如何快速发现异常交易并快速修复异常。

  • 动态配置。渠道或银行系统难免会有维护的时候,尤其银行节假日经常会有升级维护。维护期间或者他们的服务是不可用的,或者限制交易限额等等。智能路由也有如权重优先级等一些配置,等等此类的配置都是需要动态维护的。

  • 全局异常处理。各业务调用方式不一,有RESTFUL接口DUBBO接口等。如何保证异常处理的一致性。

  • 支付结果个性化通知。由于支持了不同的业务,而不同业务的后续处理方式是不同的,需要个性化通知下游系统。

  • Fail fast。分布式系统,要对每个模块系统的可用性持怀疑态度,当出现某个系统不可用时(如发包),要能快速优雅地结束整个流程。这点设计出问题时可能会帮你避免影响的进一步扩大。举个例子,服务出现过仅有的两次事故,一次是路由服务机子磁满了,一次是网络问题,导致异常交易发生,“Fail fast”避免了雪崩效应,同时保证了交易的一致性,避免人工修数据情况的发生,为服务的快速恢复提供了可能(从问题发现到服务恢复,均在十分钟左右)。

  • 埋点。涉及钱的,应该是一件很严肃的事。任何系统都会存在BUG,所以交易需要进行必要的埋点用于追踪问题交易。

  • 限制资源的使用。对于资源使用的限制设计是高可用系统最重要的一点,也是容易被忽略的一点,资源相对有限,用的过多了,自然会导致应用宕机。一般有如下限制:

  • 限制连接数

  • 限制线程创建

  • 限制并发

  • 限制内存的使用

  • 状态码的学习。第三方支付渠道返回的状态码偶尔会变更(推测是第三方会切换渠道或者接入新的渠道),而新增的新状态码第三方往往通知不及时甚至不通知,新状态码在未能判定成功或失败的情况下,是个未知状态(宁可未知也不能误判。这一点很重要,很多第三方在处理和银行或其他第三方时,出现通讯超时或者未知状态码后就返回失败,这导致了很多掉单情况的发生,踩了很多这样的坑…),如何快速发现并学习新状态码的含义?总之,需求很明确,就是适应互联网应用的场景,也没啥特别之处。后面有时间再理一下系统的演进实现吧

作者:高级架构师

来源:https://my.oschina.net/u/3772106/blog/1611400

0人推荐
随时随地看视频
慕课网APP