Use RedLock implemented in .Net Distributed Lock

Introduction ⒈

  RedLock distributed lock algorithm proposed by the authors Redis realize most languages have a corresponding view , RedLock.net is a .NET version RedLock distributed lock algorithm to achieve, to solve the problem of concurrent distributed.

  RedLock The idea is to use across multiple Redis Master, the node is completely independent, it does not require data synchronization between nodes, because once Master Master-Slave architecture fails when the data is not copied to the Slave, was elected Master of the Slave would be lost lock another client can get the lock again.

  Lock command SETNX (atomic operations) is provided, when the number of locks obtained during the active time is greater than (n / 2 + 1) representative of the success, the need to send a message to all nodes release the lock after a failure.

  Acquire a lock:

1 SET resource_name my_random_value NX PX 30000

  Release the lock:

1 if redis.call("get",KEYS[1]) == ARGV[1] then
2     return redis.call("del",KEYS[1])
3 else
4     return 0
5 end

⒉ use

  1. Create .NETCore API project

  2.Nuget installation RedLock.net

1 Install-Package RedLock.net

  3.appsettings.json add redis configuration

 1 {
 2   "Logging": {
 3     "LogLevel": {
 4       "Default": "Warning"
 5     }
 6   },
 7   "AllowedHosts": "*",
 8   "RedisUrls": [
 9     "127.0.0.1:6379",
10     "192.168.214.128:6379"
11   ]
12 }

  4. Add ProductService.cs, simulated purchase of goods

1  // There are 10 merchandise inventory, if the API service start multiple testing, or where otherwise database into memory 
2  Private  static  int stockCount = 10 ;
 . 3  public  the async the Task < BOOL > BuyAsync ()
 . 4  {
 . 5      // logic simulation execution time spent by the code 
. 6      the await Task.Delay ( new new the Random () the Next (. 100 , 500 ));
 . 7      IF (stockCount> 0 )
 . 8      {
 . 9          stockCount-- ;
 10          return  to true ;
 . 11     }
12     return false;
13 }

  5. Modify Startup.cs, create RedLockFactory

    1. Define RedLockFactory property

 1         private RedLockFactory lockFactory
 2         {
 3             get
 4             {
 5                 var redisUrls = Configuration.GetSection("RedisUrls").GetChildren().Select(s => s.Value).ToArray();
 6                 if(redisUrls.Length <= 0)
 7                 {
 8                     throw new ArgumentException("RedisUrl 不能为空");
 9                 }
10                 var endPoints = new List<RedLockEndPoint>();
11                 foreach (var item in redisUrls)
12                 {
13                     var arr = item.Split(":");
14                     endPoints.Add(new DnsEndPoint(arr[0], Convert.ToInt32(arr[1])));
15                 }
16                 return RedLockFactory.Create(endPoints);
17             }
18         }

    2. ConfigureServices injection IDistributedLockFactory:

1         // This method gets called by the runtime. Use this method to add services to the container.
2         public void ConfigureServices(IServiceCollection services)
3         {
4             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
5             services.AddSingleton(typeof(IDistributedLockFactory), lockFactory);
6             services.AddScoped(typeof(ProductService));
7         }

    3. Modify Configure, releasing lockFactory the end of the application

 1         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
 2         public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
 3         {
 4             if (env.IsDevelopment())
 5             {
 6                 app.UseDeveloperExceptionPage();
 7             }
 8 
 9             app.UseMvc();
10 
11             lifetime.ApplicationStopping.Register(() =>
12             {
13                 lockFactory.Dispose();
14             });
15 
16         }

  6. The method of adding the Controller DistributedLockTest

 1 private readonly IDistributedLockFactory _distributedLockFactory;
 2 private readonly ProductService _productService;
 3 
 4 public HomeController(IDistributedLockFactory distributedLockFactory,
 5     ProductService productService)
 6 {
 7     _distributedLockFactory = distributedLockFactory;
 8     _productService = productService;
 9 }
10 
11 [HttpGet]
12 public async Task<bool> DistributedLockTest()
13 {
 14      var the productId = " ID " ;
 15      // resource locked object
 16      // ExpiryTime lock expiration time, the logic implemented within the lock region exceeds the expiration time, the lock is released
 . 17      // the waitTime waiting time, if the same resource the current locks being used by another thread, the waiting time up to
 18      // retryTime waiting time, how long attempt to acquire a 
19      a using ( var redLock = the await _distributedLockFactory.CreateLockAsync (productId, TimeSpan.FromSeconds ( 5 ), TimeSpan.FromSeconds ( 1 ), TimeSpan.FromMilliseconds ( 20 is )))
 20 is      {
 21 is          IF (redLock.IsAcquired)
22         {
23             var result = await _productService.BuyAsync();
24             return result;
25         }
26         else
27         {
28             Console.WriteLine($"获取锁失败:{DateTime.Now}");
29         }
30     }
31     return false;
32 }

 

  In the article RedLock implement distributed lock modify part of the code written on the base.

 

  

  

Guess you like

Origin www.cnblogs.com/fanqisoft/p/10942753.html