评论

微信小程序码获取-从频繁失败到成功率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 个评论

  • 風雲
    風雲
    2020-08-19

    最终的方案

    1. 方案实现

    1. 通知运营不要再使用阿拉丁的生成小程序码的功能,若有这方面需求可以找技术帮忙获取。

    这个最终方案第一点我不是很赞同,这和第三方提供的能力有什么关系呢?

    自己的access_token,建立一个管理机制就好了,超时或失效,重新获取下就可以了嘛!有必要把责任推给别人吗~ 本身也不是什么多大的事情,何必贬低别人,抬高自己呢!

    2020-08-19
    赞同 9
    回复 1
    • 青团社
      青团社
      2021-02-23
      首先 我们只是说因为我们系统设计有缺陷,导致通过阿拉丁获取的小程序码 会导致我们这边出现异常,其次,我们这边修复好后,用阿拉丁生成码不会再出现问题,这到你这里怎么变成贬低别人抬高自己了?我们是正常排查问题原因。列出这一个点而已。
      2021-02-23
      1
      回复
  • 一世情缘
    一世情缘
    2020-04-07

    是不是换新人维护了 出了大BUG 也不修复

    2020-04-07
    赞同 3
    回复 1
    • 阿巴阿巴
      阿巴阿巴
      2020-08-26
      一直没问题 自查下吧
      2020-08-26
      回复
  • 一世情缘
    一世情缘
    2020-04-07

    四月份之前都是正常的。现在不正常。一个大大的BUG。坑死了 ,这几天天天都不正常 都被用户烦死了

    2020-04-07
    赞同 3
    回复
  • 2019-06-04

    统一出口,统一调度即可

    2019-06-04
    赞同 3
    回复
  • 阿巴阿巴
    阿巴阿巴
    2019-06-04

    token不适合从缓存取,总会发生缓存心跳,微信更新心跳,开发自己获取token心跳,节奏不一样的场景,或临界值。我们没从缓存取token目前也几乎是100%成功。也做了你说的缓存在自己服务器,下次检查没有再去获取的处理。

    祝贺成功!

    2019-06-04
    赞同 3
    回复 2
    • 2019-06-04

      先查询缓存再获取token的做法确实可以达到几乎100%的成功率,但是缓存穿透的情况理论上的确是存在的,我们之前主要是缓存token的时间太长了,经常碰到token有时有效,有时失效的问题,着实头疼了一阵子,后来减少token的缓存时间其实就已经大幅改善了。

      2019-06-04
      2
      回复
    • 阿巴阿巴
      阿巴阿巴
      2019-06-04回复

      实际上还会存在心跳节奏不一样的场景,会影响前端的成功率。最理想场景是缓存时间设置为3分钟内。请求并更新token心跳15分钟所有。保证缓存心跳*2<更新token心跳节奏基本旧不会失效了。

      2019-06-04
      2
      回复
  • 阿巴阿巴
    阿巴阿巴
    2019-06-04

    就算授权给多个平台也能支持多token的

    2019-06-04
    赞同 3
    回复 2
    • 。
      2020-08-17
      我们现在是多个项目 之前发布一个项目时没问题,后来又发布了一个新的项目就开始失效了 ,怎么解决多个项目用一个token呢,我现在是在每次调接口时 如果失效 让它重新生成重新获取
      2020-08-17
      回复
    • 阿巴阿巴
      阿巴阿巴
      2020-08-26回复
      一直没问题 自查下吧
      2020-08-26
      回复
  • 一世情缘
    一世情缘
    2020-04-07

    现在还是有问题啊。老是提示token失效。同一个token,上一秒不行下一秒就可以了

    2020-04-07
    赞同 2
    回复 11
    • 青团社
      青团社
      2020-04-10
      没问题呀。。你们的缓存方案是不是有问题。
      2020-04-10
      1
      回复
    • 青团社
      青团社
      2020-04-10
      我们线上正常跑。如果真出问题 社区就不是你一个人在说了。应该是一大群人都反馈不行了。所以建议你们再看看自己的代码。
      2020-04-10
      1
      回复
    • 『系、℃」
      『系、℃」
      2020-04-14回复青团社
      我也是有时成功,有时失败。token:32_3ILiluV7RyHmcxMkUNFPuOygQTBu3B1zTQEZhGLO7ue1tkEQNxiG5Y4KShO_O6PTVgIoJ1-XNPGrzBhePWPl6ig508eX6uXz8DRYAISgrpu4r5n76EEM4GVxaHOAax3MvOm74KyRDPQ9VfljVSZiAAAROV||{"errcode":0,"errmsg":"ok","msgid":1296381152311394305}
      token:32_3ILiluV7RyHmcxMkUNFPuOygQTBu3B1zTQEZhGLO7ue1tkEQNxiG5Y4KShO_O6PTVgIoJ1-XNPGrzBhePWPl6ig508eX6uXz8DRYAISgrpu4r5n76EEM4GVxaHOAax3MvOm74KyRDPQ9VfljVSZiAAAROV||{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hints: [EjGBigaCe-lAmPRA!]"}
      token:32_3ILiluV7RyHmcxMkUNFPuOygQTBu3B1zTQEZhGLO7ue1tkEQNxiG5Y4KShO_O6PTVgIoJ1-XNPGrzBhePWPl6ig508eX6uXz8DRYAISgrpu4r5n76EEM4GVxaHOAax3MvOm74KyRDPQ9VfljVSZiAAAROV||{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hints: [EjGB0qLnRa-414NGa!]"}
      token:32_3ILiluV7RyHmcxMkUNFPuOygQTBu3B1zTQEZhGLO7ue1tkEQNxiG5Y4KShO_O6PTVgIoJ1-XNPGrzBhePWPl6ig508eX6uXz8DRYAISgrpu4r5n76EEM4GVxaHOAax3MvOm74KyRDPQ9VfljVSZiAAAROV||{"errcode":0,"errmsg":"ok","msgid":1296381159424933892}
      token:32_3ILiluV7RyHmcxMkUNFPuOygQTBu3B1zTQEZhGLO7ue1tkEQNxiG5Y4KShO_O6PTVgIoJ1-XNPGrzBhePWPl6ig508eX6uXz8DRYAISgrpu4r5n76EEM4GVxaHOAax3MvOm74KyRDPQ9VfljVSZiAAAROV||{"errcode":0,"errmsg":"ok","msgid":1296381161975070723}
      2020-04-14
      3
      回复
    • 青团社
      青团社
      2020-04-16回复『系、℃」
      缓存的操作是怎么做的
      2020-04-16
      1
      回复
    • 瞄喵
      瞄喵
      2020-04-28
      和缓存有毛线关系,我也是这样现在, 显示发送400001错误,后面再发一次就是43004错误, 以前一直是正常的,最近就会这样,前面发送正常,后面就不行了,我用他们的页面调试接口, 重新刷新token, 发送也是43004,不懂了
      2020-04-28
      3
      回复
    查看更多(6)
  • 2019-06-04
    打call
    2019-06-04
    赞同 2
    回复
  • M小
    M小
    2020-04-13

    同一个有效token有时候成功有时候失败

    2020-04-13
    赞同 1
    回复 7
    • 青团社
      青团社
      2020-04-16
      其他地方调用挤掉了
      2020-04-16
      1
      回复
    • M小
      M小
      2020-04-16回复青团社
      只有每隔五分钟统一重新获取一次,其他地方没有获取
      2020-04-16
      1
      回复
    • 秋禾
      秋禾
      2020-06-01回复青团社
      我调试方法把参数都写死了,同一个token,有效无效无效有效xxxxxxxx。目前还在排查access_token没到7200s就失效的可能。。。
      2020-06-01
      1
      回复
    • Taxz
      Taxz
      2020-07-29回复秋禾
      是微信有bug。发工单之后 现在好了。
      2020-07-29
      回复
    • morisan
      morisan
      2020-10-27回复Taxz
      发工单?从哪里发。同样的问题请教
      2020-10-27
      回复
    查看更多(2)
  • Z
    Z
    2019-06-05

    为何不试试 云函数API加文件操作

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

      公司业务。

      2019-06-21
      1
      回复

正在加载...

登录 后发表内容