自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(150)
  • 资源 (2)
  • 收藏
  • 关注

原创 分布式事务方案

分布式事务的实现方式主要包括XA协议的二阶提交(2PC)、三阶提交(3PC)和TCC补偿性事务。XA协议由X/Open组织提出,规范了事务管理器(TM)与资源管理器(RM)之间的通信,确保事务的ACID特性。2PC通过准备和提交两个阶段实现事务,但存在阻塞和数据不一致的问题。3PC在2PC基础上增加预处理阶段和超时机制,以减少阻塞,但仍无法完全解决网络故障导致的数据不一致。TCC通过Try、Confirm、Cancel三个阶段实现最终一致性,适用于微服务架构,但对业务侵入性大。Seata是阿里开源的分布式事

2025-05-20 16:47:08 521

原创 深入了解Synchronized同步锁的优化

在并发编程中,Java通过Synchronized关键字和Lock接口实现线程同步,确保共享资源的原子性。Synchronized是JVM内置锁,而Lock需要显式管理锁的获取和释放。JDK1.5之前,Synchronized因依赖操作系统MutexLock导致性能开销大,尤其在锁竞争激烈时表现不佳。JDK1.6对Synchronized进行了优化,引入了偏向锁、轻量级锁和重量级锁等概念,通过锁升级机制减少上下文切换,提升性能。此外,JIT编译器通过逃逸分析和锁粗化技术进一步优化锁的使用。减小锁粒度,如Co

2025-05-20 16:46:21 947

原创 事务消息实现分布式事务

在电商系统中,用户下单后,订单系统需要通知购物车系统删除已购商品,这一过程通常通过消息队列实现,以确保数据一致性。分布式事务在此场景中至关重要,它确保订单创建和购物车清理要么都成功,要么都失败,避免数据不一致。分布式事务的实现通常遵循ACID原则,包括原子性、一致性、隔离性和持久性。常见的分布式事务实现方法有2PC、TCC和事务消息。事务消息适用于异步更新数据且对实时性要求不高的场景。消息队列如Kafka和RocketMQ提供了事务相关功能,通过事务消息机制实现分布式事务。例如,订单系统在创建订单后发送“半

2025-05-20 16:45:27 1108

原创 队列消息模型

消息队列产品通常采用两种主要模型:队列模型和发布-订阅模型。队列模型遵循先进先出原则,适用于单一消费者场景,而发布-订阅模型允许多个消费者接收同一消息,适用于需要消息广播的场景。RabbitMQ主要使用队列模型,通过Exchange实现消息分发。RocketMQ和Kafka则采用发布-订阅模型,其中RocketMQ通过队列实现消息的有序性和并行消费,Kafka则使用分区(Partition)实现类似功能。两种模型各有优势,选择哪种模型取决于具体应用场景和需求。

2025-05-20 16:44:25 782

原创 消息队列概述

消息队列适合解决异步处理、流量控制和服务解耦等问题。异步处理能提升系统性能,流量控制可调节系统负载,服务解耦则增强系统灵活性。选择消息队列时,应考虑开源、社区活跃度、消息可靠传递、集群支持和性能等因素。常见的消息队列产品包括RabbitMQ、RocketMQ和Kafka。RabbitMQ以轻量级和灵活路由著称,但处理大量消息时性能下降;RocketMQ由阿里巴巴开发,性能高,易于扩展;Kafka最初用于日志处理,现已发展为功能全面的消息队列,兼容性极佳。每种产品各有特点,应根据具体需求选择。

2025-05-20 16:43:33 410

原创 经典排序算法

它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。

2025-05-07 15:11:37 1082

原创 括号生成-递归版

数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且括号组合。

2025-04-30 16:02:00 613

原创 爬楼梯-递归版

原始递归解法:O(2^n) 时间,O(n) 空间(调用栈)记忆化递归:O(n) 时间,O(n) 空间迭代解法:O(n) 时间,O(n) 空间空间优化迭代:O(n) 时间,O(1) 空间最优选择是空间优化迭代解法,它同时具有最佳的时间和空间复杂度。

2025-04-30 16:01:28 175

原创 搭建基于Kafka的企业级实时日志流处理平台

