日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用缓存防击穿,解决微信”被动回复用户消息”重试回复问题

發布時間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用缓存防击穿,解决微信”被动回复用户消息”重试回复问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

?做微信公眾號開發的時候,其中有個接收普通消息、接收事件推送 API。

有這么條規則,? ”微信服務器在五秒內收不到響應會斷掉連接,并且重新發起請求,總共重試三次。假如服務器無法保證在五秒內處理并回復,可以直接回復空串,微信服務器不會對此作任何處理,并且不會發起重試。詳情請見“發送消息-被動回復消息””。

概括起來就2點

1、就是說5s沒響應,這個請求就會被放棄;

2、會重新發起請求,具有冪等性;

問題

這樣就會產生2個問題。

1、假設我的方法就正好需要6s,那么即使返回結果也是沒用的,因為請求被放棄了。

2、我需要返回給用戶正確的回信,假設第一次超時沒法及時回信,比如綁定操作,第一次沒回信,第二次再來總不能回復綁定過了,這樣顯然不合理。

或者直接回復 success ,這樣顯然沒法正常的進行消息提醒。

那么怎么做到既執行了操作(第一次超時了),(第二次微信重試)又及時回復正確的回信呢?。

代碼實現

1、定義緩存的key,就是消息MsgId。

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、使用lock ,保證并發的時候,若同時有多個 thread要求相同資料,只會(到數據庫)查第一次,剩下的從 cache讀取。

總結

以上是生活随笔為你收集整理的使用缓存防击穿,解决微信”被动回复用户消息”重试回复问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。