深入理解RabbitMQ中的prefetch_count参数

前提

在某一次用户标签服务中大量用到异步流程,使用了RabbitMQ进行解耦。其中,为了提高消费者的处理效率针对了不同节点任务的消费者线程数和prefetch_count参数都做了调整和测试,得到一个相对合理的组合。这里深入分析一下prefetch_count参数在RabbitMQ中的作用。

简化ETL工作,编写一个Canal胶水层

前提

这是一篇憋了很久的文章,一直想写,却又一直忘记了写。整篇文章可能会有点流水账,相对详细地介绍怎么写一个小型的"框架"。这个精悍的胶水层已经在生产环境服役超过半年,这里尝试把耦合业务的代码去掉,提炼出一个相对简洁的版本。

之前写的几篇文章里面其中一篇曾经提到过Canal解析MySQLbinlog事件后的对象如下(来源于Canal源码com.alibaba.otter.canal.protocol.FlatMessage):

如果直接对此原始对象进行解析,那么会出现很多解析模板代码,一旦有改动就会牵一发动全身,这是我们不希望发生的一件事。于是花了一点点时间写了一个Canal胶水层,让接收到的FlatMessage根据表名称直接转换为对应的DTO实例,这样能在一定程度上提升开发效率并且减少模板化代码,这个胶水层的数据流示意图如下:

要编写这样的胶水层主要用到:

  • 反射。
  • 注解。
  • 策略模式。
  • IOC容器(可选)。

项目的模块如下:

  • canal-glue-core:核心功能。
  • spring-boot-starter-canal-glue:适配SpringIOC容器,添加自动配置。
  • canal-glue-example:使用例子和基准测试。

下文会详细分析此胶水层如何实现。

Canal v1.1.4版本搭建HA集群

前提

Canal上一个正式版是于2019-9-2发布的v1.1.4,笔者几个月前把这个版本的Canal推上了生产环境,部署了HA集群。过程中虽然遇到不少的坑,但是在不出问题的前提下,Canal的作用还是非常明显的。上周的一次改造上线之后,去掉了原来对业务系统订单数据通过RabbitMQ实时推送的依赖,下游的统计服务完全通过上游业务主库的binlog事件进行聚合,从而实现了核心业务和实时统计两个不同的模块解耦。

这篇文章简单分析一下如何搭建生产环境下可靠的Canal高可用集群。

Canal v1.1.4版本避坑指南

前提

在忍耐了很久之后,忍不住爆发了,在掘金发了条沸点(下班时发的):

这是一个令人悲伤的故事,这条情感爆发的沸点好像被屏蔽了,另外小水渠(Canal意为水道、管道)上线一段时间,不出坑的时候风平浪静,一旦出坑令人想屎。重点吐槽几点:

  • 目前最新的RELEASE版本为v1.1.4,发布于2019-9-2,快一年没更新了。
  • Issue里面堆积了十分多未处理或者没有回应的问题,有不少问题的年纪比较大。
  • master分支经常提交异常的代码,构建不友好,因为v1.1.4比较多问题,也曾经想过用master代码手动构建,导入项目之后决定放弃,谁试试谁知道,可以尝试对比导入和构建MyBatis的源码。

这些都只是表象,下面聊聊踩过的坑。

SonarQube搭建手记

前提

这篇文章记录的是SonarQube服务搭建的详细过程,应用于云迁移后的PipleLine的代码扫描环节。

笔者有软件版本升级强迫症,一般喜欢使用软件的最新版本,编写此文的时候(2020-05-17SonarQube的最新版本为8.3.1

基于Quartz编写一个可复用的分布式调度任务管理WebUI组件

前提

创业小团队,无论选择任何方案,都优先考虑节省成本。关于分布式定时调度框架,成熟的候选方案有XXL-JOBEasy SchedulerLight Task SchedulerElastic Job等等,其实这些之前都在生产环境使用过。但是想要搭建高可用的分布式调度平台,这些框架(无论是否去中心化)都需要额外的服务器资源去部署中心调度管理服务实例,甚至有时候还会依赖一些中间件如Zookeeper。回想之前花过一段时间看Quartz的源码去分析它的线程模型,想到了它可以基于MySQL,通过一个不是很推荐的X锁方案(SELECT FOR UPDATE加锁)实现服务集群中单个触发器只有一个节点(加锁成功的那个节点)能够执行,这样子,就能够仅仅依赖于现有的MySQL实例资源实现分布式调度任务管理。一般来说,有关系型数据保存需求的业务应用都会有自己的MySQL实例,这样子就能几乎零成本引入一个分布式调度管理模块。某个加班的周六下午敲定了初步方案之后,花了几个小时把这个轮子造出来了,效果如下:

基于Canal和Kafka实现MySQL的Binlog近实时同步

前提

近段时间,业务系统架构基本完备,数据层面的建设比较薄弱,因为笔者目前工作重心在于搭建一个小型的数据平台。优先级比较高的一个任务就是需要近实时同步业务系统的数据(包括保存、更新或者软删除)到一个另一个数据源,持久化之前需要清洗数据并且构建一个相对合理的便于后续业务数据统计、标签系统构建等扩展功能的数据模型。基于当前团队的资源和能力,优先调研了Alibaba开源中间件Canal的使用。

这篇文章简单介绍一下如何快速地搭建一套Canal相关的组件。

初识Redis的数据类型HyperLogLog

前提

未来一段时间开发的项目或者需求会大量使用到Redis,趁着这段时间业务并不太繁忙,抽点时间预习和复习Redis的相关内容。刚好看到博客下面的UVPV统计,想到了最近看书里面提到的HyperLogLog数据类型,于是花点时间分析一下它的使用方式和使用场景(暂时不探究HyperLogLog的实现原理)。RedisHyperLogLog数据类型是Redid 2.8.9引入的,使用的时候确保Redis版本>= 2.8.9

使用Redis实现UA池

前提

最近忙于业务开发、交接和游戏,加上碰上了不定时出现的犹豫期和困惑期,荒废学业了一段时间。天冷了,要重新拾起开始下阶段的学习了。之前接触到的一些数据搜索项目,涉及到请求模拟,基于反爬需要使用随机的User Agent,于是使用Redis实现了一个十分简易的UA池。

一文彻底理解Redis序列化协议,你也可以编写Redis客户端

前提

最近学习Netty的时候想做一个基于Redis服务协议的编码解码模块,过程中顺便阅读了Redis服务序列化协议RESP,结合自己的理解对文档进行了翻译并且简单实现了RESP基于Java语言的解析。编写本文的使用使用的JDK版本为[8+]