它是一行 Nginx 日志,只不过 Connect 组件在读取它后,会把它包装成 JSON 格式发送到 Kafka,因此,我们需要借助 Gson 来帮助我们把 JSON 串还原为 Java 对象,这就是我在代码中创建 LogLine 类的原因。从图中我们可以看到,日志先从 Web 服务器被不断地生产出来,随后被实时送入到 Kafka Connect 组件,Kafka Connect 组件对日志进行处理后,将其灌入 Kafka 的某个主题上,接着发送到 Kafka Streams 组件,进行实时分析。

2025-04-30 01:00:00 1348

原创 Kafka副本机制详解

根据 Kafka 副本机制的定义,同一个分区下的所有副本保存有相同的消息序列,这些副本分散保存在不同的 Broker 上,从而能够对抗部分 Broker 宕机带来的数据不可用。在实际生产环境中,每台 Broker 都可能保存有各个主题下不同分区的不同副本,因此,单个 Broker 上存有成百上千个副本的现象是非常正常的。

2025-04-30 00:45:00 634

原创 16个SpringBoot 扩展接口

一般情况下,Spring通过反射机制利用bean的class属性指定支线类去实例化bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在bean中提供大量的配置信息。使用场景:用户可以扩展这个类,来为要实例化的bean作一个代理,比如为该对象的所有的方法作一个拦截,在调用前后输出一行log,模仿。可以看到,该类用于执行各种驱动接口,在bean实例化之后,属性填充之后,通过执行以上红框标出的扩展接口,来获取对应容器的变量。这里重点是要关注下这个标准的触发点,这个触发点是在。

2025-04-30 00:15:00 1608

原创 消费者组消费进度监控

对于 Kafka 消费者来说,最重要的事情就是监控它们的消费进度了,或者说是监控它们消费的滞后程度。这个滞后程度有个专门的名称:消费者 Lag 或 Consumer Lag。。比方说,Kafka 生产者向某主题成功生产了 100 万条消息,你的消费者当前消费了 80 万条消息,那么我们就说你的消费者滞后了 20 万条消息,即 Lag 等于 20 万。通常来说,Lag 的单位是消息数,而且我们一般是在主题这个级别上讨论 Lag 的,但实际上,Kafka 监控 Lag 的层级是在分区上的。

2025-04-29 00:30:00 1097

原创 位移提交Committing Offsets

现在,我们假设提交位移之后的 3 秒发生了 Rebalance 操作。对于常规性、阶段性的手动提交,我们调用 commitAsync() 避免程序阻塞,而在 Consumer 要关闭前,我们调用 commitSync() 方法执行同步阻塞式的位移提交,以确保 Consumer 关闭前能够保存正确的位移数据。提交位移主要是为了表征 Consumer 的消费进度,这样当 Consumer 发生故障重启之后,就能够从 Kafka 中读取之前提交的位移值,然后从相应的位移处继续消费,从而避免整个消费过程重来一遍。

2025-04-29 00:15:00 997

原创 位移主题consumer_offsets

自动提交位移有一个显著的优点,就是省事,你不用操心位移提交的事情,就能保证消息消费不会丢失。,用户不能修改,也就是说你不能随意地向这个主题写消息,因为一旦你写入的消息不满足 Kafka 规定的格式,那么 Kafka 内部无法成功解析,就会造成 Broker 的崩溃。但是,ZooKeeper 其实并不适用于这种高频的写操作,因此,Kafka 社区自 0.8.2.x 版本开始,就在酝酿修改这种设计,并最终在新版本 Consumer 中正式推出了全新的位移管理机制,自然也包括这个新的位移主题。

2025-04-28 10:49:54 1038

原创 消费者详解

发布 / 订阅模型倒是允许消息被多个 Consumer 消费,但它的问题也是伸缩性不高,因为每个订阅者都必须要订阅主题的所有分区。举个简单的例子,假设一个 Consumer Group 订阅了 3 个主题,分别是 A、B、C,它们的分区数依次是 1、2、3,那么通常情况下,为该 Group 设置 6 个 Consumer 实例是比较理想的情形,因为它能最大限度地实现高伸缩性。Consumer Group 订阅了多个主题后,组内的每个实例不要求一定要订阅主题的所有分区,它只会消费部分分区中的消息。

2025-04-28 10:49:18 277

原创 幂等生产者和事务生产者

在 0.11 之后,指定 Producer 幂等性的方法很简单,仅需要设置一个参数即可,即 props.put(“enable.idempotence”, ture),或props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true)。其次,它只能实现单会话上的幂等性,不能实现跨会话的幂等性。看上去,幂等性 Producer 的功能很酷,使用起来也很简单,仅仅设置一个参数就能保证消息不重复了,但实际上,我们必须要了解幂等性 Producer 的作用范围。

