ASP.Net Core使用redis連接池(StackExchange.Redis.ConnectionPool)


===============================================

 2020/3/28_第1次修改                       ccb_warlock

 

===============================================

最近有較多的時間給我做框架優化的工作,之所以會關注到redis連接池則是因為框架的數據路由層在redis連接異常時的處理有可以優化的地方,於是針對redis連接池的功能做了學習和測試。

 


一、價值

1.1 池子的價值

這里簡單提下池子設計的價值在於當某類連接需要反復創建,且創建的開銷遠遠大於復用的開銷時,可以選擇引入池子來優化這塊的設計。

一般來說,池子初始化時需要限定池子的大小。

最初池子里沒有一個對象,當需要對象時,從池子里獲取(沒有時會自動創建一個跟蹤的對象后提供你使用),當對象用完后並不做真正的釋放,而是將該對象放回池子里等待下一個業務需要時取用。

 

1.2 redis池子的價值

一般在C#的項目中主要用StackExchange.Redis作為操作redis的輪子,而StackExchange.Redis通過創建TCP連接redis后對其進行一系列操作。

既然通過tcp,我們知道需要做3次握手后才能進行后續的業務,當業務並發執行時,池子就可以更好的降低創建連接的開銷,提高連接效率。

 


二、NuGet包

 

StackExchange.Redis.ConnectionPool

PS.當前使用的版本為1.0.1

 


三、將redis連接池引入項目

3.1 前提

我只在基於asp.net core(2.2、3.1)的項目中測試過相關功能。

 

3.2 添加redis的配置信息

開發過asp.net core項目的應該知道,系統提供了用appsettings.json記錄配置項、並通過依賴注入在項目中獲取配置信息的方案。

 

假設appsettings.json的內容如下:

{
  "Redis": {
    "Host": "localhost",
    "Port": 6379,
    "Password": "123456",
    "PoolSize": 20
  }
}

 

3.3 創建接收配置的實體定義

public class RedisConfig
{
    public string Host { get; set; }
    public int Port { get; set; }
    public string Password { get; set; }
    public int PoolSize { get; set; }
}

 

3.4 添加連接池的依賴注入

這里先不考慮代碼結構的問題,緊接着在Startup.cs中,添加下面的內容:

public class Startup
{
    private IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
    {
         Configuration = configuration;
    }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        //todo

        // 根據實際的業務量來設置最小線程數
        ThreadPool.SetMinThreads(200, 200);
         
        var redisConfig = Configuration.GetSection("Redis").Get<RedisConfig>();

        var redisOptions = new ConfigurationOptions
        {
            EndPoints =
            {
                {redisConfig.Host, redisConfig.Port}
            },
            Password = redisConfig.Password,
        };

        services.AddRedisConnectionPool(redisOptions, redisConfig.PoolSize);

        //todo
    }

}

 

通過調用StackExchange.Redis.ConnectionPool提供的方法,就已經將redis連接池的實體注入到了整個項目中。

 


四、redis連接池的使用

由於我優化的框架是在數據路由層的攔截器里去使用連接池,故以此為例來做描述。

public class RouteInterceptor : BaseInterceptor
{
    private ObjectPool<PooledConnectionMultiplexer> Pool { get; set; }

    public RouteInterceptor(ObjectPool<PooledConnectionMultiplexer> pool)
    {
        Pool = pool;
    }

    protected override void Handler(IInvocation invocation)
    {
        var db = 1;
        //todo(獲取要操作的db)

        PooledConnectionMultiplexer client = null;
        try
        {
            client = Pool.GetObject();
            var clientDb = redis.GetDatabase(db)
            
            //todo
        }
        catch (Exception e)
        {
            //todo
        }
        
        try
        {
            invocation.Proceed();
        }
        catch (Exception e)
        {
            //todo
        }
        finally
        {
            client?.Dispose();
        }
    }
}

 

接着就根據StackExchange.Redis的使用方法對redis進行操作就可以了。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM