gpt4 book ai didi

c#.NET高级编程高并发必备技巧(二)-分布式锁

转载 作者:我是一只小鸟 更新时间:2023-08-23 22:33:33 25 4
gpt4 key购买 nike

上一篇文章简单的介绍了单机的情况下如何进行加锁,防止高并发带来的问题。 然而现实中,一般会高并发的应用,很少会单机部署。当用户量达到一定的程度,分布式、集群部署是必然的选择。在分布式部署的情况下,之前的单机锁还会有效吗?代码还是之前的代码:

                          
                                private static object lck = new object();
    /// <summary>
    /// 单机锁
    /// </summary>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    [HttpGet]
    public  int Reduce1()
    {
        lock(lck)
        {
            int r = 0;
            string key = "stock";
            string stock = Rds.cli.Get(key);
            r = int.Parse(stock);
            if (r > 0)
            {
                r--;
                Rds.cli.Set(key, r);
            }
            else
            {
                throw new Exception("库存用尽!");
            }
            return r;
        }
    } 

                          
                        

今天再来测试一下,首先在本机模拟分布式的部署。 api 部署3个,分别对应的端口 1020、1021、1022。使用nginx进行负载均衡转发,Nginx简单配置信息如下: Jmeter请求的接口是nginx的8000,请求线程和上一次一样100*10 1000次请求后,再去查库存,发现库存并不为0。所以单机锁,在分布式的情况下,根本没起作用.

所以在分布式的情况下,必须要借助第三方的中间件。Redis是其中比较常见的解决方案,以下是简单的实现代码:

                          
                                /// <summary>
    /// 分布式锁
    /// </summary>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    [HttpGet]
    public int Reduce2()
    {
        bool Lck1 =false;
        int r = 0;
        string identity=Guid.NewGuid().ToString(); //设置识别,避免错误释放锁。
        int OverTime = 10; //根据实际业务场景设置 超时时间,避免出现死锁
        try
        {
            Lck1 = Rds.cli.SetNx("lock", identity, OverTime);
            while (!Lck1)
            {
                Lck1 = Rds.cli.SetNx("lock", identity, OverTime);
            }
            string key = "stock";
            string stock = Rds.cli.Get(key);
            r = int.Parse(stock);
            if (r > 0)
            {
                r--;
                Rds.cli.Set(key, r);
            }
            else
            {
                throw new Exception("库存用尽!");
            }
        }
        catch (Exception ex)
        {
            throw;
        }
        finally
        {
            string id = Rds.cli.Get("lock");
            if(id==identity)
            {
                Rds.cli.Del("lock");
            }
        }
        return r;
    }

                          
                        

再次通过Jmeter 请求nginx 的端口。经过改造后的代码方法,在1000次请求后,库存已经为0。说明此次的分布式锁是有效的.

需要注意的是,要避免死锁,所以加锁的时候,要根据业务场景 设置 过期时间。 为了避免释放错误,加锁的时候也要加上身份认证.

好了此次关于锁的分享完毕.

最后此篇关于c#.NET高级编程高并发必备技巧(二)-分布式锁的文章就讲到这里了,如果你想了解更多关于c#.NET高级编程高并发必备技巧(二)-分布式锁的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com