2025-04-28 10:48:42 579

原创 Kafka术语

2025-04-28 10:48:16 120

原创 透视HTTP

看上去好像很多,但互联网的快速发展让地址的分配管理很快就“捉襟见肘”。因为IP协议定义了“IP地址”的概念,所以就可以在“链接层”的基础上,用IP地址取代MAC地址,把许许多多的局域网、广域网连接成一个虚拟的巨大网络,在这个网络里找设备时只要把IP地址再“翻译”成MAC地址就可以了。URI另一个更常用的表现形式是URL(Uniform Resource Locator),统一资源定位符,也就是我们俗称的“网址”,它实际上是URI的一个子集,不过因为这两者几乎是相同的,差异不大,所以通常不会做严格的区分。

2025-04-28 10:46:02 795

原创 MySQL 日志:undo log、redo log、binlog

具体更新一条记录 UPDATE t_user SET name = "xiaolin" WHERE id =1 的流程如下:1.执行器负责具体执行,会调用存储引擎的接口,通过主键索引树搜索获取 id=1这一行记录如果 id=1这一行所在的数据页本来就在 buffer pool 中,就直接返回给执行器更新;如果记录不在 buffer pool,将数据页从磁盘读入到 buffer pool,返回记录给执行器如果一样的话就不进行后续更新流程;

2025-04-15 14:38:25 773

原创 如何制造出死锁

两个事务即使生成的间隙锁的范围是一样的,也不会发生冲突,因为间隙锁目的是为了防止其他事务插入数据,因此间隙锁与间隙锁之间是相互兼容的。在执行插入语句时,如果插入的记录在其他事务持有间隙锁范围内,插入语句就会被阻塞,因为插入语句在碰到间隙锁时,会生成一个插入意向锁,然后插入意向锁和间隙锁之间是互斥的关系。

2025-04-15 14:37:51 764

原创 MySQL是怎么加锁的

当查询的记录是「存在」的,在索引树上定位到这一条记录后,将该记录的索引中的 next-key lock 会退化成「记录锁」。当查询的记录是「不存在!的,在索引树找到第一条大于该查询记录的记录后,将该记录的索引中的next-key lock 会退化成「间隙锁」当查询的记录「存在」时,由于不是唯一索引,所以肯定存在索引值相同的记录,于是非唯一索引等值查询的过程是一个扫描的过程,直到扫描到第一个不符合条件的二级索引记录就停止扫描,然后在扫描的过程中,

2025-04-15 14:36:52 907

原创 MySQL事务及锁分类

MySQL事务及锁分类

2025-04-15 14:36:11 789

原创 了解Mysql索引

虽然在符合 a>= 1 条件的二级索引记录的范围里,b 字段的值是「无序」的,但是对于符合 a = 1 的二级索引记录的范围里,b 字段的值是「有序」的(因为对于联合索引,是先按照 a 字段的值排序,然后在 a字段的值相同的情况下,再按照 b 字段的值进行排序)。,由于每次插入主键的索引值都是随机的,因此每次插入新的数据时,就可能会插入到现有数据页中间的某个位置,这将不得不移动其它数据来满足新数据的插入,甚至需要从一个页面复制数据到另外一个页面,我们通常将这种情况称为。

2025-04-15 14:35:39 780

原创 自定义参数校验

有些时候 JSR303 标准中提供的校验规则不满足复杂的业务需求,也可以自定义校验规则。自定义注解类,定义错误信息和一些其他需要的内容注解校验器,定义判定规则//自定义注解类/*** 是否允许为空*//*** 校验不通过返回的提示信息*/String message() default "不是一个手机号码格式";/*** Constraint要求的属性,用于分组校验和扩展,留空就好*/Class<?Class<?//注解校验器// 验证手机号/**

2025-04-15 14:35:05 261

原创 使用Python ORM框架来操作MySQL

Python 还有另一种方式可以与 MySQL 进行交互,这种方式采用的是 ORM 框架。

2025-04-15 14:34:16 1092

原创 用Python操作MySQL

