Azure Function生成唯一序列号时Mutex失效重复问题咨询
Azure Function 序列号重复问题解决
问题根源
你当前的方案无法生效有三个核心原因:
- 本地锁的作用域限制:你用的命名
Mutex属于单机器进程级锁,而Azure Function默认支持横向扩容,当请求量升高时会启动多个实例处理请求,不同实例之间的本地锁完全不互通,自然会出现重复的序列号 - 计数存储不可靠:你把序列号存在静态变量
count里,静态变量仅在当前进程的内存中生效,一旦Function实例重启、扩容、进程回收,count的值就会被重置,也会导致序列号重复甚至回退 - 代码存在拼写错误:
waitOne应为WaitOne、RelaseMutex应为ReleaseMutex,错误的方法调用会导致锁逻辑异常,进一步放大重复问题
对应解决方案
根据你的业务并发量可以选择两种实现方案:
方案一:低并发场景(单实例即可满足需求)
- 先在Azure Function的配置中关闭自动扩容,将实例数固定为1
- 替换
Mutex为更轻量的lock关键字,足以满足单进程内的线程安全要求 - 增加计数持久化逻辑,每次更新序列号后写入本地文件或者Azure存储,避免实例重启导致计数重置
参考代码:
public class MySharedCounter { // 锁对象 private static readonly object _lockObj = new object(); // 计数,实例启动时可以从持久化存储读取上次保存的值 private static long _count = 0; } public long GetSequenceNo(){ lock(MySharedCounter._lockObj){ long seqId = ++MySharedCounter._count; if(seqId > 100){ MySharedCounter._count = 0; seqId = ++MySharedCounter._count; } // 此处添加代码将最新的_count值写入持久化存储 return seqId; } }
方案二:高并发场景(需要支持多实例扩容)
必须使用分布式锁+分布式存储的方案,推荐直接使用Azure Redis缓存的原子自增能力:
- Redis的
INCR命令本身是全局原子操作,不需要额外加锁,调用后直接返回自增后的唯一序列号 - 当返回的序列号大于100时,调用原子命令将计数重置为1即可
这种方案既支持多实例横向扩容,也能保证序列号的唯一性和连续性。
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

