前言

之前在做 秒杀架构实践 时有提到对 distributed-redis-tool 的一次小升级,但是没有细说。

其实主要原因是:

秒杀时我做压测:由于集成了这个限流组件,并发又比较大,所以导致连接、断开 Redis 非常频繁。
最终导致获取不了 Redis connection 的异常。

池化技术

这就是一个典型的对稀缺资源使用不善导致的。

何为稀缺资源?常见的有:

  • 线程
  • 数据库连接
  • 网络连接等

这些资源都有共同的特点:创建销毁成本较高

这里涉及到的 Redis 连接也属于该类资源。

我们希望将这些稀有资源管理起来放到一个池子里,当需要时就从中获取,用完就放回去,不够用时就等待(或返回)。

这样我们只需要初始化并维护好这个池子,就能避免频繁的创建、销毁这些资源(也有资源长期未使用需要缩容的情况)。

通常我们称这项姿势为池化技术,如常见的:

  • 线程池
  • 各种资源的连接池等。

为此我将使用到 Redis 的 分布式锁、分布式限流 都升级为利用连接池来获取 Redis 的连接。

这里以分布式锁为例:

将使用的 api 修改为:

原有:

@Configuration
public class RedisLockConfig {@Beanpublic RedisLock build(){//Need to get Redis connection RedisLock redisLock = new RedisLock() ;HostAndPort hostAndPort = new HostAndPort("127.0.0.1",7000) ;JedisCluster jedisCluster = new JedisCluster(hostAndPort) ;RedisLock redisLock = new RedisLock.Builder(jedisCluster).lockPrefix("lock_test").sleepTime(100).build();return redisLock ;}}

现在:

@Configuration
public class RedisLockConfig {private Logger logger = LoggerFactory.getLogger(RedisLockConfig.class);@Autowiredprivate JedisConnectionFactory jedisConnectionFactory;@Beanpublic RedisLock build() {RedisLock redisLock = new RedisLock.Builder(jedisConnectionFactory,RedisToolsConstant.SINGLE).lockPrefix("lock_").sleepTime(100).build();return redisLock;}
}

将以前的 Jedis 修改为 JedisConnectionFactory,后续的 Redis 连接就可通过这个对象获取。

并且显示的传入使用 RedisCluster 还是单机的 Redis。

所以在真正操作 Redis 时需要修改:

    public boolean tryLock(String key, String request) {//get connectionObject connection = getConnection();String result ;if (connection instanceof Jedis){result =  ((Jedis) connection).set(lockPrefix + key, request, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, 10 * TIME);((Jedis) connection).close();}else {result = ((JedisCluster) connection).set(lockPrefix + key, request, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, 10 * TIME);try {((JedisCluster) connection).close();} catch (IOException e) {logger.error("IOException",e);}}if (LOCK_MSG.equals(result)) {return true;} else {return false;}}//获取连接private Object getConnection() {Object connection ;if (type == RedisToolsConstant.SINGLE){RedisConnection redisConnection = jedisConnectionFactory.getConnection();connection = redisConnection.getNativeConnection();}else {RedisClusterConnection clusterConnection = jedisConnectionFactory.getClusterConnection();connection = clusterConnection.getNativeConnection() ;}return connection;}    

最大的改变就是将原有操作 Redis 的对象(T extends JedisCommands)改为从连接池中获取。

由于使用了 org.springframework.data.redis.connection.jedis.JedisConnectionFactory 作为 Redis 连接池。

所以需要再使用时构件好这个对象:

        JedisPoolConfig config = new JedisPoolConfig();config.setMaxIdle(10);config.setMaxTotal(300);config.setMaxWaitMillis(10000);config.setTestOnBorrow(true);config.setTestOnReturn(true);RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();redisClusterConfiguration.addClusterNode(new RedisNode("10.19.13.51", 7000));//单机JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(config);//集群//JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration) ;jedisConnectionFactory.setHostName("47.98.194.60");jedisConnectionFactory.setPort(6379);jedisConnectionFactory.setPassword("");jedisConnectionFactory.setTimeout(100000);jedisConnectionFactory.afterPropertiesSet();//jedisConnectionFactory.setShardInfo(new JedisShardInfo("47.98.194.60", 6379));//JedisCluster jedisCluster = new JedisCluster(hostAndPort);HostAndPort hostAndPort = new HostAndPort("10.19.13.51", 7000);JedisCluster jedisCluster = new JedisCluster(hostAndPort);redisLock = new RedisLock.Builder(jedisConnectionFactory, RedisToolsConstant.SINGLE).lockPrefix("lock_").sleepTime(100).build();

看起比较麻烦,需要构建对象的较多。

但整合 Spring 使用时就要清晰许多。

配合 Spring

Spring 很大的一个作用就是帮我们管理对象,所以像上文那些看似很复杂的对象都可以交由它来管理:

   <!-- jedis 配置 --><bean id="JedispoolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxIdle" value="${redis.maxIdle}"/><property name="maxTotal" value="${redis.maxTotal}"/><property name="maxWaitMillis" value="${redis.maxWait}"/><property name="testOnBorrow" value="${redis.testOnBorrow}"/><property name="testOnReturn" value="${redis.testOnBorrow}"/></bean><!-- redis服务器中心 --><bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="poolConfig" ref="JedispoolConfig"/><property name="port" value="${redis.port}"/><property name="hostName" value="${redis.host}"/><property name="password" value="${redis.password}"/><property name="timeout" value="${redis.timeout}"></property></bean><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="connectionFactory"/><property name="keySerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property><property name="valueSerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property></bean>

这个其实没多少好说的,就算是换成 SpringBoot 也是创建 JedispoolConfig,connectionFactory,redisTemplate 这些 bean 即可。

总结

换为连接池之后再进行压测自然没有出现获取不了 Redis 连接的异常(并发达到一定的量也会出错)说明更新是很有必要的。

推荐有用到该组件的朋友都升级下,也欢迎提出 Issues 和 PR。

项目地址:

https://github.com/crossoverJie/distributed-redis-tool

转载于:https://www.cnblogs.com/crossoverJie/p/9385900.html

分布式工具的一次小升级⏫ 1相关推荐

  1. 分布式工具的一次小升级⏫

    前言 之前在做 秒杀架构实践 时有提到对 distributed-redis-tool 的一次小升级,但是没有细说. 其实主要原因是: 秒杀时我做压测:由于集成了这个限流组件,并发又比较大,所以导致连 ...

  2. 最强分布式工具Redisson:分布式锁

    一.Redisson概述 什么是Redisson?-- Redisson Wiki Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).它 ...