我在下图中列出了 DB API 规范的作用,这个规范给我们提供了数据库对象连接、对象交互和异常处理的方式,为各种 DBMS 提供了统一的访问接口。需要说明的是,我们在使用 SQL 语句的时候,可以向 SQL 语句传递参数,这时 SQL 语句里要统一用(%s)进行占位,否则就会报错。今天我讲解的是 mysql-connector,它是 MySQL 官方提供的驱动器,用来给后端语言,比如 Python 提供连接。在安装之后,你可以创建数据库连接,然后查看下数据库的版本号,来验证下数据库是否连接成功。

2025-04-15 14:33:36 370

原创 Java 泛型详解

Java 泛型通过参数化类型提高了代码的复用性和类型安全性。泛型类、泛型接口、泛型方法和通配符泛型是 Java 泛型的四种主要形式。理解泛型的原理和使用方法,可以帮助我们编写更高效、更安全的代码。Java 泛型是 Java 5 引入的一项重要特性,它允许在定义类、接口和方法时使用类型参数,从而提高代码的复用性和类型安全性。泛型类是在类定义时使用类型参数的类。类型参数可以在类的成员变量、方法参数和返回值中使用。泛型方法是在方法定义时使用类型参数的方法。泛型接口是在接口定义时使用类型参数的接口。

2025-04-15 14:31:32 1161

原创 Java遍历树(深度优先+广度优先)

在编程生活中,我们总会遇见树性结构,这几天刚好需要对树形结构操作,就记录下自己的操作方式以及过程。现在假设有一颗这样树,(是不是二叉树都没关系,原理都是一样的)

2025-03-24 09:28:25 604

原创 了解红黑树

但 Java 实现的红黑树将使用 null 来代表空节点,因此遍历红黑树时将看不到黑色的叶子节点,反而看到每个叶子节点都是红色的。因此若给定黑色节点的个数 N,最短路径的情况是连续的 N 个黑色,树的高度为 N - 1;x 节点的左旋就是把 x 变成 右孩子 y 的左孩子,同时把 y 的左孩子送给 x 当右子树。y 节点的右旋就是把 y 变成 左孩子 x 的右孩子,同时把 x 的右孩子送给 x 当左子树。性质 4 的意思是:从每个根到节点的路径上不会有两个连续的红色节点,但黑色节点是可以连续的。

2025-03-24 09:28:07 126

原创 数据结构回顾:B、B-、B+、B*-Tree

B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3;

2025-03-24 09:27:47 677

原创 CMS垃圾回收

1.7中存在永久代,1.8中没有永久代,替换它的是元空间,元空间所占的内存不是在虚拟机内部,⽽是本地内存空间,这么做的原因是,不管是永久代还是元空间,他们都是⽅法区的具体实现,之所以元空间所占的内存改成本地内存,官⽅的说法是为了和JRockit统⼀,不过额外还有⼀些原因,⽐如⽅法区所存储的类信息通常是⽐较难确定的,所以对于⽅法区的⼤⼩是⽐较难指定的,太⼩了容易出现⽅法区溢出,太⼤了⼜会占⽤了太多虚拟机的内存空间,⽽转移到本地内存后则不会影响虚拟机所占⽤的内存。所有新生成的对象首先都是放在年轻代的。

2025-03-24 09:27:20 478

原创 详解slf4j、log4j、logback、log4j2

笼统的讲就是slf4j是一系列的日志接口,而log4j logback是具体实现了的日志框架。接下来我们跟着官方文档详细的来看一下他们的关系。官方文档的这一段话已经明确描述了三者的关系。slf4j译为简单日志门面,是日志框架的抽象。而log4j和logback是众多日志框架中的几种这里写了几行简单的代码来验证一下。从运行结果可以看到,由于没有给出具体的logger实现,无法在控制台输出日志。也就是说我们在具体开发中,需要绑定一个日志框架,才能正常的使用slf4j。

2025-03-24 09:26:27 549

原创 aop的循环依赖bean加载过程

2、实例化对象之前调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation(实例化对象前的回调方法),如果此时代理了,直接返回代理对象。4、处理MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition,此时处理依赖注入的属性,找到放到beanDefinition中,留后面属性设置的时候处理。6.6按照上面1、2、3、4、5、6走过来。

2025-03-24 09:25:42 1397

原创 如何使用DDD设计微服务代码模型

