一篇學(xué)會(huì) C# Redis list 當(dāng)作隊(duì)列使用
本文轉(zhuǎn)載自微信公眾號(hào)「后端Q」,作者conan 。轉(zhuǎn)載本文請(qǐng)聯(lián)系后端Q公眾號(hào)。
Redis的列表經(jīng)常被用作隊(duì)列,用于在不同程序之間有序地交換消息。一個(gè)客戶端通過(guò) LPUSH 命令將消息放入隊(duì)列中,而另一個(gè)客戶端通過(guò) RPOP 或者 BRPOP 命令取出隊(duì)列中等待時(shí)間最長(zhǎng)的消息。
對(duì)于c# 方法
- using (var redisClent = RedisManager.GetClient())
- {
- while (true)
- {
- if ((DateTime.Now - date).TotalSeconds > maxSeconds)
- break;
- var infoJson = redisClent.DequeueItemFromList(CacheKeys.UploadLoginTimeQueue);
- if (string.IsNullOrWhiteSpace(infoJson) || string.IsNullOrEmpty(infoJson))
- break;
- var info = JsonConvert.DeserializeObject<LoginTimeUpdate>(infoJson);
- UpdateLoginTime(info);
- }
- }
- client = RedisManager.GetClient();
- if (!client.Get<bool>(key))
- {
- client.Set(key, true, DateTime.Now.Date.AddDays(1).AddSeconds(-1));
- }
- var jsonObj = JsonConvert.SerializeObject(info);
- client.EnqueueItemOnList(CacheKeys.UploadLoginTimeQueue, jsonObj);
命令
- redis 127.0.0.1:6379> LPUSH runoobkey redis
- (integer) 1
- redis 127.0.0.1:6379> LPUSH runoobkey mongodb
- (integer) 2
- redis 127.0.0.1:6379> LPUSH runoobkey mysql
- (integer) 3
- redis 127.0.0.1:6379> LRANGE runoobkey 0 10
- 1) "mysql"
- 2) "mongodb"
- 3) "redis"
問(wèn)題,上面的隊(duì)列方法是『不安全』的,因?yàn)樵谶@個(gè)過(guò)程中,一個(gè)客戶端可能在取出一個(gè)消息之后崩潰,而未處理完的消息也就因此丟失。
使用 RPOPLPUSH 命令(或者它的阻塞版本 BRPOPLPUSH )可以解決這個(gè)問(wèn)題:因?yàn)樗粌H返回一個(gè)消息,同時(shí)還將這個(gè)消息添加到另一個(gè)備份列表當(dāng)中,如果一切正常的話,當(dāng)一個(gè)客戶端完成某個(gè)消息的處理之后,可以用 LREM 命令將這個(gè)消息從備份表刪除。
最后,還可以添加一個(gè)客戶端專門(mén)用于監(jiān)視備份表,它自動(dòng)地將超過(guò)一定處理時(shí)限的消息重新放入隊(duì)列中去(負(fù)責(zé)處理該消息的客戶端可能已經(jīng)崩潰),這樣就不會(huì)丟失任何消息了。