- 博客(86)
- 收藏
- 关注
原创 分库分表的 9种分布式主键ID 生成方案,挺全乎的
利用SPI全称() 机制拓展主键生成规则,这是一种服务发现机制,通过扫描项目路径下的文件,并自动加载文件里所定义的类。实现自定义主键生成器其实比较简单,只有两步。第一步,实现接口,并重写其内部方法,其中getType()方法为自定义的主键生产方案类型、方法则是具体生成主键的规则。下面代码中用来模拟实现一个有序自增的 ID 生成。/*** @Description: 自定义主键生成器*/@Component/*** 自定义的生成方案类型*/@Override/**
2025-04-02 14:03:31
632
原创 聊聊spring事务失效的12种场景,太坑了
对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了。在某些业务场景下,如果一个请求中,需要同时写入多张表的数据。为了保证操作的原子性(要么同时成功,要么同时失败),避免数据不一致的情况,我们一般都会用到spring事务。,就能轻松搞定事务。我猜大部分小伙伴也是这样用的,而且一直用一直爽。但如果你使用不当,它也会坑你于无形。今天我们就一起聊聊,事务失效的一些场景,说不定你已经中招了。不信,让我们一起看看。
2025-04-02 14:02:49
621
原创 分库分表, 用图来说明清晰多了
分库分表是在海量数据下,由于单库、表数据量过大,导致数据库性能持续下降的问题,演变出的技术方案。分库分表是由分库和分表这两个独立概念组成的,只不过通常分库与分表的操作会同时进行,以至于我们习惯性的将它们合在一起叫做分库分表。通过一定的规则,将原本数据量大的数据库拆分成多个单独的数据库,将原本数据量大的表拆分成若干个数据表,使得单一的库、表性能达到最优的效果(响应速度快),以此提升整体数据库性能。预定义算法是事先已经明确知道分库和分表的数量,可以直接将某类数据路由到指定库或表中,查询的时候亦是如此。
2025-04-01 15:21:54
962
原创 Redis 分布式锁的正确实现原理演化历程与 Redisson 实战总结
红锁是不是这个?泡面吃多了你,Redlock红锁是为了解决主从架构中当出现主从切换导致多个客户端持有同一个锁而提出的一种算法。大家可以看官方文档(https://redis.io/topics/distlock),以下来自官方文档的翻译。想用使用 Redlock,官方建议在不同机器上部署 5 个 Redis 主节点,节点都是完全独立,也不使用主从复制,使用多个节点是为容错。一个客户端要获取锁有 5 个步骤客户端获取当前时间T1(毫秒级别);使用相同的key和value顺序尝试从N个Redis。
2025-04-01 15:19:34
789
原创 企业级支付状态机设计与落地方案!
1.状态机设计列出核心状态(CREATED、PENDING、SUCCESS、FAIL、REFUNDING、REFUNDED、CLOSED 等)和对应事件;明确当前状态 + 事件 -> 下一个状态的规则,保证每次状态变更都有明确触发。2.状态变更记录表建议使用多条记录的方式保存状态流转历史,每次变更都插入一条;表中至少包含订单标识、原状态、新状态、触发事件、操作人、时间、备注等核心字段;方便后续审计、问题排查与统计分析。3.关键落地点确保幂等与异常场景处理;考虑部分退款多次退款等业务需求;
2025-04-01 15:12:26
944
原创 SpringBoot + minio实现分片上传、秒传、续传
MinIO是一个基于Go实现的高性能、兼容S3协议的对象存储。它采用GNU AGPL v3开源协议,项目地址是https://github.com/minio/minio。引用官网:MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储。它与Amazon S3云存储服务兼容。使用MinIO构建用于机器学习,分析和应用程序数据工作负载的高性能基础架构。官网地址:文档地址:
2025-03-31 14:06:57
311
原创 从3s到25ms!看看人家的接口优化技巧,确实很优雅!!
关于锁粒度:就是你要锁的范围有多大,不管是 synchronized 还是 redis 分布式锁,只需要在临界资源处加锁即可,不涉及共享资源的,不必要加锁,就好比你要上卫生间,只需要把卫生间的门锁上就可以,不需要把客厅的门也锁上。我们都用过数据库连接池,线程池等,这就是池思想的体现,它们解决的问题就是避免重复创建对象或创建连接,可以重复利用,避免不必要的损耗,毕竟创建销毁也会占用时间。也就是预取思想,就是提前要把查询的数据,提前计算好,放入缓存或者表中的某个字段,用的时候会大幅提高接口性能。
2025-03-31 14:06:23
266
原创 Maven官宣:干掉Maven和Gradle,更强更快更牛逼的新一代构建工具来了!
在一筹莫展之际,笔者从maven-mvnd的最新版本的更新说明上发现一个Closed issues:Different java versions for mvnd and maven #512,在该问题上作者提供了一种解决方案就是将JAVA_HOME所指定的版本设置为JDK11,并且在运行mvnd命令时加上参数-Dmaven.compiler.release=8,即。与Maven相比,JIT编译花费的时间更少。而在笔者本机的实测中,与传统的Maven相比,通过mvnd的构建所耗费的时间是原来的1/2。
2025-03-31 14:05:41
398
原创 一次订单系统重构实践
总结在整个重构过程中的几个关键步骤分析目前系统的问题点,找到最重要最优先要突破的点确定重构所要达成的目标、方向及限制条件确定重构涉及到的核心技术方案及可行性梳理重构所涉及到的需求、场景及相关上下游依赖方设计明确和完善的技术方案制定详细的项目计划,锁定资源和里程碑节点并推进全流程的测试验证详细完备的上线计划不可或缺的灰度验证系统重构是一件耗时耗力的工作,但同时也是对自身综合能力的一个巨大挑战和锻炼,期间会遇到各种各样新的问题。
2025-03-28 14:17:43
690
原创 如何从0-1的建设云上稳定性?
一、系统架构整个系统包含了私有云和公有云两个节点。前端和服务端存在私有云和公有云两套系统交互,公有云上的系统为三方黑盒系统。带着上面的五点风险和挑战,我们从前后端的视角整体制定优化策略和方案。二、前端策略作为钉钉的合作产品,必然也是需要保障钉钉的体验的,这就涉及到如何将三方前端子页面进行一方化了,我们考虑了以下几套方案。基于稳定性优先的原则,为了能够使得三方预订页面具备可监控、可灰度、可回滚的能力,我们采用方案二:前端微应用的方式进行接入。
2025-03-28 14:12:06
832
原创 「查缺补漏」巩固你的 RabbitMQ 知识体系
消息重复消费是各个MQ都会发生的常见问题之一,在一些比较敏感的场景下,重复消费会造成比较严重的后果,比如重复扣款等。消息重复消费的场景大概可以分为 生产者端重复消费 和 消费者端重复消费,解决办法是是通过幂等性来保证重复消费的消息不对结果产生影响即可。消息生成时 RabbitMQ 内部 对每个生产的消息生成个 inner-msg-id,作为去重和幂等的依据(消息投递失败并重传),避免重复的消息进入队列。
2025-03-28 14:11:06
994
原创 小白也能看得懂!日志审计插件从入门到实战
因篇幅有限,仅展示部分关键字段@Data@ToString/*** 日志标题*//*** 服务器地址*//*** 服务器名字*//*** 客户端地址*//*** 请求地址*//*** 请求参数*//*** 方法名*/终于,我们已经了解了所有的组件以及它们对应的“职责”,那么,切面就是最后将把他们组合起来,实现最终日志逻辑的大 Boss。通过注解切点,我们把相关的切面逻辑织入进去。
2025-03-27 15:47:48
404
原创 在高并发场景下,送你这三根救命毫毛
以商品详情页服务为例,这个服务在电商系统中非常关键,它需要从多个依赖服务中获取数据,如商品描述服务、商品价格服务、商品评论服务等。在高流量事件中,如大型促销活动或购物季等,服务器可能会面临极大的压力。通过上面的示例,我们可以将这种策略应用到所有的服务调用中,以保证即使在某个服务发生故障时,也能向用户提供最基本的服务,从而提高系统的整体可用性和用户的体验。通过上述配置,当用户对商品详情页的访问频率超过每秒5次时,额外的请求将被限流策略拦截,从而保护了背后的商品详情服务不会因为过高的访问频率而过载。
2025-03-27 15:47:09
380
原创 Redis批量查询的四种技巧,应对高并发场景的利器!
简单直接,适用于批量获取字符串值的场景。适用于批量获取哈希表中的字段值,可以在一个命令中获取多个字段。最小化网络开销,一次性发送多个不同的命令,管道中的命令按照执行顺序依次执行,减少往返时间。高并发场景下,可以显著提高性能。使用 Lua 脚本的好处 :减少网络开销。将多个请求通过脚本的形式一次发送,减少网络时延。原子操作。Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。复用。客户端发送的脚本会永久存在 Redis 中,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑。
2025-03-26 14:33:57
712
原创 Kafka 4.0 发布:KRaft 替代 Zookeeper、新一代重平衡协议、点对点消息模型、移除旧协议 API
Kafka 4.0 通过彻底摆脱 ZooKeeper,全面采用 KRaft 模式,不仅简化了部署和维护工作,还显著提升了系统的性能和稳定性。同时,新一代消费者重平衡协议和队列功能的引入,为开发者提供了更为灵活和高效的消息处理模式。这些架构革新使得 Kafka 4.0 成为了一个更加独立、高效和易用的分布式消息系统,为未来的发展奠定了坚实的基础。
2025-03-26 14:25:24
877
原创 四种方案讲清楚,数据权限该如何设计?
在数字化系统的权限架构演进中,用户、角色、菜单始终构成权限管理的三位一体基础框架。随着企业治理进入精细化阶段,传统RBAC模型在应对多维数据管控需求时日益显现其局限性。基于此,"功能权限-数据权限-审批权限"的三元权限体系逐渐成为行业最佳实践,其中数据权限因其与业务场景的高度耦合性,成为系统架构设计中的关键突破点。本文将系统解构四种典型数据权限实现方案,揭示灵活高效的数据权限建模方法论。
2025-03-26 14:24:33
724
原创 Kafka 4.0 发布,彻底移除 ZooKeeper!
在 KRaft 模式下,Kafka 消除了对 ZooKeeper 的依赖,控制面板功能完全集成到 Kafka 内部。这些配置在 ZooKeeper 模式下使用,用来定义和备份密码,这个密钥用于加密加密敏感数据(如密码)。Kafka 4.0 默认允许在 KRaft 模式下,大大简化了集群的部署和管理,消除了集成 ZooKeeper 的复杂性。在 KRaft 模式下,一些配置、指标和功能发生了不小的变化,今天我们来看一下都有哪些改变。在 KRaft 模式下,要修改这些配置,就需要重启 Broker。
2025-03-25 15:36:57
490
原创 38 张图详解 Redis:核心架构、发布订阅机制、9大数据类型底层原理、RDB和AOF 持久化、高可用架构、性能问题排查和调优
比如,member 存储 “女神 ID”,score 是该女神的经纬度信息。v 是键值对的 value 值,是个 union(联合体),当它的值是 uint64_t、int64_t 或 double 数字类型时,就不再需要额外的存储,这有利于减少内存碎片。Java 的 HashSet 底层是用 HashMap 实现,Sets 的底层数据结构也是用 Hashtable(散列表)实现,散列表的 key 存的是 Sets 集合元素的 value,散列表的 value 则指向 NULL。香肌如雪,罗裳慢解春光泄。
2025-03-25 15:17:35
628
原创 面试官:10亿数据如何最快速插入MySQL
但如果是HDD的话,虽然顺序读写会有非常高的表现,但HDD无法应对并发写入,例如每个库10张表,假设10张表在并发写入,每张表虽然是顺序写入,由于多个表的存储位置不同,HDD只有1个磁头,不支持并发写,只能重新寻道,耗时将大大增加,失去顺序读写的高性能。回到SSD的场景,不同SSD厂商的写入能力不同,对于并发写入的能力也不同,有的支持500M/s,有的支持1G/s读写,有的支持8个并发,有的支持4个并发。使用主节点轮训任务,可以减少任务的争抢,通过kafka发布消息,接收到消息的进程处理任务。
2025-03-25 15:16:34
542
原创 SpringBoot接口防抖(防重复提交)的一些实现方案
在Web系统中,表单提交是一个非常常见的功能,如果不加控制,容易因为用户的误操作或网络延迟导致同一请求被发送多次,进而生成重复的数据记录。key分隔符是用来将多个参数合并在一起的,比如userName是张三,userPhone是123456,那么完整的key就是"张三&123456",最后再加上redis锁前缀,就组成了一个唯一key。从测试的结果上看,防抖是做到了,但是随着缓存消失、锁失效,还是可以发起同样的请求,所以要真正做到接口幂等性,还需要业务代码的判断、设置数据库表的UK索引等操作。
2025-03-24 13:39:31
269
原创 字节一面:POST 为什么会发送两次请求?
最近博主在字节面试中遇到这样一个面试题,这个问题也是前端面试的高频问题,因为在前端开发的日常开发中我们总是会与post请求打交道,一个小小的post请求也是牵扯到很多知识点的,博主在这给大家细细道来。同源策略是一个重要的安全策略,它用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。如果你近期准备面试跳槽,建议在ddkk.com在线刷题,涵盖 一万+ 道 Java 面试题,几乎覆盖了所有主流技术面试题,还有市面上最全的技术五百套,精品系列教程,免费提供。
2025-03-24 13:38:29
986
原创 Spring Boot 一个接口实现任意表的 Excel 导入导出
Java的web开发需要excel的导入导出工具,所以需要一定的工具类实现,如果是使用easypoi、Hutool导入导出excel,会非常的损耗内存,因此可以尝试使用easyexcel解决大数据量的数据的导入导出,且可以通过Java8的函数式编程解决该问题。这种方式可以通过把表中的字段顺序存储起来,通过配置数据和字段的位置实现数据的新增,那么如果出现了导出数据模板/手写excel的时候顺序和导入的时候顺序不一样怎么办?那么这些问题都解决了,如果出现大数据量的情况,如果要极大的使用到cpu,该怎么做呢?
2025-03-24 13:37:08
547
原创 面试官:详细说说你对序列化的理解
前面引入游戏的例子是为了让大家生动地理解什么是序列化和反序列化。序列化是指将对象实例的状态存到存储媒体的过程反序列化是指将存储在存储媒体中的对象状态装换成对象的过程把对象转化为可传输的字节序列过程反序列化:把字节序列还原为对象的过程。
2025-03-23 14:56:56
828
原创 10 张图搞懂服务注册发现机制
在单体架构中一个应用程序就是一个服务包,包内的模块通过函数方法相互调用,模型足够简单,根本没有服务注册和发现一说。在微服务架构中会将一个应用程序拆分为多个微服务,微服务会部署在不同的服务器、不同的容器、甚至多数据中心,微服务间要相互调用,服务注册和发现成为了一个不可或缺的组件。
2025-03-23 14:56:22
624
原创 Redis 突然变慢了如何排查并解决?
如下检查清单,帮助你在遇到 Redis 性能变慢的时候能高效解决问题。获取当前 Redis 的基线性能;开启慢指令监控,定位慢指令导致的问题;找到慢指令,使用 scan 的方式;将实例的数据大小控制在 2-4GB,避免主从复制加载过大 RDB 文件而阻塞;禁用内存大页,采用了内存大页,生成 RDB 期间,即使客户端修改的数据只有 50B 的数据,Redis 需要复制 2MB 的大页。当写的指令比较多的时候就会导致大量的拷贝,导致性能变慢。Redis 使用的内存是否过大导致 swap;
2025-03-23 14:31:58
612
原创 Spring计时器StopWatch使用
该种方法通过获取执行完成时间与执行开始时间的差值得到程序的执行时间,简单直接有效,但想必写多了也是比较烦人的,尤其是碰到不可描述的代码时,会更加的让人忍不住多写几个 bug 聊表敬意,而且该结果也不够直观,此时会想是否有一个工具类,提供了这些方法,或者自己写个工具类,刚好可以满足这种场景,并且把结果更加直观的展现出来。属性,从而使该类可记录多个任务,最后的输出也仅仅是对之前记录的信息做了一个统一的归纳输出,从而使结果更加直观的展示出来。统一归纳,展示每项任务耗时与占用总时间的百分比,展示结果直观;
2025-03-21 15:17:29
331
原创 Spring是如何支持多数据源的
原因:声明式事务事务的本质也是 AOP,其只对开启时使用的数据源生效,所以一定要在切换到指定数据源之后再开启,声明式事务默认的优先级是最低级,这里只需要设定自定义的数据源切面的优先级比它高即可。样例中为了减少代码层级,让展示更直观,在 controller 层写了事务注解,实际开发中可别这么干,controller 层的任务是绑定、校验参数,封装返回结果,尽量不要在里面写业务!方法,该方法是抽象方法,由用户自己实现,通过改变其返回值,控制返回不同的数据源。,决定使用哪个目标数据源,并使用该数据源的。
2025-03-21 15:16:58
401
原创 Spring 声明式事务应该怎么学?
认真读完本文,相信你会对声明式事务有更深刻的认识。小结:本小节介绍了 3 种常见的Spring 声明式事务传播属性,结合样例代码,相信你也对其有所了解了,接下来我们从源码层面看一看,Spring 是如何帮我们简化事务样板代码,解放生产力的。不同的是,其总是开启独立的事务,不会参与到已存在的事务中,这就保证了两个事务的状态相互独立,互不影响,不会因为一方的回滚而干扰到另一方。,所以挂起前面的事务(至于如何挂起,后面我们会从源码中窥见),并开启一个物理上独立于前者的新事务,这样二者的事务回滚就不会相互干扰了。
2025-03-21 15:16:07
571
原创 线程池参数的动态化原理及集成nacos实践
通过结合Spring Boot和Nacos配置中心,可以实现线程池参数的动态调整。关键点包括:使用注解支持配置的动态刷新。通过动态调整线程池参数。监听事件,实时更新线程池配置。
2025-03-20 15:36:48
532
原创 阿里云技术终面:每天 100w 次登陆请求,8G 内存该如何设置 JVM 参数?
对象进入老年代的动态年龄判断规则(动态晋升年龄计算阈值):Minor GC 时,Survivor 中年龄 1 到 N 的对象大小超过 Survivor 的 50% 时,则将大于等于年龄 N 的对象放入老年代。核心的优化策略是:是让短期存活的对象尽量都留在survivor里,不要进入老年代,这样在minor gc的时候这些对象都会被回收,不会进到老年代从而导致full gc。
2025-03-20 15:11:04
673
原创 循环中使用 Thread.sleep,代码评审被老板喷了
如果对文中示例有所了解,你会发现本质其实就是一个定时问题,每隔一段时间进行操作直至达到条件,按文中示例,便是每隔 3 秒检查标记量并做一些事情,因此我们完全可使用调度 API 进行替换。通过这种方式,线程可以等待特定条件的变化,而无需频繁轮询和消耗 CPU 资源。来避免频繁检查标记量的值,看起来非常合理对吧。任务管理:调度器自动管理任务执行,无需显式控制线程的休眠和唤醒,避免了忙等待的问题。不能捕捉任务中的异常,任务异常可能导致后续的定时任务停止。在代码上稍显复杂,尤其在简单的定时任务中,可能稍显复杂。
2025-03-20 15:10:13
525
原创 日常工作,MQ的8种常用使用场景!
在日常的Java开发工作中,消息队列(MQ)可谓是我们的得力助手。它凭借自身的诸多特性,在不同的业务场景中发挥着至关重要的作用。接下来,就让我们一同深入探讨MQ的8种常用使用场景。
2025-03-19 14:05:23
893
原创 写代码有这20个好习惯,可以减少80%非业务的bug!
在程序员的职业生涯中,每一个好习惯都是我们积累的宝贵财富。今天,我精心为大家整理了写代码的16个好习惯,这些习惯个个经典实用,倘若你能将它们融入日常的编程工作中,相信大部分非业务相关的Bug都能被我们轻松规避。希望这些内容能对大家有所帮助,废话不多说,让我们一起开启这趟好习惯之旅吧!
2025-03-19 14:04:43
775
原创 异步利器 CompletionService 真实用!
CompletionService 的应用场景还是非常多的,比如Dubbo 中的 Forking Cluster多仓库文件/镜像下载(从最近的服务中心下载后终止其他下载过程)多服务调用(天气预报服务,最先获取到的结果)CompletionService 不但能满足获取最快结果,还能起到一定 "load balancer" 作用,获取可用服务的结果,使用也非常简单, 只需要遵循范式即可并发系列 讲了这么多,分析源码的过程也碰到各种队列,接下来我们就看看那些让人眼花缭乱的队列。
2025-03-19 14:03:57
620
原创 服务熔断是指什么?
• 服务熔断是一种软件设计模式,用于分布式系统中处理服务调用失败的情况,可以防止被调用服务因为频繁失败被压垮。它借鉴了电路中的断路器原理,通过监控服务调用的失败率等条件来决定是否阻止进一步的调用,以保护系统免受过载。关闭(Closed)半开(HalfOpen)和打开(Open),分别对应不同的保护策略。当服务调用失败次数超过阈值时,熔断器打开,阻止服务调用。在一定时间后,熔断器尝试半开状态,允许少量请求通过以测试服务恢复情况。如果服务恢复,熔断器关闭;如果失败,熔断器保持打开状态。
2025-03-14 17:26:18
915
原创 docker 和传统虚拟机有什么区别?
好了,如果你觉得这期文章对你有帮助,记得转发给你那不成器的兄弟。最后遗留一个问题, docker 大概是什么你是了解了,那你知道它的内部架构吗?如果你感兴趣,记得关注。我们下期见!
2025-03-14 17:25:35
903
原创 Docker 是什么? 和 k8s 之间是什么关系?
• Docker 本质上就是一个将程序和环境打包并运行的工具软件,而 Docker 容器本质上只是个自带独立运行环境的特殊进程,底层用的其实是宿主机的操作系统内核。• Docker 软件 通过 Dockerfile 描述环境和应用程序的依赖关系, docker build 构建镜像, docker pull/push 跟 Docker Registry 交互实现存储和分发镜像,docker run 命令基于镜像启动容器,基于容器技术运行程序和它对应的环境,从而解决环境依赖导致的各种问题。
2025-03-14 17:24:57
572
原创 Java 性能优化的 48 个细节(珍藏版)
JVM为Vector扩充大小的时候需要重新创建一个更大的数组,将原原先数组中的内容复制过来,最后,原先的数组再被回收。可见Vector容量的扩大是一个颇费时间的事。通常,默认的10个元素大小是不够的。你最好能准确的估计你所需要的最佳大小。
2025-03-13 14:20:34
966
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人