  3. 租赁共享农机械设备工具门店扫码小程序开发

    租赁共享农机械设备工具门店扫码小程序开发 支持一物一码 一物一码让您更好的监控租赁物品,扫 一扫即可知道物品当前所在,状态及其 他.而且一物一码可以让您的业务更轻 松拓展到物联网. 营销功能 支持开通 ...

  4. python自动翻译小工具_Python实现翻译小工具

    一.背景 利用Requests模块获取有道词典web页面的post信息,BeautifulSoup来获取需要的内容,通过tkinter模块生成gui界面. 二.代码 git源码地址 Python实现翻 ...

  5. android开发工具哪个好_小程序开发工具怎么用?哪个好用?

    想要开发微信小程序,在没有太多资金找外包团队定制.自建团队开发时,就需要你自己通过小程序开发工具来生成小程序了.现在各种开发工具很多,到底小程序开发工具有哪些?这些微信小程序开发工具哪个好用?根据我的 ...

  6. 实用工具证件照制作微信小程序源码

    这是一款证件照制作的微信小程序,里面也支持直接微信公众号版本生成安装 支持多种尺寸制作 支持相册上传于直接相机拍摄 支持电子照存档等等 拥有小程序推荐功能,可以给其它的小程序实现引流 另外还支持换装美 ...

  7. 全新实用工具证件照制作微信小程序源码下载支持多种证件生成与制作

    这是一款证件照制作的微信小程序,里面也支持直接微信公众号版本生成安装 支持多种尺寸制作 支持相册上传于直接相机拍摄 支持多种类型的证件制作如,职业证件,公务员证件,身份证等各种类型 支持电子照存档等等 ...

  8. Keil MDK又来了一个小升级

    关注.星标公众号,不错过精彩内容 素材来源:Arm Keil 编辑整理:strongerHuang Keil MDK升级离上次(Keil MDK 5.30来了)时间不远,这次只是进行了一次小升级. 其 ...

  9. t460p和t470p对比评测_老模具小升级 ThinkPad T470p商务本评测

    老模具小升级 ThinkPad T470p商务本评测 2017年03月29日 05:35作者:孙斌编辑:孙斌文章出处:泡泡网原创 分享 ThinkPad品牌的商务本中,T系列无疑是元老级的存在.主打性 ...

最新文章

  1. Servlet -- 重定向
  2. 设计模式C++实现(3)——适配器模式
  3. mongodb基础知识_3
  4. 肝!分享 2 本高质量算法书籍!
  5. php查询字段的总和,ThinkPHP 多表查询-如其字段A相同,则把字段B相加
  6. 在Word中插入条形码又一法
  7. JS调用打印机打印Web页面
  8. 大数据聚类分析用于预测_多模态数据中的非负矩阵分解用于分割和标签预测
  9. Java数据结构——代码实现顺序表的操作
  10. 《信息学奥赛一本通·初赛真题解析》
  11. 接口测试用例设计思路_学习接口测试,你需要知道这些!
  12. 如何快速入门Spring Cloud
  13. 【Fuzzy】不确定规划:模糊变量
  14. 好喝的阿拉伯咖啡Gahwa
  15. 什么不能吃——总结版来了!
  16. eclipse 不自动弹出提示(alt+/快捷键失效) 快捷键
  17. 打造全栈安全防护体系,华为云等保合规解决方案帮企业30天过等保
  18. Wormhole资产跨链项目代码解析
  19. cobbler一键装机流程
  20. 如何长高青春期后 - 两个简单而成功的方法

热门文章

  1. KDD 2021 | 一种使用真负样本的在线延迟反馈建模
  2. java char 打印_Java中char[]输出不是内存地址的原因详解
  3. Python游戏开发--外星人入侵(源代码)
  4. 树莓派的linux系统安装,树莓派安装Linux操作系统
  5. Codeblocks无法输出中文和中文乱码解决方法(亲测可用)
  6. 动态规划经典算法--最大子段和
  7. 51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子
  8. Ubuntu14.04下使用apt-get命令傻瓜式安装ffmepg成功
  9. ARM7寄存器分布图
  10. IP3 三阶交调截取点测试(转帖)