如果领域服务内的业务逻辑相对复杂,我建议你将一个领域服务设计为一个领域服务类,避免由于所有领域服务代码都放在一个领域服务类中,而出现代码臃肿的问题。这里提示一下:虽然应用层和领域层都可以进行事件的发布和处理,但为了实现事件的统一管理,我建议你将微服务内所有事件的发布和订阅的处理都统一放到应用层,事件相关的核心业务逻辑实现放在领域层。它主要存放领域层核心业务逻辑相关的代码。它主要存放基础资源服务相关的代码,为其它各层提供的通用技术能力、三方软件包、数据库服务、配置和基础资源服务的代码都会放在这一层目录里。

2025-03-24 00:15:00 1008

原创 聚合和聚合根

在领域驱动设计(DDD)中,聚合和聚合根是核心概念,它们帮助我们更好地组织和管理领域模型中的实体和值对象。本文将深入探讨聚合和聚合根的概念、作用以及如何在实际开发中设计它们。聚合是一组相关联的对象的集合,它们作为一个整体被对待。在领域模型中,这些对象包括实体和值对象。聚合的边界明确了哪些对象属于同一个聚合,哪些不属于。例如,在电商系统中,一个订单(Order)和它的订单项(OrderItem)可以组成一个聚合,因为它们在业务上紧密相关,通常一起被创建、修改和删除。聚合根是聚合的入口点,它是聚合中唯一的全局可

2025-03-23 00:15:00 308

原创 DDD分层架构

微服务架构模型有好多种,例如整洁架构、CQRS 和六边形架构等等。每种架构模式虽然提出的时代和背景不同,但其核心理念都是为了设计出“高内聚低耦合”的架构,轻松实现架构演进。而 DDD 分层架构的出现,使架构边界变得越来越清晰,它在微服务架构模型中,占有非常重要的位置。那 DDD 分层架构到底长什么样?DDD 分层架构如何推动架构演进?我们该怎么转向 DDD 分层架构?这就是我们这一讲重点要解决的问题。DDD 的分层架构在不断发展。最早是传统的四层架构;后来四层架构有了进一步的优化,实现了各层对基础层的解耦;

2025-03-23 00:15:00 682

原创 实体和值对象

实体与值对象的选择,本质是业务语义与技术实现的权衡实体守护业务核心,承载复杂逻辑与生命周期;值对象提升内聚性,简化设计与数据存储。领域驱动:从业务需求出发,而非数据库范式。上下文隔离:同一对象在不同上下文中可灵活切换角色。演进式设计:随着业务变化,允许模型迭代优化。最终目标是通过清晰的领域模型,构建高响应力、易维护的系统,让技术真正服务于业务价值。

2025-03-22 01:15:00 885

原创 限界上下文

限界上下文不是简单的技术划分工具,而是业务语义的守护者与团队协作的催化剂。业务复杂度可控:将庞杂系统分解为高内聚、低耦合的单元;技术架构敏捷响应:支持快速迭代与局部技术升级;组织效能提升:减少跨团队沟通摩擦,加速价值交付。

2025-03-22 00:15:00 1289

原创 Java8中时间日期库的20个常用使用示例

在Java 8之前,时间日期的格式化可是个技术活,我们的好伙伴SimpleDateFormat并不是线程安全的,而如果用作本地变量来格式化的话又显得有些笨重。多亏了线程本地变量,这使得它在多线程环境下也算有了用武之地,但Java维持这一状态也有很长一段时间了。这次它引入了一个全新的线程安全的日期与时间格式器。它还自带了一些预定义好的格式器,包含了常用的日期格式。比如说,本例 中我们就用了预定义的BASICISODATE格式,它会将2014年2月14日格式化成20140114。

2025-03-21 15:59:54 845

原创 bean的生命周期

Spring 容器首先会加载 Bean 的定义信息()。这些定义信息可以通过以下方式加载:加载的 Bean 定义信息会被注册到 中,具体实现类是 。每个 Bean 的定义信息包括:Spring 容器根据 实例化 Bean。实例化的过程包括:在 Bean 实例化后,Spring 容器会通过依赖注入(DI)填充 Bean 的属性。依赖注入的方式包括:如果 Bean 实现了 Spring 的 接口(如 、、),Spring 容器会调用相应的回调方法,将相关的上下文信息注入到 Bean 中。在 Bean 初始

2025-03-21 15:58:54 1236

es数据迁移工具esm

es数据迁移工具esm

2024-10-16

grovvy Reference zk

敏捷开发,grovvy语言,zk框架,grails 开发

2014-03-17

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除