您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

RedLock实现了分布式锁。 <网站代码>

  • 时间:2022-08-19 00:43 编辑: 来源: 阅读:341
  • 扫一扫,手机访问
摘要:RedLock实现了分布式锁。 <网站代码>
并发是并发程序开发中不可避免的问题。根据系统面向客户和功能场景的不同,对并发的重视程度会有所不同。 从程序的角度来说,并发是指同一段代码同时执行,有些情况是不允许的,比如转移、抢购库存等。如果不验证临界条件,会带来非常严重的后果。 根本原因是并发导致的数据不一致。面对并发,我们通常使用锁来优化。 模拟场景如下:模拟抢购的示例代码(c#)://有10只商品股票private static int stockCount = 10Public bool Buy(){ //模拟执行的逻辑代码thread.sleep所花费的时间(new random()。接下来(100,500));if(stock count & gt;0){ stock count-;返回true}返回false}var测试= new Test();平行。For(1,16,(I)= & gt;{ var stopwatch =新秒表();秒表。start();var数据=测试。buy();秒表。stop();控制台。WriteLine($"ThreadId:{Thread。CurrentThread.ManagedThreadId},结果:{data},时间:{stopwatch。ElapsedMilliseconds }”);});控制台。read key();模拟并行调用Buy方法15次(使用内部线程池,所以ThreadId会重复)。实际上,只有10只股票,但是返回的结果显示11个请求都购买成功。 并发单机部署模式处理方案在单机部署模式下,我们可以通过添加lock(){ }://有10个商品库存private static int stockCount = 10来处理问题;私有静态对象obj = new object();Public bool Buy(){ lock (obj) {//模拟执行的逻辑代码thread.sleep所花费的时间(new random()。接下来(100,500));if(stock count & gt;0){ stock count-;返回true}返回false} }与lock并发从输出结果可以看出,只有10个请求显示购买成功,但同时发现部分请求的执行时间明显变长,这是锁定最直观的影响。当一个线程获得锁时,其余的线程只能继续等待,直到它被释放。并发性越高,需要等待依次解决的线程就越多。 所有语言一般都提供锁的实现,用法也差不多。语言本身实现的锁只能在当前进程中使用,所以在单机模式部署的系统中使用基本没有问题。 集群模式处理方案(分布式锁)在集群模式下,系统部署在多台机器上(一个系统运行多个进程),语言本身实现的锁只能保证当前进程有效(基于内存),没有办法让多个进程共享锁状态。这时候就不得不考虑采用分布式锁,可以通过数据库、ZooKeeper、Redis等来实现。,这些最终都达到了在不同的进程和线程中共享锁状态的目的。 这里,将详细介绍基于Redis的RedLock.net来处理分布式环境下的并发问题。RedLock.net是。NET版的RedLock分布式锁定算法(大部分语言都有相应的实现,查看一下),RedLock分布式锁定算法是Redis的作者提出的。 RedLock简介RedLock的思路是使用多个RedisMasters,节点完全独立,节点之间不需要数据同步。由于主-从体系结构,一旦主设备出现故障,被选为主设备的从设备将失去其锁,而另一个客户机可以重新获得锁。 锁是由setNX(原子操作)命令设置的。在有效时间内,当获取的锁数大于(n/2+1)时,表示成功。失败后,需要向所有节点发送解除锁定的消息。 get lock:set resource _ name my _ random _ valuenxpx 30000 Release lock:ifredis . call(" get ",keys [1]) = = argv [1]然后returnredis.call ("del ",keys [1])否则返回0endRedLock.net集成创建。NETCore API项目NuGet安装redlock.net安装包redlock.net appsettings . JSON添加redis配置{"RedisUrl": "127.0.0.1: 679 ",//多次使用,拆分...}添加ProductService.cs模拟购买商品。//库存有10个商品。如果同时启动多个API服务进行测试,这里改为保存数据库或者其他方式private static int stockCount = 10公共异步任务& ltbool & gtBuyAsync(){ //模拟执行的逻辑代码awaittask.delay (newrandom()所花费的时间。接下来(100,500));if(stock count & gt;0){ stock count-;返回true}返回false}修改Startup.cs,创建RedLockFactory定义RedLockFactory变量:私有Redlock Factory Lockfactory添加的方法:private red lock factory getredlock factory(){ varredisurl = configuration[" redisurl "];If(字符串。IsnullRempty(redi URL)){ throw new argument exception(" redi URL不能为空");} var urls = redisUrl。拆分(“,”)。to list();var endPoints =新列表<。RedLockEndPoint & gt();foreach(URL中的var item){ var arr = item。拆分(":");端点。Add(新的DnsEndPoint(arr[0],Convert。toint 32(arr[1]));}返回RedLockFactory。创建(端点);}在ConfigureServices中注入idistributedlockfactory:lock factory = getredlockfactory();服务。add singleton(type of(IDistributedLockFactory),lock factory);服务。add scoped(type of(product service));修改Configure,并释放lock factory:public void Configure(iApplicationBuilder app,iHosting environment env,iApplicationLifetime) {...lifetime . application stopping . register(()= >;{ lockFactory。dispose();});}在控制器中添加方法distributedlocktest private readonly idistributedlockfactory _ distributedlockfactory;私有只读ProductService _ productServicepublic home controller(IDistributedLockFactory distributedLockFactory,product service product service){ _ distributedLockFactory = distributedLockFactory;_ product service = product service;}[http get]公共异步任务& ltbool & gtDistributedLockTest(){ var product id = " id ";//资源锁定对象// expiryTime锁定到期时间。如果锁区域中的逻辑执行超过了到期时间,锁将被释放。// waitTime等待时间,同样的资源。如果当前锁被其他线程占用,最大等待时间// retryTime等待时间,尝试获取的频率使用(var red lock = await _ distributedlockfactory . createlocasync(product id,timespan.fromseconds (5),timespan.fromseconds (1)),timespan。from milliseconds(20))){ if(red lock。isac quired){ var result = await _ product service。buy async();返回结果;} else {控制台。WriteLine($ "无法获取锁:{DateTime。现在}”);} }返回false}调用接口测试parallel.for (1,16,(I)= >;{ var stopwatch =新秒表();秒表。start();var data = get async($ " http://localhost:5000/home/distributed locktest ")。结果;秒表。stop();控制台。WriteLine($"ThreadId:{Thread。CurrentThread.ManagedThreadId},结果:{data},时间:{stopwatch。ElapsedMilliseconds }”);});红锁关于红锁分布式加锁算法的争议可以参考:分布式加锁怎么做红锁安全吗?综上所述,如果使用锁,肯定会影响性能。我们需要根据实际场景来判断是否真的需要。 在指定锁到期时间时,应该相对恰当,避免锁已经到期,但逻辑还没有执行,从而失去锁的意义。当然,这种情况下也可以考虑重新入锁。 最后推荐Orleans,一个基于Actor模型的分布式框架,是微软开源的,也可以达到分布式锁的效果。 请参阅RedisRedLock.net分布式锁链接。


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【域名/主机/服务器|】qq邮箱提醒在哪里打开(2024-06-04 18:58)
【技术支持|常见问题】1556原创ng8文章搜索页面不齐(2024-05-01 14:43)
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部