首先了解下何为SPI,这里引用Dubbo官方对SPI的解说,比较全面。SPI简介

SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。

Dubbo本身实现了对JDK的SPI的扩展,为了能够更好的理解Dubbo的SPI机制,我们需要理解JDK的原生SPI原理。

从概念可以看出,SPI机制是一种服务发现机制,能够在运行时动态的增加、获取服务实现。个人感觉很像设计原则中的里氏替换原则。

我将通过一个实例来讲解如何对JDK的SPI进行运用。

Read More

考虑到部分业务场景下没有使用RocketMQ,因此我在之前的基础上添加了对单机模式调度的封装。

本文就单机模式下,不依赖RocketMQ如何使用shield-job进行定时任务调度展开讲解。

目前有两种主要的调用方式,客户端实现抽象调度方法 execute ,或者直接使用内置的 executeOneway 方法进行调用,接下来分别介绍两种方式。

Read More

自己写分布式调度组件继续更新,目前已经完成了一个里程碑版本。

千呼万唤始出来,却不是当初想的模样。之前立的flag太大,最终决定暂时放弃开发分布式版本,把目标改为基于消息队列RocketMQ的任务分发框架,具体的调度逻辑由调用方自行开发。

客户端接口

首先介绍客户端需要关注的接口以及实体

客户端实体–任务实体BaseJob

任务实体BaseJob为shield-job的调度核心实体,调用方的业务实体需要继承该作业抽象类,实现其中的encode() 以及 decode(String msg) 抽象方法。

Read More

在上篇中,我们了解了RocketMQ中的消息重试机制以及如何在Producer、Consumer两端对重试消息进行处理。

RocketMQ会在消息消费时,按照一定规则推送消息到消费者端进行消息重试。这里涉及到了消息幂等的概念。

首先我们了解一下什么是幂等,以及何为消息幂等。

什么是幂等

百度对 “幂等” 解释如下

设f为一由X映射至X的一元运算,则f为幂等的,当对于所有在X内的x,
f(f(x)) = f(x).
特别的是,恒等函数一定是幂等的,且任一常数函数也都是幂等的。

这里的关键是 f(f(x)) = f(x), 翻译成通俗的解释就是:

如果有一个操作,多次执行与一次执行所产生的影响是相同的,我们就称这个操作是幂等的。

关于消息幂等

基于上述的概念,结合消息消费的场景,我们能够很容易的总结出消息幂等的概念:

即:

如果消息重试多次,消费者端对该重复消息消费多次与消费一次的结果是相同的,并且多次消费没有对系统产生副作用,那么我们就称这个过程是消息幂等的。

例如:

支付场景下,消费者消费扣款消息,对一笔订单进行扣款操作,该扣款操作需要扣除10元。

这个扣款操作重复多次与执行一次的效果相同,只进行一次真实扣款,用户的扣款记录中对应该笔订单的只有一条扣款流水。不会多扣。那么我们就说这个扣款操作是符合要求的,这个消费过程是消息幂等的。

Read More

本文中,我将讲解RocketMQ使用过程中,如何进行消息重试。

首先,我们需要明确,只有当消费模式为 MessageModel.CLUSTERING(集群模式) 时,Broker才会自动进行重试,对于广播消息是不会重试的。

集群消费模式下,当消息消费失败,RocketMQ会通过消息重试机制重新投递消息,努力使该消息消费成功。

当消费者消费该重试消息后,需要返回结果给broker,告知broker消费成功(ConsumeConcurrentlyStatus.CONSUME_SUCCESS)或者需要重新消费(ConsumeConcurrentlyStatus.RECONSUME_LATER)。

这里有个问题,如果消费者业务本身故障导致某条消息一直无法消费成功,难道要一直重试下去吗?

答案是显而易见的,并不会一直重试。

