Open yanchengv opened 8 years ago
正在修复。
@yanchengv
@wikimo @lanrion
def send_template openid,template_id,data
url = $weixin.authorize_url(‘http://www.jinhuo.com’)
template_id = Settings.weixin.template1
response = $weixin.send_template_msg(openid, template_id, url, 'red', data)
end
这种问题出现是由于部署由mina
改为Capistrano
引起的,后来改回mina就正常了。找了一下原因,猜测应该是worker_processes
进程数量引起的。
一直泪奔过来了,现在恢复正常也没敢在动环境测试,等缓一缓我测试一下是否这个原因
你是不是每台机器都new了一个 WeixinAuthorize::Client?这样子的话,会互相请求access_token的API,导致其他worker正在使用时失败。
微信的官方wiki对此的解释:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183&token=&lang=zh_CN
1、为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务;
https://github.com/lanrion/weixin_authorize/wiki/input-custom_access_token
即先在中控服务器使用weixin_authorize的 get_access_token接口获取,然后在其他业务服务器使用这些数据,参照wiki https://github.com/lanrion/weixin_authorize/wiki/input-custom_access_token
同时建议使用Redis。
这种基本就是重复调用引起的,建议源码也阅读下,以便于更好地使用gem @yanchengv
workproess 如果是多个的话,可以看成是多个client获取access_token。
根据微信的建议,你需要独立获取access_token,然后供应给其他人使用。
项目里用了 MonitorMixin 的 synchronize 来避免 access_token 的竞争。 但只能避免线程间的竞争,如果用 Puma 开启了多个进程,是容易出现重复刷新 access_token 的问题。
可以通过第三方存储的锁机制。例如,用Redis的写入锁
Redis.set('lock_key', 'refreshing', ex: 3, nx: true)
https://github.com/Eric-Guo/wechat 这个项目中用了随机数检查过期时间的方式,但这种方式会有不稳定的结果。
@lingceng
获取access_token 最好是单独一台机器来维护.
添加分布式锁setnx 也是最好的方案.
调用
$client.download_media_url(media_id) 或者$weixin.send_template_msg()
: 不定期出现错误,但是微信的 每日实时调用量并没有变化,重复调用几次又正常了,一会又报错了。。。{"code":40001,"en_msg":"invalid credential, access_token is invalid or not latest hint: [8KS0939ge11]","cn_msg":"获取access_token时AppSecret错误,或者access_token无效","result":{}}