Skip to content

Latest commit

 

History

History
131 lines (95 loc) · 5.49 KB

Distributed-Locking.md

File metadata and controls

131 lines (95 loc) · 5.49 KB

分布式锁

分布式锁是一种管理多个应用程序访问同一资源的技术. 主要目的是同一时间只允许多个应用程序中的一个访问资源. 否则, 从不同的应用程序访问同一对象可能会破坏资源.

ABP当前的分布式锁实现基于DistributedLock库.

安装

你可以打开一个命令行终端并输入以下命令来安装Volo.Abp.DistributedLocking到你的项目中:

abp add-package Volo.Abp.DistributedLocking

这个库提供了使用分布式锁系统所需的API, 但是, 在使用它之前, 你应该配置一个提供程序.

配置一个提供程序

DistributedLock库对RedisZooKeeper提供多种实现.

例如, 如果你想使用Redis provider, 你应该将DistributedLock.Redis NuGet包添加到项目中, 然后将以下代码添加到ABP模块类的ConfigureServices方法中:

using Medallion.Threading;
using Medallion.Threading.Redis;

namespace AbpDemo
{
    [DependsOn(
            typeof(AbpDistributedLockingModule)
            //If you have the other dependencies, you should do here
    )]
    public class MyModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
        
            context.Services.AddSingleton<IDistributedLockProvider>(sp =>
            {
                var connection = ConnectionMultiplexer
                    .Connect(configuration["Redis:Configuration"]);
                return new 
                    RedisDistributedSynchronizationProvider(connection.GetDatabase());
            });
        }
    }
}

此代码从配置获取Redis连接字符串, 因此你可以将以下行添加到appsettings.json文件:

"Redis": {
    "Configuration": "127.0.0.1"
}

使用

有两种方法可以使用分布式锁API: ABP的IAbpDistributedLock抽象和DistributedLock库的API.

使用IAbpDistributedLock服务

IAbpDistributedLock是ABP框架提供的一个用于简单使用分布式锁的服务.

实例: 使用IAbpDistributedLock.TryAcquireAsync方法

using Volo.Abp.DistributedLocking; 

namespace AbpDemo
{
    public class MyService : ITransientDependency
    {
        private readonly IAbpDistributedLock _distributedLock;
		public MyService(IAbpDistributedLock distributedLock)
        {
            _distributedLock = distributedLock;
        }
        
        public async Task MyMethodAsync()
        {
            await using (var handle = 
                         await _distributedLock.TryAcquireAsync("MyLockName"))
            {
                if (handle != null)
                {
                    // your code that access the shared resource
                }
            }   
        }
    }
}

TryAcquireAsync可能无法获取锁. 如果无法获取锁, 则返回null. 在这种情况下, 你不应该访问资源. 如果句柄不为null, 则表示你已获得锁, 并且可以安全地访问资源.

TryAcquireAsync方法拥有以下参数:

  • name (string, 必须): 锁的唯一名称. 不同的锁命名用于访问不同的资源.
  • timeout (TimeSpan): 等待获取锁的超时值. 默认值为TimeSpan.Zero, 这意味着如果锁已经被另一个应用程序拥有, 它不会等待.
  • cancellationToken: 取消令牌可在触发后取消操作.

配置

AbpDistributedLockOptions

AbpDistributedLockOptions 是配置分布式锁的主要选项类.

示例: 设置应用程序的分布式锁Key前缀

Configure<AbpDistributedLockOptions>(options =>
{
    options.KeyPrefix = "MyApp1";
});

在你的模块类中的 ConfigureServices 方法进行配置.

可用选项
  • KeyPrefix (string, 默认值: null): 指定分布式锁名称前缀.

使用DistributedLock库的API

ABP的IAbpDistributedLock服务非常有限, 主要用于ABP框架的内部使用. 对于你自己的应用程序, 可以使用DistributedLock库自己的API. 参见文档详细信息.

Volo.Abp.DistributedLocking.Abstractions库

如果你正在构建一个可重用的库或应用程序模块, 那么对于作为单个实例运行的简单应用程序, 你可能不希望为模块带来额外的依赖关系. 在这种情况下, 你的库可以依赖于Volo.Abp.DistributedLocking.Abstractions库, 它定义了IAbpDistributedLock服务, 并将其在进程内实现(实际上不是分布式的). 通过这种方式, 你的库可以在作为单个实例运行的应用程序中正常运行(没有分布式锁提供程序依赖项). 如果应用程序部署到集群环境, 那么应用程序开发人员应该安装一个真正的分布式提供程序, 如安装部分所述.