分布式工具的一次小升级⏫
前言
之前在做 秒杀架构实践 时有提到对 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
分布式工具的一次小升级⏫相关推荐
- 分布式工具的一次小升级⏫ 1
前言 之前在做 秒杀架构实践 时有提到对 distributed-redis-tool 的一次小升级,但是没有细说. 其实主要原因是: 秒杀时我做压测:由于集成了这个限流组件,并发又比较大,所以导致连 ...
- 最强分布式工具Redisson:分布式锁
一.Redisson概述 什么是Redisson?-- Redisson Wiki Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).它 ...
- 租赁共享农机械设备工具门店扫码小程序开发
租赁共享农机械设备工具门店扫码小程序开发 支持一物一码 一物一码让您更好的监控租赁物品,扫 一扫即可知道物品当前所在,状态及其 他.而且一物一码可以让您的业务更轻 松拓展到物联网. 营销功能 支持开通 ...
- python自动翻译小工具_Python实现翻译小工具
一.背景 利用Requests模块获取有道词典web页面的post信息,BeautifulSoup来获取需要的内容,通过tkinter模块生成gui界面. 二.代码 git源码地址 Python实现翻 ...
- android开发工具哪个好_小程序开发工具怎么用?哪个好用?
想要开发微信小程序,在没有太多资金找外包团队定制.自建团队开发时,就需要你自己通过小程序开发工具来生成小程序了.现在各种开发工具很多,到底小程序开发工具有哪些?这些微信小程序开发工具哪个好用?根据我的 ...
- 实用工具证件照制作微信小程序源码
这是一款证件照制作的微信小程序,里面也支持直接微信公众号版本生成安装 支持多种尺寸制作 支持相册上传于直接相机拍摄 支持电子照存档等等 拥有小程序推荐功能,可以给其它的小程序实现引流 另外还支持换装美 ...
- 全新实用工具证件照制作微信小程序源码下载支持多种证件生成与制作
这是一款证件照制作的微信小程序,里面也支持直接微信公众号版本生成安装 支持多种尺寸制作 支持相册上传于直接相机拍摄 支持多种类型的证件制作如,职业证件,公务员证件,身份证等各种类型 支持电子照存档等等 ...
- Keil MDK又来了一个小升级
关注.星标公众号,不错过精彩内容 素材来源:Arm Keil 编辑整理:strongerHuang Keil MDK升级离上次(Keil MDK 5.30来了)时间不远,这次只是进行了一次小升级. 其 ...
- t460p和t470p对比评测_老模具小升级 ThinkPad T470p商务本评测
老模具小升级 ThinkPad T470p商务本评测 2017年03月29日 05:35作者:孙斌编辑:孙斌文章出处:泡泡网原创 分享 ThinkPad品牌的商务本中,T系列无疑是元老级的存在.主打性 ...
最新文章
- C++复制控制:拷贝构造函数
- Redis大集群扩容性能优化实践
- html.partial mvc,MVC Html.Partial or Html.Action
- (新鲜出炉)二本,两年经验,阿里P6面经
- 使用while 循环实现输出 1, 2, 3, 4, 5, 7, 8, 9, 11, 12(提示:输出结果为一行,没有6和10,12后面没有逗号)
- linux更改桌面壁纸的脚本,自动更换桌面壁纸的脚本,支持Ubuntu 18.04系统
- okhttp 连接池_okhttp 源码分析
- 保存时自动加分号_CAD自动保存文件扩展名是什么?如何快速恢复自动保存文件?...
- pythonappend教程_对python append 与浅拷贝的实例讲解
- ResNeXt - Aggregated Residual Transformations for Deep Neural Networks
- springboot项目java生成kml文件
- word操作——论文中——设置WPS奇偶页页眉内容不同和公式居中,公式的标号靠右、......
- HTML短信测压引流源码
- 倪光南:解读中国ISV生存现状
- iOS开发有关导航条坐标问题
- http协议如何获取请求参数
- 如何制作微信二维码指纹扫描图片
- 科研狗citavi/mendeley+word使用技巧外加读论文瞎琢磨
- Python实现“已知三角形两个直角边,求斜边”
- uniapp MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 upgrade listeners