背景

最近收到反馈,用户觉得小程序比较慢,统一分析后认为,我们系统在用户刷新的一些动作时,耗时比较长。

排查

  • 由于业务的需求,用户在打开微信小程序的时候会调用一次服务端的接口
  • 服务端在执行时会去调用高德地图/IPIP的接口,由于是外部服务的调用,所以耗时比较长(有些极端的会达到好几秒,但是普遍都是500ms+)
  • 由于业务的原因,这些外部调用必须调用

解决思路

一开始是针对部分接口有了缓存的(Redis),但对每一个小的业务场景都使用了一个对象来处理缓存的使用,目前已经积累了五个了,按照堆屎山的逻辑,我应该再去配置一堆缓存对象来处理这个问题,然后在各个调用接口的地方使用缓存对象,但,我认为这不是一个好的设计了,原有的设计不太实用了,并且会造成代码逻辑的混乱,不好维护,以后即便缓存出现了问题,也难以排查。所以怎么解决呢?

启发

无意中看到代码中有http trace的逻辑(可以对http调用过程中的状态进行感知),我想到,是不是可以使用类似的逻辑来实现对HTTP调用统一的缓存呢?我只需要配置一下域名,路由,HTTP Method,是不是就可以快速完成HTTP调用呢?

实现

  • 方案一:在HTTP Trace中制作缓存,但我发现HTTP Trace没有办法去拦截HTTP的Response数据,所以这条路行不通。
  • 方案二:对HTTP的调用进行封装,这样确实是可以统一的进行HTTP缓存的逻辑,但是我想了一下,工作量有点接受不了,太多了。
  • 方案三:我找到了一个aiohttp的client缓存三方库,它相当于对http的调用进行了封装,当然是当一个api gay来得快乐,但是,这个库对于缓存的过期机制的处理有点傻,没有使用Redis的过期机制,所以对其进行改动了一部分。

总结

  1. 当初在设计HTTP缓存的时候并没有考虑到这是一个通用的东西,也没有做得太通用,每一种业务调用都和缓存类进行强绑定,所谓“吃一堑,长一智”,下一次遇到类似的逻辑我一定不会写出强侵入式的逻辑。
  2. 在调研HTTP Trace的逻辑时,一开始是认为能走通的,但确实是没考虑到HTTP Trace没有办法拦截HTTP的Response数据的问题,导致自己做了一半了,不得不放弃,这也算是自己没有把事情的全流程考虑好,算是拿了半截就跑的典型错误,下一次还是要将全流程的思路写出来才算是调研成功。
  3. 目前看来,增加了缓存还是提升了很大的效率,算是告一段落。
  4. 现在看来,突然有点理解为什么以前遇到的项目会直接对Redis,Http的调用进行了包装,第一就是老生常谈的可能会换底层包的情况,另外一种可能就是我当前的情况。