开篇
-
近两个星期参与了一个比较完整的项目,项目背景在这里就不做过多介绍了,这里只是想简单总结下项目过程中涉及的一些技术方案,权当给自己之前纠结的技术和业务的方向做一个阶段性的总结。
-
在这个总结中对我个人而言既有已经技术点的回顾,又有新技术点的使用,这也是我为什么会写这篇总结的原因。
-
在这个项目中我们使用了一些中间件的技术,包括RabbimtMq、Redis、HttpClient等,这些都是日常比较常用的。
RabbitMq重试
-
这是一个大家都会遇到的问题,在一套测试环境中存在多个消费者消费同一个主题的消息,但是我们的最新消费逻辑的代码只会在其中一个消费者中部署,这就导致测试过程中无法保证消息都会被最新的代码逻辑消费到。
-
为了解决指定机器消费消息,研究了下RabbitMq的重试机制后发现可以利用重试机制来解决这个问题。通过在消费侧增加代码用来判断当前机器是否在配置中心指定消费的机器ip地址,如果不是指定机器的消费我们就直接抛出异常来让RabbitMq进行重试直到指定机器的消费。
-
整个解决方案的核心在于了解RabbitMq的重试机制并知道如何进行利用,至于增加判断代码我们使用了Interceptor,只是为了让代码显得有些逼格。
Redis的lua脚本
- 关于Redis,大家熟知内容包括Redis从3.0版本开始引入集群模式,Redis是读写处理是单线程的并且线程安全的。
- 在项目中我们用Redis来实现一个固长的队列并支持批量消费。整体解决方案是基于Redis的List数据结构和Lua脚本。
- Redis的固长队列我们使用Lua脚本,在Lua脚本中判断List的长度并且在达到长度后丢弃最早的数据并插入最新的数据,使用是LPOP和RPUSH的组合命令。
- Redis的批量消费我们使用Lua脚本,在Lua脚本中使用LRANGE和LTRIM组合命令来实现的。
- Redis 3.0是支持集群模式的,所以在一个Lua脚本当中只能针对单个key进行操作,否则会出现多个key不在一个redis槽的问题。
- Redis 3.x 和 4.x版本针对Lua脚本中对nil类型的数据处理是一致的,这部分建议查看Redis的官网的语法,Lua脚本对nil的处理是当作false。
Jedis的集群模式
- 项目中访问Redis使用的是Jedis的客户端,之前对Jedis的源码就有阅读的经验,这次刚好借项目之便又重新看了一次。
- Jedis针对Redis的集群模式的访问是通过cluster slots命令进行发现并给予发现的master节点进行连接处理的,这部分逻辑已经完成整理并准备公司内部技术投稿。
- Jedis的集群模式下的连接管理是通过apache common pools进行管理的,DBCP应该也是使用它来实现对象复用管理的,有兴趣的可以研究研究。
HttpClient的多线程问题
- 项目中通过HttpClient访问外部网站,借项目之便顺带研究了下多线程访问HttpClient的逻辑,可以减少频繁重新连接的开销。
- 整体的思路可以参考之前我写的文章HttpClient介绍和使用,针对HttpClient的连接池管理抽空再写篇文章进行分析。
网友评论