当前位置: 首页 > news >正文

凡科建站代理商潍坊专业输送带产品介绍

凡科建站代理商,潍坊专业输送带产品介绍,手机端网页设计尺寸规范,wordpress百度结构化数据插件前言 系统为了保证高可用#xff0c;通常会部署多实例#xff0c;并且会存在同时对共享资源并发读写#xff0c;这时候为了保证读写的安全#xff0c;常规手段是会引入分布式锁#xff0c;本文将介绍如何使用redis设计一个优雅的Go分布式锁。 设计 redis分布式锁是借助…前言 系统为了保证高可用通常会部署多实例并且会存在同时对共享资源并发读写这时候为了保证读写的安全常规手段是会引入分布式锁本文将介绍如何使用redis设计一个优雅的Go分布式锁。 设计 redis分布式锁是借助SETNX来实现可能会遇到一下两个场景 加锁后没正确解锁当一个协程获取到锁后还未执行解锁操作时因为服务重启等原因导致死锁。解除别人的锁为了避免死锁会引入超时机制如果锁时间较短但是执行时间过长就会导致锁超时其他协程就会获取这个时候第一个协程执行完后会将第二个协程获取的锁提前释放了。 解决方案其实也挺简单 加锁时记录锁定协程的标识解锁的时候校验是否是自己的锁。设置合理超时时间并且锁定期间增加一个续约协程延长超时时间。 实现 接口定义 首先需要考虑定义一个抽象接口来作为防腐层解耦业务和具体技术细节。 接口定义的原则职责单一、功能抽象不要与具体实现的技术细节挂钩可以设计如下 sync/locker.go package syncimport (contexterrors ) type UnlockFunc func(ctx context.Context) error // 解锁函数type Locker interface {Lock(ctx context.Context, key string) (UnlockFunc, error) // 加锁 }接口只有一个方法加锁成功后返回一个解锁的方法这样设计好处是可以巧妙利用闭包来保存加锁人信息并且封装在具体的实现中使用方无感知使用起来也非常简单 var locker ... unlock, err: locker.Lock(ctx, ..) if err!nil {return err } defer func{err unlock(ctx)... }()另外为了简单起见加/解锁失败或是网络异常等未知异常都是返回一个error为了区分通常会预定义两个加/解锁失败的异常 var ErrLockFail errors.New(get lock get fail) var ErrUnlockFail errors.New(unlock lock get fail)接口实现 接着我们开始实现接口 package redisimport (contextfmttimeitart.top/internal/pkg/syncgithub.com/go-redis/redis/v8github.com/gofrs/uuid )var lockerTimeout time.Minute // 默认锁定1分钟 var renewalTime lockerTimeout / 2 // 时间过一半就续期var delLockerScript redis.NewScript( if redis.call(get,KEYS[1]) ARGV[1] thenreturn redis.call(del,KEYS[1]) elsereturn 0 end) // 删除锁的lua脚本先判断是否是自己的锁再删除type Locker struct {client *redis.Clientns string }func NewLocker(client *redis.Client, ns string) *Locker {return Locker{client: client,ns: ns,} }func (r *Locker) Lock(ctx context.Context, key string) (sync.UnlockFunc, error) {lockKey : fmt.Sprintf(%s:%s, r.ns, key)uuid, _ : uuid.NewV4()id : uuid.String() // 锁定人标识cmd : r.client.SetNX(ctx, lockKey, id, lockerTimeout)if !cmd.Val() { // 已经被锁住return nil, sync.ErrLockFail}ctx, cancel : context.WithCancel(ctx)go r.renewal(ctx, lockKey) // 续期return func(ctx context.Context) error {defer cancel()return r.unlock(ctx, lockKey, id)}, nil }// 续约: 时间过半后续约 func (r *Locker) renewal(ctx context.Context, key string) {ticker : time.NewTicker(renewalTime)defer ticker.Stop()for {select {case -ctx.Done():returncase -ticker.C:r.client.Expire(ctx, key, lockerTimeout)}} }// 解锁 func (r *Locker) unlock(ctx context.Context, lockKey string, id string) error {num, err : delLockerScript.Run(ctx, r.client,[]string{lockKey}, id).Int()if err ! nil {return err}if num 0 {return sync.ErrUnlockFail}return nil }说明 通过Lua来保证原子性校验“解锁”和“加锁”是同一个协程是的话才执行删除锁。通过ns标识来隔离业务不同的业务分配不同的实例和ns命名空间。通过renewal方法续期如果业务执行时间超过加锁时间则可以自动续期另外因为有这个续期的存在所以“锁超时时间”没必要设置过长。异常自动释放锁由于续期是通过协程存在内存中如果程序异常中止就不会续期加锁时间超时后就会自动解锁。 使用 我们可以手动NewLocker方式直接使用为不同的业务都实例化一个不同ns的实例。 也可以通过wire管理由于wire是单例方式管理如果要实现多实例只能为不同业务定义不同的别名假设我们需要实现一个部署锁 首先需要为实现类定义一个别名DeployLocker然后增加一个实例方法 NewDeployLocker指定一个命名空间deploy redis/deploy_locker.go type DeployLocker Lockerfunc NewDeployLocker(cache *cache.Cache) *DeployLocker {return (*DeployLocker)(NewLocker(cache, deploy)) }接着给接口也定义一个别名 biz/deploy_locker.go type DeployLocker sync.Locker最后通过wire绑定接口和实现类 redis.NewDeployLocker, wire.Bind(new(biz.DeployLocker), new(*redis.DeployLocker)这样就定义好一个部署的锁需要地方就可以定义一个biz.DeployLocker参数有wire来注入实现。 如果还有其他业务也需要锁时可以和Deploy类似再定义一套来实现。 原文地址https://itart.cn/blogs/2025/practice/go-redis-locker.html
http://www.w-s-a.com/news/877831/

相关文章:

  • 别人的做网站网页打不开图片
  • 北京专业网站设计推荐怎么建立网站网址
  • 上海网站建设开发公司哪家好网站数据搬家
  • 杭州建站平台哪里有免费的网站推广软件
  • 深圳极速网站建设服务什么网站可以做产品入驻
  • 淄博易宝网站建设app推广拉新公司
  • 营销型外贸网站建设软件备案域名出租
  • 网站域名禁止续费m99ww094cn 苍井空做的网站
  • 上海建设工程网站大同网站建设熊掌号
  • 设计类书籍网站江苏网站建设简介模板
  • 手机企业网站推广c 手机app开发
  • 网站建设需要多少天凡客建设网站稳定吗
  • 房天下网站建设女生说wap是什么意思
  • 网站开发安全机制北京做网站多少钱合理
  • 扁平化 公司网站建设大型视频网站需要的资金量
  • 免费建各种网站淄博网站建设yx718
  • 凡科网建站入门教程运城市网站建设
  • 黄浦区未成年人思想道德建设网站oa系统是什么
  • 微信里的网站怎么做电子商务网站开发平台
  • 易企秀网站怎么做轮播图网站建设张世勇
  • 网站备案幕布尺寸建立网页的几个步骤
  • pc网站页面找出网站所有死链接
  • 专业做seo的网站网站内连接
  • 阿里云网站开发服务器想开网站建设公司
  • 网站开发不足之处茶叶seo网站推广与优化方案
  • 响应式网站建设系统网站优化怎么做 有什么技巧
  • 班级网站做哪些方面wordpress标签 扩展
  • 如何在电商上购物网站Wordpress 域名授权插件
  • 网站建设后台怎么弄昆明如何做好关键词推广
  • 自己怎么做个网站优酷视频网站开发