searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

分布式缓存连接池版Java客户端开发

2022-12-21 08:17:55
664
0

背景

分布式缓存连接池版Java客户端,在redis官方java客户端Jedis的基础上进行了封装,针对分布式缓存存在多个接入机的模式,建立并维护与多接入机的连接池(同步连接),支持:
(1)多接入机模式下的连接池操作,可配置多接入机地址,采用轮询方式发送命令至接入机集群。 
(2)完全兼容jedis,可直接使用官方客户端Jedis的操作。
(3)客户端可动态监测服务端可用状态来调整获取连接策略。
(4)支持最大连接数、最大/最小空闲连接数、监测开闭、后台监测周期等多项参数的配置。
通过全国各省IT推广的运维经验,建议单个应用使用单个连接池,而不是单个应用使用多个连接池(会导致总体连接数较高,浪费资源)。

开发相关配置

  1.  项目配置
    1. Maven-pom配置
      <dependency>
      		<groupId>com.ctg.itrdc.cache</groupId>
      		<artifactId>ctg-cache-nclient</artifactId>
      		<version>2.8.4</version>
      </dependency>
      
      注意:2.3.2版本以后,Java连接池版客户端依赖ctg-cache-nclient,不再依赖ctg-cache-control,新版的nclient中jedis请使用3.3.0。
      <distributionManagement>
      		<repository>
      			<id>releases</id>
      			<name>Internal Releases</name>
      			<url>http://10.142.90.61:8081/nexus/content/repositories/releases</url>
      		</repository>
      		<snapshotRepository>
      			<id>snapshots</id>
      			<name>Internal Snapshots</name>
      			<url>http://10.142.90.61:8081/nexus/content/repositories/snapshots</url>
      		</snapshotRepository>
      	</distributionManagement>
      ​
    2. 配置项

      需要设置如下两个配置类,其中后者是前者的变量。

      CtgJedisPoolConfig  包含客户端所有配置项

      参数 类型 说明

      poolConfig

      GenericObjectPoolConfig

      Apache pool 配置,默认为JedisPoolConfig

      connectionTimeout

      int

      连接超时时间,单位毫秒,默认5秒

      soTimeout

      int

      操作超时时间,单位毫秒,默认5秒

      password

      String

      密码,必填,格式为“用户#密码”

      database

      Int/String

      桶位或者分组名,必填

      clientName

      String

      客户端名,默认null

      period

      long

      后台监控执行周期,毫秒,默认3秒

      monitorTimeout

      int

      监控命令超时时间,毫秒,默认500毫秒

      monitorErrorNum

      int

      监控连续出错几次,将接入机节点判断为失效,默认3次

      nodes

      List<HostAndPort>

      接入机地址列表

      monitorLog

      boolean

      是否开启后台监控日志,默认开启

      GenericObjectPoolConfig 封装了与连接池有关配置

      参数 类型 说明

      MaxTotal

      int

      最大连接数(空闲+使用中),建议设置为应用线程数的一半到应用的线程总数的范围内。

      MaxIdle

      int

      最大空闲连接数,不超过最大连接数

      MinIdle

      int

      保持的最小空闲连接数,默认0

      MaxWaitMillis

      long

      获取连接时的最大等待毫秒数,如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1

      TestWhileIdle

      boolean

      在空闲时检查有效性,默认true

      MinEvictableIdleTimeMillis

      long

      逐出连接的最小空闲时间(毫秒),默认60秒

      TimeBetweenEvictionRunsMillis

      long

      逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认30秒

      NumTestsPerEvictionRun

      int

      每次逐出检查时 逐出的最大数目百分比,如果是负数,则为1/abs(n),默认为-1

    3. 配置操作连接池对象的实例化需要CtgJedisPoolConfig配置类,CtgJedisPoolConfig配置类中的参数可参考上述表格,其中(GenericObjectPoolConfig)poolConfig变量用于配置客户端与接入机的连接池参数,类JedisPoolConfig继承自GenericObjectPoolConfig并设置了合理的默认参数。所以在配置操作时,CtgJedisPoolConfig中的poolConfig参数推荐使用类JedisPoolConfig实现,并设置额外的配置。参考代码如下:
      List<HostAndPort> hostAndPortList = new ArrayList();
      // 接入机的ip和端口号
      HostAndPort host1 = new HostAndPort("132.122.232.225" ,8352);
      HostAndPort host2 = new HostAndPort("132.122.232.225" ,8362	);
      hostAndPortList.add(host1);
      hostAndPortList.add(host2);
      
      GenericObjectPoolConfig poolConfig = new JedisPoolConfig();
      poolConfig.setMaxTotal(10); //最大连接数(空闲+使用中),建议设置为应用线程数的一半到应用的线程总数的范围内。
      poolConfig.setMaxIdle(10); //最大空闲连接数
      poolConfig.setMinIdle(3); //保持的最小空闲连接数
      poolConfig.setMaxWaitMillis(3000);
      
      CtgJedisPoolConfig config = new CtgJedisPoolConfig(hostAndPortList);
      config.setDatabase(255)//分组名或者db
      .setPassword("pool#Jedis*123") // 实例名#密码
      .setPoolConfig(poolConfig)
      .setPeriod(3000)
      .setMonitorTimeout(200);
      
  2. 连接池操作
    1. 创建连接池CtgJedisPool
      CtgJedisPool pool = new CtgJedisPool(config);​
      入参说明

      参数

      类型

      是否可为空

      说明

      config

      CtgJedisPoolConfig

      N

      连接池配置数据

      示例
      List<HostAndPort> hostAndPortList = new ArrayList();
      HostAndPort host1 = new HostAndPort("132.122.232.225" ,8352);
      HostAndPort host2 = new HostAndPort("132.122.232.225" ,8362	);
      hostAndPortList.add(host1);
      hostAndPortList.add(host2);
      
      GenericObjectPoolConfig poolConfig = new JedisPoolConfig();
      poolConfig.setMaxTotal(10); // 最大连接数(空闲+使用中)
      poolConfig.setMaxIdle(5); //最大空闲连接数
      poolConfig.setMinIdle(3); //保持的最小空闲连接数
      poolConfig.setMaxWaitMillis(3000);
      
      CtgJedisPoolConfig config = new CtgJedisPoolConfig(hostAndPortList);
      config.setDatabase(255).setPassword("pool#Jedis*123").setPoolConfig(poolConfig)
      .setPeriod(3000).setMonitorTimeout(200);
      
      CtgJedisPool pool = new CtgJedisPool(config);
      ​
    2. 销毁连接池close

      (CtgJedisPool)pool.close();

      功能描述:销毁连接池,可能会抛出运行时异常:

      throw new JedisException("Could not destroy the pool", e);
      示例
      CtgJedisPool pool = new CtgJedisPool(config);
      pool.close();
      ​
    3. 获取连接getResource
      (CtgJedisPool)pool.getResource();​

      功能描述:从连接池中获取一个可用连接,客户端会轮询可用列表从中拿出可用连接,使用完成后请使用归还命令归还连接。

      注意事项:获取失败会抛出异常CtgJedisPoolException

      返回类型:ProxyJedis

      示例

      initPool();
      ProxyJedis jedis = new ProxyJedis();
      try {
        jedis = pool.getResource();
        String key   = StringGenarator.getRandomKeyString(10);
        String value = StringGenarator.getRandomValueString(10);
        //sendCommand 可能会抛出 运行时异常
        jedis.set(key, value);
        //sendCommand 可能会抛出 运行时异常
        jedis.get(key);
        jedis.close();
      } catch (Throwable je){
        jedis.close();
      }
      pool.close();
      ​
    4. 归还连接jedis.close()
      (ProxyJedis)jedis.close();
      功能描述:将连接归还至连接池中,如果使用过程发生异常、超时,将会销毁该连接

      示例

      initPool();
      ProxyJedis jedis = new ProxyJedis();
      try {
        jedis = pool.getResource();
        String key   = StringGenarator.getRandomKeyString(10);
        String value = StringGenarator.getRandomValueString(10);
        //sendCommand 可能会抛出 运行时异常
        jedis.set(key, value);
        //sendCommand 可能会抛出 运行时异常
        jedis.get(key);
        jedis.close();
      } catch (Throwable je){
        jedis.close();
      }
      pool.close();
      ​
  3. 其他说明

    (1)密码与桶位在初始化连接池时使用,后期不可修改。

    (2)获取连接后及时归还连接,使用过程中发生异常catch后要归还连接。

    (3)GenericObjectPoolConfig配置的连接池数量是与所有接入机连接数之和,请参考Apache Commons pool2合理配置。

    (4)类JedisPoolConfig继承自GenericObjectPoolConfig并设置了合理的默认参数,推荐使用JedisPoolConfig作为配置。

    (5)查问题时请先跟踪连接池客户端的监控日志,判断接入机状况;

    (6)单个连接只能单线程调用,不可多线程复用。

  4. 示例代码
    public class CtgJedisPoolTest {
    	public static final Logger logger = LoggerFactory.getLogger(CtgJedisPoolTest.class);
    	public static void main(String[] args) {
    		BasicConfigurator.configure();
    		List<HostAndPort> hostAndPortList = new ArrayList(); //接入机地址列表
            HostAndPort host1 = new HostAndPort("132.122.232.225" ,8352); //接入机-1
            HostAndPort host2 = new HostAndPort("132.122.232.225" ,8362); //接入机-2
            hostAndPortList.add(host1);
            hostAndPortList.add(host2);
            GenericObjectPoolConfig poolConfig = new JedisPoolConfig(); //线程池配置
            poolConfig.setMaxTotal(10); // 最大连接数(空闲+使用中)
            poolConfig.setMaxIdle(3); //最大空闲连接数
            poolConfig.setMinIdle(3); //保持的最小空闲连接数
            poolConfig.setMaxWaitMillis(3000); //借出连接时最大的等待时间
            CtgJedisPoolConfig config = new CtgJedisPoolConfig(hostAndPortList);
            config.setDatabase(255) //分组对应的桶位
                    .setPassword("pool#Jedis*123") // “用户#密码”
                    .setPoolConfig(poolConfig) //线程池配置
                    .setPeriod(3000)  //后台监控执行周期,毫秒
                    .setMonitorTimeout(200);  //后台监控ping命令超时时间,毫秒
            CtgJedisPool pool = new CtgJedisPool(config); //创建连接池
            ProxyJedis jedis = null;
            for (int i = 1; i <= 1000; i++) {
                try {
                    jedis = pool.getResource();  //获取连接,可能抛出异常
                    String key   = "**key" +i;
                    String value = "**value" + i;
                    jedis.set(key, value);
                } catch (CtgJedisPoolException e) {
                    logger.error(e.getMessage(), e);
                } catch (JedisConnectionException e) {
                    logger.error(e.getMessage(), e);
                }
                finally {
                    // finally内执行,确保连接归还
                    try{
                        jedis.close();
                    } catch (Throwable e) {
                    }
                     //归还连接至连接池
                }
            }
            pool.close(); //关闭连接池
    	}
    }
    ​

 

 

 

 

