优化 支付接口 到1S内我做了这些!

834 阅读5分钟

项目背景

公司是某支付公司的服务商,但是去年支付公司突然告诉我们根据人民银行的要求以后的所有结算的资金只能结算到公户不能入私户,这就吓跑了一堆 在我们旗下的商户,所以公司决定跟更多可以入私的支付公司合作且封装一套通义的支付接口(得累死我是吧)。

dtb-1716564339306.jpg

问题出现

在平平安安的对代码疯狂编码的时候,突然微信群冒出来一条消息,市场人员告诉我封装的接口太慢了至少要3-5秒左右,等到客户都不想支付了!

side_pic_gif1.gif 我尼玛这么久怎么可能!所以我内心慌得一笔,赶紧打开了API测试软件测试了一下

不看不知道一看吓一跳,直接六秒飞起!好吧,PHPStrome启动!

image.png

定位问题

所以看了看代码,发现当初因为要求快点上线所以就库库写根本没想着优化和测试,导致现在特别慢,所以首先明确排查拖慢代码是在哪一个阶段出现的

  1. 看看 渠道方接口是否太慢了(这个不会)
  2. 看看 是否有太多数据库的操作
  3. 有没有 比较耗时的操作 (这个倒是没有因为它本质上就是查查和请求)

渠道方的问题?

首先 我先想到了 会不会是 渠道方响应太慢了所以就拖累到了接口,可测 了一下也才 2-4毫秒左右也不会影响到接口

image.png

难道接口太多数据库的操作了?

看了看请求链路快照,在请求渠道之前至少花了2-3秒的时间去处理一些是,但是在这之前都是一些数据库查询和校验的工作

image.png

所以仔细数了数 在实际调用 支付代码的前后 总共有 6个数据库的查询和更新的工作!发现还挺多,所以就针对这些数据库的操作进行了优化。

首先入口处每次请求都会在数据库查一遍 商户的公钥和私钥对请求来的数据进行验证和签名还有商户的相应渠道的配置信息,这样就已经产生了2条数据库的操作,如果当前处于非常高的流量下那将对数据库造成很大的压力。

image.png

image.png 因为这些信息是几乎不怎么变动的热点数据,所以在这里采用了redis进行了缓存和查询这样就稍微下降了一些。 但是请求还是保持在3-4秒左右,

image.png

但是响应时长还是比较长的还是得排查排查到了代码的渠道实现基类发现好吧还有一些数据库的插入操作例如,订单创建的操作 和 订单链路日志的写入数据库操作 还有 请求日志操作

1.订单创建插入操作

本身设计上是想着 先在数据库中创建一个订单它的状态是在 生成中的,如果有插入错误的情况就更改这个订单的状态到支付失败,所以在这个上面会多出2个操作情况,所以将这里优化到了一个 只有当 渠道方响应时才会创建这一个 状态为支付中的订单出现报错的情况就直接抛出一个订单创建失败的异常,反正 生成中的状态永远只会出现在数据库中,也就没有意义了(当然后面有用再说把现在还不需要)

2.订单链路日志的写入数据库操作 还有 请求日志操作

其实这两个写入的操作并不重要,尤其是 请求日志写入,我也不知道当时哪根筋抽了本身系统是由请求日志的然后我又在这里写了一遍相当于脱裤子放屁了嗷所以这个操作删除掉了,

这个订单链路日志还是虽然不重要但是只是相对于这个接口来说的,当有商户 请求有异常时这个日志功能就可以排上用场了,所以这里采取了异步处理的方式 但是PHP它又没有线程这类玩意,只好用上了MQ去异步去处理插入数据

总结

  1. 将热点数据保存至 redis 减少数据库的频繁查询
  2. 日志类的数据采集可进行异步处理 例如 队列 和 异步线程
  3. 不得不进行查数据库的数据可以在数据库上加索引去查(这里没讲,因为订单库没有加索引也导致了查询订单重复时过慢)
  4. 渠道响应过久也是原因之一 (当然这个几率很小)

image.png 优化完毕后又重新测试了一遍这次就从最初的4-6S优化到了1S之内,其实里面需要优化的点还挺多不仅仅从代码层面从设计层面也是有许多高度耦合的代码让我在这个优化中十分难受。