zoukankan      html  css  js  c++  java
  • 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进行操作就可以了。

     

     

     

  • 相关阅读:
    SDOI2008 Sandy的卡片
    BZOJ2555 Substring
    CTSC2012 熟悉的文章
    递增
    丢失的牛
    【模板】点分治
    陌上花开(三维偏序)
    Holes(河鼠入洞)
    弹飞河鼠
    树状数组1
  • 原文地址:https://www.cnblogs.com/straycats/p/12585461.html
Copyright © 2011-2022 走看看