主动回复用户信息 经常使用缓存防击穿 处置微信 重试回复疑问
做微信群众号开发的时刻,其中有个接纳普通讯息、接纳事情推送 API。
有这么条规定, ”微信服务器在五秒内收不到照应会断掉衔接,并且从新动员恳求,总共重试三次。如果主机无法保障在五秒内处置并回复,可以间接回复空串,微信服务器不会对此作任何处置,并且不会动员重试。概略请见“发送信息-主动回复信息””。
概括起来就2点
1、就是说5s没照应,这个恳求就会被丢弃;
2、会从新动员恳求,具备幂等性;
这样就会发生2个疑问。
1、假定我的方法就正好须要6s,那么即使前往结果也是没用的,由于恳求被丢弃了。
2、我须要前往给用户正确的回信,假定第一次性超时没法及时回信,比如绑定操作,第一次性没回信,第二次再来总不能回复绑定过了,这样显然不正当。
或许间接回复 success ,这样显然没法反常的启动信息提示。
那么怎样做到既口头了操作(第一次性超时了),(第二次微信重试)又及时回复正确的回信呢。
1、定义缓存的key,就是信息。
string cacheKey = model.MsgId.ToString();
2、经常使用缓存机制,把结果缓存起来,下次出去,间接回复上次口头的结果。
TimeSpan expired = new TimeSpan(0, 0, 20);string cacheKey = model.MsgId.ToString();return _cacheLayer.Get(cacheKey, () =>{MsgReply param = new MsgReply() { ToUserName = model.FromUserName, FromUserName = model.ToUserName };string Jsonstr = WeiXinHelper.ReadAccess(HttpRuntime.AppDomainAppPath.ToString() + "/App_Data/WeChat/KeyWordReplay.json");var r = JsonConvert.DeserializeObject<AutoReplay>(Jsonstr);param.Content = r.content;if (String.Equals(model.MsgType, "text", StringComparison.CurrentCultureIgnoreCase)){var item = r.keywordcontent.FirstOrDefault(o => o.keyword.Contains(model.Content));if (item != null){param.Content = item.content;}}string response = _weChatAlertsService.SubscribeReply(param);AddReceiveLog(model, xml, response);return response;}, expired);
3、这样既处置幂等疑问,也前往了正确的结果。
4、这里须要留意,缓存 取得每个 Key专有的 lock object;若同时有多个 thread要求相反资料,只会(到数据库)查第一次性,剩下的从 cache读取。
public T Get<T>(string key, Func<T> getDataWork, TimeSpan absoluteExpireTime, bool forceRefresh = false, bool returnCopy = true) where T : class{try{lock (GetMemoryCacheLockObject(key)){
private static object GetMemoryCacheLockObject(string key){string cacheLockKey = string.Format(MemoryCacheLockObjectFormat, key);lock (CacheObject){var lockObject = CacheObject[cacheLockKey];if (lockObject == null){// 取得每個 Key專屬的 lock object;若同時有多個 thread要求相反資料,只會(到資料庫)查第一次性,剩下的從 cache讀取lockObject = new object();CacheObject.Set(cacheLockKey,lockObject,new System.Runtime.Caching.CacheItemPolicy(){AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(10)});}return lockObject;}}
1、经常使用缓存机制,把第一次性的结果保留上去,对方重试的时刻,间接前往上次的结果。
2、经常使用,保障并发的时刻, 若同时有多个 thread要求相反资料,只会(到数据库)查第一次性,剩下的从 cache读取 。