0条评论
作者已关闭评论
洪****能
3文章数
0粉丝数
洪****能
3 文章 | 0 粉丝
洪****能
3文章数
0粉丝数
洪****能
3 文章 | 0 粉丝
原创

分布式缓存连接池版Java客户端开发

2022-12-21 08:17:55
664
0

背景

分布式缓存连接池版Java客户端,在redis官方java客户端Jedis的基础上进行了封装,针对分布式缓存存在多个接入机的模式,建立并维护与多接入机的连接池(同步连接),支持:
(1)多接入机模式下的连接池操作,可配置多接入机地址,采用轮询方式发送命令至接入机集群。 
(2)完全兼容jedis,可直接使用官方客户端Jedis的操作。
(3)客户端可动态监测服务端可用状态来调整获取连接策略。
(4)支持最大连接数、最大/最小空闲连接数、监测开闭、后台监测周期等多项参数的配置。
通过全国各省IT推广的运维经验,建议单个应用使用单个连接池,而不是单个应用使用多个连接池(会导致总体连接数较高,浪费资源)。

开发相关配置

  1.  项目配置
    1. Maven-pom配置
      <dependency>
      		<groupId>com.ctg.itrdc.cache</groupId>
      		<artifactId>ctg-cache-nclient</artifactId>
      		<version>2.8.4</version>
      </dependency>
      
      注意:2.3.2版本以后,Java连接池版客户端依赖ctg-cache-nclient,不再依赖ctg-cache-control,新版的nclient中jedis请使用3.3.0。
      <distributionManagement>
      		<repository>
      			<id>releases</id>
      			<name>Internal Releases</name>
      			<url>http://10.142.90.61:8081/nexus/content/repositories/releases</url>
      		</repository>
      		<snapshotRepository>
      			<id>snapshots</id>
      			<name>Internal Snapshots</name>
      			<url>http://10.142.90.61:8081/nexus/content/repositories/snapshots</url>
      		</snapshotRepository>
      	</distributionManagement>
      ​
    2. 配置项

      需要设置如下两个配置类,其中后者是前者的变量。

      CtgJedisPoolConfig  包含客户端所有配置项

      参数 类型 说明

      poolConfig

      GenericObjectPoolConfig

      Apache pool 配置,默认为JedisPoolConfig

      connectionTimeout

      int

      连接超时时间,单位毫秒,默认5秒

      soTimeout

      int

      操作超时时间,单位毫秒,默认5秒

      password

      String

      密码,必填,格式为“用户#密码”

      database

      Int/String

      桶位或者分组名,必填

      clientName

      String

      客户端名,默认null

      period

      long

      后台监控执行周期,毫秒,默认3秒

      monitorTimeout

      int

      监控命令超时时间,毫秒,默认500毫秒

      monitorErrorNum

      int

      监控连续出错几次,将接入机节点判断为失效,默认3次

      nodes

      List<HostAndPort>

      接入机地址列表

      monitorLog

      boolean

      是否开启后台监控日志,默认开启

      GenericObjectPoolConfig 封装了与连接池有关配置

      参数 类型 说明

      MaxTotal

      int

      最大连接数(空闲+使用中),建议设置为应用线程数的一半到应用的线程总数的范围内。

      MaxIdle

      int

      最大空闲连接数,不超过最大连接数

      MinIdle

      int

      保持的最小空闲连接数,默认0

      MaxWaitMillis

      long

      获取连接时的最大等待毫秒数,如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1

      TestWhileIdle

      boolean

      在空闲时检查有效性,默认true

      MinEvictableIdleTimeMillis

      long

      逐出连接的最小空闲时间(毫秒),默认60秒

      TimeBetweenEvictionRunsMillis

      long

      逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认30秒

      NumTestsPerEvictionRun

      int

      每次逐出检查时 逐出的最大数目百分比,如果是负数,则为1/abs(n),默认为-1

    3. 配置操作连接池对象的实例化需要CtgJedisPoolConfig配置类,CtgJedisPoolConfig配置类中的参数可参考上述表格,其中(GenericObjectPoolConfig)poolConfig变量用于配置客户端与接入机的连接池参数,类JedisPoolConfig继承自GenericObjectPoolConfig并设置了合理的默认参数。所以在配置操作时,CtgJedisPoolConfig中的poolConfig参数推荐使用类JedisPoolConfig实现,并设置额外的配置。参考代码如下:
      List<HostAndPort> hostAndPortList = new ArrayList();
      // 接入机的ip和端口号
      HostAndPort host1 = new HostAndPort("132.122.232.225" ,8352);
      HostAndPort host2 = new HostAndPort("132.122.232.225" ,8362	);
      hostAndPortList.add(host1);
      hostAndPortList.add(host2);
      
      GenericObjectPoolConfig poolConfig = new JedisPoolConfig();
      poolConfig.setMaxTotal(10); //最大连接数(空闲+使用中),建议设置为应用线程数的一半到应用的线程总数的范围内。
      poolConfig.setMaxIdle(10); //最大空闲连接数
      poolConfig.setMinIdle(3); //保持的最小空闲连接数
      poolConfig.setMaxWaitMillis(3000);
      
      CtgJedisPoolConfig config = new CtgJedisPoolConfig(hostAndPortList);
      config.setDatabase(255)//分组名或者db
      .setPassword("pool#Jedis*123") // 实例名#密码
      .setPoolConfig(poolConfig)
      .setPeriod(3000)
      .setMonitorTimeout(200);
      
  2. 连接池操作
    1. 创建连接池CtgJedisPool
      CtgJedisPool pool = new CtgJedisPool(config);​
      入参说明

      参数

      类型

      是否可为空

      说明

      config

      CtgJedisPoolConfig

      N

      连接池配置数据

      示例
      List<HostAndPort> hostAndPortList = new ArrayList();
      HostAndPort host1 = new HostAndPort("132.122.232.225" ,8352);
      HostAndPort host2 = new HostAndPort("132.122.232.225" ,8362	);
      hostAndPortList.add(host1);
      hostAndPortList.add(host2);
      
      GenericObjectPoolConfig poolConfig = new JedisPoolConfig();
      poolConfig.setMaxTotal(10); // 最大连接数(空闲+使用中)
      poolConfig.setMaxIdle(5); //最大空闲连接数
      poolConfig.setMinIdle(3); //保持的最小空闲连接数
      poolConfig.setMaxWaitMillis(3000);
      
      CtgJedisPoolConfig config = new CtgJedisPoolConfig(hostAndPortList);
      config.setDatabase(255).setPassword("pool#Jedis*123").setPoolConfig(poolConfig)
      .setPeriod(3000).setMonitorTimeout(200);
      
      CtgJedisPool pool = new CtgJedisPool(config);
      ​
    2. 销毁连接池close

      (CtgJedisPool)pool.close();

      功能描述:销毁连接池,可能会抛出运行时异常:

      throw new JedisException("Could not destroy the pool", e);
      示例
      CtgJedisPool pool = new CtgJedisPool(config);
      pool.close();
      ​
    3. 获取连接getResource
      (CtgJedisPool)pool.getResource();​

      功能描述:从连接池中获取一个可用连接,客户端会轮询可用列表从中拿出可用连接,使用完成后请使用归还命令归还连接。

      注意事项:获取失败会抛出异常CtgJedisPoolException

      返回类型:ProxyJedis

      示例

      initPool();
      ProxyJedis jedis = new ProxyJedis();
      try {
        jedis = pool.getResource();
        String key   = StringGenarator.getRandomKeyString(10);
        String value = StringGenarator.getRandomValueString(10);
        //sendCommand 可能会抛出 运行时异常
        jedis.set(key, value);
        //sendCommand 可能会抛出 运行时异常
        jedis.get(key);
        jedis.close();
      } catch (Throwable je){
        jedis.close();
      }
      pool.close();
      ​
    4. 归还连接jedis.close()
      (ProxyJedis)jedis.close();
      功能描述:将连接归还至连接池中,如果使用过程发生异常、超时,将会销毁该连接

      示例

      initPool();
      ProxyJedis jedis = new ProxyJedis();
      try {
        jedis = pool.getResource();
        String key   = StringGenarator.getRandomKeyString(10);
        String value = StringGenarator.getRandomValueString(10);
        //sendCommand 可能会抛出 运行时异常
        jedis.set(key, value);
        //sendCommand 可能会抛出 运行时异常
        jedis.get(key);
        jedis.close();
      } catch (Throwable je){
        jedis.close();
      }
      pool.close();
      ​
  3. 其他说明

    (1)密码与桶位在初始化连接池时使用,后期不可修改。

    (2)获取连接后及时归还连接,使用过程中发生异常catch后要归还连接。

    (3)GenericObjectPoolConfig配置的连接池数量是与所有接入机连接数之和,请参考Apache Commons pool2合理配置。

    (4)类JedisPoolConfig继承自GenericObjectPoolConfig并设置了合理的默认参数,推荐使用JedisPoolConfig作为配置。

    (5)查问题时请先跟踪连接池客户端的监控日志,判断接入机状况;

    (6)单个连接只能单线程调用,不可多线程复用。

  4. 示例代码
    public class CtgJedisPoolTest {
    	public static final Logger logger = LoggerFactory.getLogger(CtgJedisPoolTest.class);
    	public static void main(String[] args) {
    		BasicConfigurator.configure();
    		List<HostAndPort> hostAndPortList = new ArrayList(); //接入机地址列表
            HostAndPort host1 = new HostAndPort("132.122.232.225" ,8352); //接入机-1
            HostAndPort host2 = new HostAndPort("132.122.232.225" ,8362); //接入机-2
            hostAndPortList.add(host1);
            hostAndPortList.add(host2);
            GenericObjectPoolConfig poolConfig = new JedisPoolConfig(); //线程池配置
            poolConfig.setMaxTotal(10); // 最大连接数(空闲+使用中)
            poolConfig.setMaxIdle(3); //最大空闲连接数
            poolConfig.setMinIdle(3); //保持的最小空闲连接数
            poolConfig.setMaxWaitMillis(3000); //借出连接时最大的等待时间
            CtgJedisPoolConfig config = new CtgJedisPoolConfig(hostAndPortList);
            config.setDatabase(255) //分组对应的桶位
                    .setPassword("pool#Jedis*123") // “用户#密码”
                    .setPoolConfig(poolConfig) //线程池配置
                    .setPeriod(3000)  //后台监控执行周期,毫秒
                    .setMonitorTimeout(200);  //后台监控ping命令超时时间,毫秒
            CtgJedisPool pool = new CtgJedisPool(config); //创建连接池
            ProxyJedis jedis = null;
            for (int i = 1; i <= 1000; i++) {
                try {
                    jedis = pool.getResource();  //获取连接,可能抛出异常
                    String key   = "**key" +i;
                    String value = "**value" + i;
                    jedis.set(key, value);
                } catch (CtgJedisPoolException e) {
                    logger.error(e.getMessage(), e);
                } catch (JedisConnectionException e) {
                    logger.error(e.getMessage(), e);
                }
                finally {
                    // finally内执行,确保连接归还
                    try{
                        jedis.close();
                    } catch (Throwable e) {
                    }
                     //归还连接至连接池
                }
            }
            pool.close(); //关闭连接池
    	}
    }
    ​

 

 

 

 

文章来自个人专栏
开发指引
3 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0