事实上,对于一直无法消费成功的消息,RocketMQ会在达到最大重试次数之后,将该消息投递至死信队列。然后我们需要关注死信队列,并对该死信消息业务做人工的补偿操作。

Read More

本文是 “跟我学Sharding-JDBC” 系列的第四篇,我将带领读者一起了解下Sharding-JDBC的数据分片规则并通过实例实现自定义分片策略的开发实现。

Sharding-JDBC中的分片策略有两个维度,分别是:数据源分片策略(DatabaseShardingStrategy)、表分片策略(TableShardingStrategy)。

其中,数据源分片策略表示:数据路由到的物理目标数据源,表分片策略表示数据被路由到的目标表。

特别的,表分片策略是依赖于数据源分片策略的,也就是说要先分库再分表。

这里贴一张盗来的图

Sharding-JDBC分片策略代码架构

Read More

本文是 “跟我学Sharding-JDBC” 系列的第三篇,我将带领读者一起了解下Sharding-JDBC的分布式主键,并实现业务性更强的自定义主键。

首先了解下,什么是分布式主键。

传统的关系型数据库,如MySQL中,数据库本身自带自增主键生成机制,但在分布式环境下,由于分库分表导致数据水平拆分后无法使用单表自增主键,因此我们需要一种全局唯一id生成策略作为分布式主键。

当前业界已经有不少成熟的方案能够解决分布式主键的生成问题,如:UUID、SnoWflake算法(Twitter)、Leaf算法(美团点评)等。

Read More

“云计算”的概念从提出到现在已经过了十多年,经过了大量的实践之后早已不再是阳春白雪般不接地气的抽象理论。

随着微服务的提出到落地,分布式领域中又诞生了新的基于云的理论–“云原生(Cloud Native)”。

“云原生”的概念由来自Pivotal的Matt Stine于2013年首次提出,被一直延续使用至今……(它涵盖的)内容非常多,包括DevOps持续交付微服务敏捷基础设施以及12要素等几大主题。不但包括根据业务能力对公司进行文化、组织架构的重组与建设,也包括方法论与原则,还有具体的操作工具。 –《云原生技术架构实践》

本文,我将主要介绍云原生的12要素,并着重讲解云原生中关于微服务的主题中的容器化与应用无状态的特性。

Read More

生产上我们对数据库连接密码一般都是配置密文,从源头上尽可能地保证安全性。

本文中,我将介绍一款在Spring Boot中使用的自动加解密工具,对数据库连接密码进行加密操作。

该工具名为 jasypt-spring-boot-starter ,能够做到在Spring Boot 加载属性之前,对属性进行进行加解密操作。它使用对称加密方式进行加解密。

项目的Github为 jasypt-spring-boot, 感兴趣的可以去点个star支持下。

话不多说,进入正题。

Read More

在上文中,我们讲解了分布式环境下的分库分表,从概念及案例上分析了何为分库分表及其优缺点。

我说分布式之分库分表

从本文开始我们一起学习一下如何使用当前比较成熟的分库分表框架 Sharding-JDBC 实现分库分表。

什么是Sharding-JDBC

Sharding-JDBC是分布式数据中间件Sharding-Sphere中的重要组成部分,官方的介绍如下:

Sharding-Sphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器、云原生等各种多样化的应用场景。

Sharding-JDBC 是Sharding-Sphere的第一款产品,也是最接近开发者的一款分库分表中间件,很有代表性,也值得我们深入的学习与应用。

Sharding-JDBC官方文档地址

这里我贴出官方的文档地址,版本为3.x,有问题先看文档是比较直接快速准确的trouble-shooting方式。

如何使用Sharding-JDBC3.x 实现分库分表

简单了解一下背景之后,我们用一个案例先把它用起来,直观地感受一下Sharding-JDBC的魅力,后续我们会对它做进一步的讲解。

由于目前的后端Java开发主要以Spring Boot为主,因此我将主要依据Spring Boot的2.x进行讲解。

Read More

Fork me on GitHub