曾管理一萬多臺快遞柜,優化了系統中生成唯一取件碼的算法。
項目:https://github.com/nnhy/PickupCode
新建項目,添加 Nuget 應用 NewLife.Redis ,借助其Add去重能力。
代碼如下:
private static void Main(string[] args)
{XTrace.UseConsole();var redis = new FullRedis("127.0.0.1", null, 3);var stationCode = "2743";for (int i = 0; i < 8; i++){var code = BuildPickupCode(redis, stationCode);XTrace.WriteLine("取件碼{0}:{1}", i + 1, code);}
}/// <summary>為站點生成唯一取件碼</summary>
/// <param name="cache">redis確保48小時不重復</param>
/// <param name="stationCode">站點編碼</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
static string BuildPickupCode(ICache cache, string stationCode)
{if (stationCode.IsNullOrEmpty()) throw new ArgumentNullException(nameof(stationCode));var rnd = new Random();for (int i = 0; i < 10; i++){// 生成6位隨機數作為取件碼,不足6位時前面補0var code = rnd.Next(100000, 1000000).ToString().PadLeft(6, '0');// 站點結合取件碼作為唯一key,Redis去重確保48小時內不重復。如果重復再生成一次新的隨機數var key = $"{stationCode}:{code}";if (cache.Add(key, code, 48 * 3600)) return code;}// 連續10次都失敗,就有可能是redis網絡或代理有問題了throw new Exception("Build PickupCode Error!");
}
運行效果
原理比較簡單,借助Redis的SETNX能力,當key不存在時添加,已存在時不改變已有值。
SETNX的返回值0和1表示是否添加成功。
在NewLife.Redis中redis.Add即是SETNX的封裝,如果添加成功,說明這個隨機取件碼可用,反之則生成新的隨機取件碼。
Add第二個參數意義不大,第三個參數表示有效期,這里使用48小時。也就是說,這個key在48小時后將會自動消失,該取件碼將有可能重新生成用于新的快遞。實際運營中,這個有效時間也可能是5到7天。
最后吐槽一下,很多快遞柜的8位取件碼,實在不利于快速記憶,不利于便捷輸入。如果使用6位,大多數人看一次默念一下,即可完成輸入!