评论

微信小程序码获取-从频繁失败到成功率100%

记一次小程序码生成失败的随笔

早期实现方案

1. 方案实现

  • 通过微信的appSecret获取小程序accessToken并缓存
  • 微信小程序上很多操作都需要使用accessToken,比如用户授权手机号,当然也包括获取小程序码
  • 通过微信提供的api获取到对应的小程序码,由于http接口直接返回的是图片本身,所以考虑将图片上传七牛服务器并获取图片链接,最后使用图片的链接来展示或保存小程序码

2. 方案优点

  • 由于上传了小程序码,对于一些跳转固定页面和参数的码可以将图片链接存到数据库,以供用户下次分享使用,无需重复获取

3. 存在的问题

  • 稳定性很差,获取小程序码的失败率比较高,甚至会出现一个时间段内完全获取不到码的情况
  • 接口效率不好,由于每次都会存在图片上传,而且上传本身又比较耗时,导致服务器压力巨大且频繁出现慢接口,可能会影响到项目中的其他服务

改造后方案

1. 方案实现

  • 获取小程序码后不再上传七牛,直接通过图片流的方式返回给前端

2. 方案优点

  • 取消了图片的上传操作,接口效率大幅提升,提高了小程序码的获取成功率,也减轻了服务的压力

3. 存在的问题

  • 依旧存在小程序码获取失败的情况

4. 问题排查

经排查日志发现是accessToken失效导致,缓存的accessToken失效时间远比微信规定的失效时间短,那究竟又是什么情况会导致accessToken失效呢?经讨论和实验发现以下三点:

  • 我们微信的appSecret授权给第三方网站使用(比如阿拉丁),他们也有获取小程序码的服务,运营可以通过阿拉丁获取小程序码,这就会导致阿拉丁使用我们的appSecret获取accessToken,以至于我们缓存中的accessToken失效。
  • 后端缓存中的accessToken存入和获取的逻辑存在缺陷,每当从缓存读取accessToken时,若缓存不命中,则通过微信api获取新的accessToken然后再存入缓存,这个逻辑容易导致缓存穿透,即当多个请求都没有命中缓存时,只有一个线程能通过微信api拿到新的accessToken,其他线程都拿不到。
  • 当一个accessToken存在时间比较长时,手动调用微信api获取小程序码,会看到微信的api也会存在概率获取不到码的情况,但是一个全新生成的accessToken则不会有这种情况,至少在10分钟之内非常稳定。

最终的方案

1. 方案实现

  1. 通知运营不要再使用阿拉丁的生成小程序码的功能,若有这方面需求可以找技术帮忙获取。
  2. 缓存中的accessToken有效时间缩短至5分钟,保证每次使用的accessToken都能稳定获取小程序码。
  3. 修改accessToken的获取机制,由定时器来获取accessToken并更新缓存,定时器每4分钟执行一次,以确保每个请求都能命中缓存,若定时器出现异常,则回退之前的逻辑(请求没有命中缓存,通过微信api重新获取accessToken)。
  4. 最终效果
    这一个方案上线后,线上再也没有出现小程序码没有获取成功的情况,观察日志也没再出现获取失败的情况,目前已经两周保持100%成功率了。

最后一次编辑于  2019-06-04  
点赞 12
收藏
评论

18 个评论

  • 闲云野鹤
    闲云野鹤
    2022-07-12

    发表一下自己的看法和观点,大家看对自己有没有用。

    首先大家知道accessToken 是通过appId,和appSecret来获取的,那么,只要任何地方通过appId和appSecret来进行操作,这个时候,都会改变accessToken值。大家注意了,如果你的同一个appId和appSecret部署了好几个环境,那么这个时候,每个环境都在获取accessToken,这个时候会导致刚刚获取后的accessToken会缓存后变成无效,这个时候,每个环境都这样相互影响,导致了各种死结。
    


    2022-07-12
    赞同
    回复 1
    • 青团社
      青团社
      2022-07-14
      目前我们就是这种情况导致,改了缓存时间解决了。
      2022-07-14
      回复
  • Pillar.L
    Pillar.L
    2021-03-03

    总而言之,是不是有个token校验,所有问题就不是问题了

    2021-03-03
    赞同
    回复
  • skyline
    skyline
    2021-02-24

    每5分钟获取一次是利用了微信被替换的旧token还有5分钟有效期的机制,微信没有对这个有效期做可靠性保证,随时有可能调整为更短时间,这种机制不保险。

    2021-02-24
    赞同
    回复
  • 别说。
    别说。
    2020-12-14

    遇到相同问题,请问是怎么解决的?代码中写固定的access_token,去请求同一个接口,有时成功,有时失败

    2020-12-14
    赞同
    回复
  • S n
    S n
    2020-08-24

    相同的token,时而正常,时而失效,跟缓存没关系,应该是bug

    2020-08-24
    赞同
    回复 1
    • 青团社
      青团社
      2020-08-24
      我们也是啊,上一秒正常,重新扫下就失效,再扫下又好了,目前改造后 从19年到现在没出现过未获取到的情况。
      2020-08-24
      回复
  • Taxz
    Taxz
    2020-07-27

    缓存的同一个有效token有时候成功有时候失败 同样是这样。

    没有别的地方去调用刷掉了。

     2020-07-27 16:34:28 false

     2020-07-27 16:33:03 true

     2020-07-27 16:32:59 true

     2020-07-27 16:32:56 false

     2020-07-27 16:28:30 false

     2020-07-27 16:08:13 false

     2020-07-27 16:08:07 true

     2020-07-27 15:59:03 true

    2020-07-27
    赞同
    回复 3
    • 青团社
      青团社
      2020-07-27
      那这个就不清楚了。。没遇到过。
      2020-07-27
      回复
    • 一棵姚钱树คิดถึง
      一棵姚钱树คิดถึง
      2020-07-28
      我这边也遇到了~有解决么?
      2020-07-28
      回复
    • BUCKY
      BUCKY
      2020-08-14
      我们也遇到同样的问题了,相同的 access_token,第一次失败 第二次成功,目前还没找到原因,你们解决了么?
      2020-08-14
      回复
  • YTC
    YTC
    2020-04-16

    token失效,我怀疑有可能是微信放token的redis满了,触发了淘汰机制,自动失效了

    2020-04-16
    赞同
    回复
  • 月之獠
    月之獠
    2019-06-05

    其实我很想知道的是 最后那张图 记录日志的 是用的什么平台搭建的●▂●

    2019-06-05
    赞同
    回复 1
    • 2019-06-05

      是阿里云的日志收集系统

      2019-06-05
      回复

正在加载...

登录 后发表内容