- 博客(225)
- 收藏
- 关注
原创 TreeUtil树构建工具-超好用工具
抽象方法实现:适合简单的视图对象转换,代码清晰易懂泛型实现:适合复杂的业务实体,支持更丰富的类型和数据库集成高内聚低耦合:将树构建逻辑与业务逻辑分离开闭原则:通过抽象类和泛型支持扩展性能优先:使用高效的算法处理大数据量场景在实际项目中,可以根据具体需求选择合适的实现方式。对于大多数场景,抽象方法实现已经足够;对于需要与MyBatis-Plus等ORM框架深度集成的复杂项目,建议使用泛型实现。扩展思考。
2026-01-06 10:40:39
320
原创 asynctool-京东内部的超好用工具
譬如A执行完毕后,A的监听器会收到回调,带着A的执行结果(成功、超时、异常)。根据你的需求,将各个执行单元组合完毕后,开始在主线程执行并阻塞,直到最后一个执行完毕。并且。
2026-01-05 04:30:00
757
原创 RocketMQ 核心编程模型与生产环境最佳实践
文章介绍了RocketMQ的核心编程模型和生产环境最佳实践,包括消息模型、发送与消费流程、消息确认机制、顺序消息、延迟消息、批量消息、过滤消息、事务消息和ACL权限控制。同时详细讲解了SpringBoot整合RocketMQ的实现原理和注意事项,并提供了合理分配Topic、Tag、关注错误消息重试、手动处理死信队列等最佳实践建议。
2026-01-02 15:25:29
1106
原创 RocketMQ的运行架构&理解RocketMQ的消息模型
通过之前的一系列实验,相信你对RocketMQ的运行机制有了一个大概的了解。接下来我们结合一下之前实验的过程,来理解一下RocketMQ的运行架构。下图是RocketMQ运行时的整体架构:
2026-01-01 16:26:46
714
原创 RocketMQ如何搭建分布式集群
但是很可惜,主从架构中各个服务的角色都是固定了的,slave服务虽然拥有全部的数据,但是它没办法升级成为master服务去响应客户端的请求,依然只是傻傻等待master服务重启后,继续做它的数据备份工作。但是,这种主从架构的集群却也有一个不足的地方,那就是不具备服务高可用。在RocketMQ的这种主从架构的集群下,客户端发送的消息会分散保存到broker-a和broker-b两个服务上,然后每个服务都配有slave服务,可以备份对应master服务上的消息,这样就可以防止单点故障造成的消息丢失问题。
2026-01-01 15:24:22
817
原创 高可用刷题点赞系统设计:应对800万题目的点赞挑战
高性能:所有实时读写请求命中内存,响应速度极快。高可用:Redis Cluster、消息队列等组件保障了系统整体的可用性,数据库压力得到屏蔽。可扩展:架构清晰,各层可独立水平扩展。数据可靠:通过定时任务+消息队列,确保数据最终准确持久化。这套以Redis 为盾,异步化为矛周氏总结:当用户触发登录时,触发事件监测@EventListener去重新写入缓存,写入缓存时加一个是否写入完成的key,如果没有完成则数据库读取。③每日凌晨使用使用SCAN命令避免阻塞。
2025-12-30 16:28:58
1398
原创 Kafka vs RabbitMQ vs RocketMQ:三大消息队列深度对比
优点:吞吐量极高、生态完善、适合日志与大数据场景。缺点:事务不支持、易丢数据、Topic 多时性能下降。
2025-12-28 04:00:00
1752
原创 RocketMQ简介&简易搭建
RocketMQ 是阿里巴巴开源的一个消息中间件,在阿里内部历经了双十一等很多高并发场景的考验,能够处理亿万级别的消息。2016 年开源后捐赠给 Apache,现在是 Apache 的一个顶级项目。早期阿里使用 ActiveMQ,但是,当消息开始逐渐增多后,ActiveMQ 的 IO 性能很快达到了瓶颈。于是,阿里开始关注 Kafka。但是 Kafka 是针对日志收集场景设计的,他的高级功能并不是很贴合阿里的业务场景。
2025-12-25 11:17:26
731
原创 Spring事务失效的经典场景:自调用与代理的陷阱
Spring AOP代理下的自调用问题是每个Spring开发者都可能遇到的"坑"。理解其背后的原理——代理对象只能拦截外部调用,无法拦截对象内部的方法调用——是解决问题的关键。在实际开发中,推荐采用代码重构的方案,将事务方法拆分到不同的Service中。这不仅能解决技术问题,还能使代码结构更加清晰,更符合软件设计原则。好的架构设计往往能避免技术上的陷阱。当我们遇到Spring事务失效的问题时,不妨先思考一下,是不是我们的代码结构需要优化了?
2025-12-21 13:39:21
666
原创 基于Redis ZSet实现多维度题目贡献度排行榜
高性能:Redis内存操作,O(logN)的复杂度灵活的时间维度:支持日、周、月、年等多维度统计原子性操作:确保数据一致性丰富的操作:支持排名查询、范围查询、分数更新等该方案已经成功应用于本在线教育平台,能够有效激励用户贡献优质题目,提升平台内容质量。
2025-12-13 10:00:00
1052
原创 MyBatis-Plus自动填充字段:优雅处理创建时间和更新时间
自动填充是MyBatis-Plus的一个核心功能,它允许我们在执行插入或更新操作时,自动为特定字段填充值。创建时间:数据插入时自动填充当前时间更新时间:数据更新时自动填充当前时间操作人信息:自动填充当前登录用户ID或姓名逻辑删除标记:自动填充删除状态@Data@Slf4j@Component@Overridelog.info("开始插入填充...");// 方法1: 根据属性类型自动匹配(推荐)
2025-12-12 11:25:04
594
原创 OpenFeign 拦截器:实现微服务上下文打通的艺术
通过OpenFeign拦截器实现微服务上下文传递是一种优雅且高效的解决方案。透明传递上下文:业务代码无需关心上下文传递的细节保持一致性:确保整个调用链中的上下文信息一致灵活扩展:可以根据需要传递不同的上下文信息解耦设计:拦截器与业务逻辑分离,便于维护在实际应用中,我们可以根据具体需求扩展这个基础实现,添加日志记录、监控指标、故障注入等高级功能,构建更加健壮的微服务通信机制。
2025-12-10 09:00:00
752
原创 Gateway网关拦截自定义header & 用户上下文打通实战
通过Gateway全局过滤器微服务拦截器ThreadLocal上下文持有器的组合,我们实现了:✅ 网关统一鉴权与用户信息传递✅ 微服务内无侵入获取用户信息✅ 线程安全的上下文管理✅ 链路结束时自动清理,避免内存泄漏该方案结构清晰、耦合度低,适合在中小型微服务项目中快速落地用户上下文传递机制。线程本地变量是多线程编程中的强大工具,正确使用可以简化代码、提高性能。提供了基础的线程隔离能力,扩展了父子线程传值功能,而解决了异步编程中的上下文传递难题。在实际开发中,应根据具体场景选择合适的实现。
2025-12-09 10:53:02
1324
原创 内网穿透-NatApp
内网穿透是一种技术手段,通过在内网和外网之间建立一个稳定的通信通道,使得外部用户能够访问内网中的设备和服务,就像这些设备和服务直接暴露在公网一样。内网穿透简单来说就是将内网外网通过natapp隧道打通,让内网的数据让外网可以获取。比如常用的办公室软件等,一般在办公室或家里,通过拨号上网,这样办公软件只有在本地的局域网之内才能访问,那么问题来了,如果是手机上,或者公司外地的办公人员,如何访问到办公软件呢?这就需要natapp内网穿透工具了。
2025-12-03 16:10:04
444
原创 MyBatis中selectKey标签的深度解析与实践应用(获取数据库生成的主键值)
是MyBatis框架中专门用于处理数据库生成键值的XML标签,主要应用在插入操作中获取数据库自动生成的主键值。它的核心作用是在数据插入后(或插入前)立即获取数据库生成的关键值,并将该值自动映射到实体对象的对应属性中。
2025-11-24 17:14:52
596
原创 Vue综合案例-面经基础版
keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件中。在组件切换过程中把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。App.vue<template></div>缓存了所有被切换的组件。
2025-09-04 21:58:17
888
1
原创 Vue路由
生活中的路由:设备和ip的映射关系路径和组件的映射关系router-link的两个高亮类名 太长了,我们希望能定制怎么办声明式导航跳转时, 有几种方式传值给路由页面?查询参数传参(多个参数)动态路由传参(一个参数,优雅简洁)
2025-09-02 21:41:55
1081
原创 Vue自定义指令、插槽、单页应用程序介绍
概念:自己定义的指令,可以封装一些DOM操作,扩展额外的功能全局注册//在main.js中Vue.directive('指令名', {// 可以对 el 标签,扩展额外功能el.focus()})局部注册//在Vue组件的配置项中"指令名": {// 可以对 el 标签,扩展额外功能el.focus()使用指令注意:在使用指令的时候,一定要先注册再使用,否则会报错 使用指令语法: v-指令名。如:<input type="text" v-focus/>注册指令时不用加v-前缀,但使用时。
2025-08-31 17:00:39
875
原创 Vue生命周期、工程化开发和脚手架、组件化开发
虽然脚手架中的文件有很多,目前咱们只需认识三个文件即可main.js 入口文件App.vue App根组件index.html 模板文件组件化:一个页面可以拆分成一个个组件,每个组件有着自己独立的结构、样式、行为。好处:便于维护,利于复用 → 提升开发效率。组件分类:普通组件、根组件。比如:下面这个页面,可以把所有的代码都写在一个页面中,但是这样显得代码比较混乱,难易维护。咱们可以按模块进行组件划分组件通信,就是指组件与组件之间的数据传递组件的数据是独立的,无法直接访问其他组件的数据。
2025-08-30 19:28:22
777
原创 Vue基础入门、常用指令、指令修饰符、computed计算属性、watch侦听器
基于数据渲染出用户可以看到的界面所谓渐进式就是循序渐进,不一定非得把Vue中的所有API都学完才能开发Vue,可以学一点开发一点Vue核心包开发场景:局部模块改造Vue核心包&Vue插件&工程化场景:整站开发所谓框架:就是一套完整的解决方案举个栗子如果把一个完整的项目比喻为一个装修好的房子,那么框架就是一个毛坯房。我们只需要在“毛坯房”的基础上,增加功能代码即可。提到框架,不得不提一下库。库,类似工具箱,是一堆方法的集合,比如 axios、lodash、echarts等。
2025-08-24 14:12:18
1284
原创 线程池中的线程到底设置数量多少合适
现代CPU基本都是多核心的,比如我这里测试用的阿里云Cenos7,4核心8线程(超线程),我们可以简单的认为这个CPU就可以同时做8件事,互不打扰。如果要执行的线程大于核心数,那么就需要通过操作系统的调度了。操作系统给每个线程分配CPU时间片资源,然后不停的切换,从而实现“并行”执行的效果。但是这样真的更快吗?从上面的例子可以看出,一个线程就可以把一个核心的利用率跑满。如果每个线程都很“霸道”,不停的执行指令,不给CPU空闲的时间,并且同时执行的线程数大于CPU的核心数,就会导致操作系统。
2025-07-08 03:00:00
1569
原创 ThreadPoolExecutor + FutureTask 并发编程实战
创建/*** 线程池的配置管理类*/20, // 核心线程数100, // 最大线程数5, // 空闲线程存活时间TimeUnit.SECONDS, // 时间单位new LinkedBlockingDeque<>(40), // 任务队列Executors.defaultThreadFactory(), // 线程工厂new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略4.1.1 核心参数解析。
2025-07-07 14:28:23
767
原创 Gateway实现全局异常处理
本文旨在说明如何在 Gateway 中实现。该实现建立在)的基础之上。由于我们采用了微服务架构,因此需要通过网关来实现全局异常处理。
2025-07-02 16:05:07
651
原创 Linux中部署Nacos保姆级教程
前置说明: Dokcer部署Nacos官方文档:Nacos Docker 快速开始 | Nacos 官网Nacos 1.1.3 :是一个相对稳定的版本,在一段时期内被广泛使用,但目前该版本已经下线,不再单独维护,建议升级至更高版本。Nacos 1.2.1 :从 1.1.3 升级到 1.2.1 版本相对简单,该版本在功能和稳定性上都有一定提升,为后续升级到 2.x 版本奠定了基础。Nacos 1.3.3 :在服务发现、配置管理等方面性能提升显著,如在 100k 服务实例场景下,注册耗时相比 1.
2025-06-29 16:31:30
2884
1
原创 Minio入门+适配器模式(实战教程)
1.2.2 创建配置文件目录这个 Docker 命令用于启动一个 MinIO 对象存储服务器容器。MinIO 是一个高性能、与 Amazon S3 API 兼容的开源对象存储解决方案。下面是详细解释:启动容器后,可以通过浏览器访问 MinIO 控制台:使用之前设置的用户名和密码( 和 )登录。在yml添加如下配置:然后创建对应的配置类:自定义的MinioUtil代码如下:当我们创建桶后,Minio会在数据挂载目录下,创建一个和桶同名的文件夹。上面的过程
2025-06-28 16:08:25
1757
原创 Linux中部署Jenkins保姆间教程
本文将以docker的方式,讲述如何部署Jenkins最新版Jenkins地址:Download and deploy当前最新版的如下图所示:地址如下:Java Support Policy如果你安装了不受支持的 Java 版本,你的 Jenkins 控制器将无法运行。 特别注意:此处的JDK版本是Jenkins运行所依赖的版本。比如不支持在 JDK8 上运行。根据 Jenkins 的官方文档,从 版本开始,要求至少使用 Java 17 或更新版本来运行。(官方镜像已内置 OpenJDK)。不过,尽管
2025-06-26 17:24:43
1100
原创 Mybatisplus自定义日志(实战教程)
是 MyBatis-Plus 提供的一个拦截器接口,它可以在 SQL 执行的不同阶段拦截操作,从而实现对 SQL 语句的动态修改、性能监控、日志记录等功能。允许开发者在 SQL 执行的不同阶段插入自定义逻辑,如在查询前、执行更新前、准备 SQL 前等。常见的内置拦截器包括分页插件、多租户插件、乐观锁插件等,这些插件通过实现接口来提供特定功能。@Slf4j@Override@Overridetry {log.info("parameter-参数: {}", parameter);
2025-06-25 14:14:40
1566
原创 工厂 + 策略设计模式(实战教程)
工厂模式工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。其核心思想是定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类。策略模式策略模式是一种行为型设计模式,它定义了算法家族,分别封装起来,让它们之间可以互相替换。此模式让算法的变化独立于使用算法的客户。/*** 题目类型枚举* 1单选 2多选 3判断 4简答*/@GetterRADIO(1,"单选"),MULTIPLE(2,"多选"),JUDGE(3,"判断"),
2025-06-24 10:16:52
1447
原创 分布式事务-Seata
首先我们看看项目中的下单业务整体流程:由于订单、购物车、商品分别在三个不同的微服务,而每个微服务都有自己独立的数据库,因此下单过程中就会跨多个数据库完成业务。而每个微服务都会执行自己的本地事务:交易服务:下单事务购物车服务:清理购物车事务库存服务:扣减库存事务整个业务中,各个本地事务是有关联的。因此每个微服务的本地事务,也可以称为。多个有关联的分支事务一起就组成了。我们必须保证整个全局事务同时成功或失败。我们知道每一个分支事务就是传统的。
2025-06-11 08:00:00
913
原创 微服务保护-Sentinel
Sentinel是阿里巴巴开源的一款服务保护框架,目前已经加入SpringCloudAlibaba中。核心库(Jar包):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。在项目中引入依赖即可实现服务限流、隔离、熔断等功能。控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。为了方便监控微服务,我们先把Sentinel的控制台搭建出来。1)下载jar包。
2025-06-11 06:00:00
1055
原创 (新)Gateway网关+基于Nacos配置动态路由
无论是还是都支持自定义,只不过编码方式、使用方式略有差别。自定义不是直接实现,而是实现。@Component@Override@Override// 获取请求// 编写过滤器逻辑System.out.println("过滤器执行了");// 放行注意:该类的名称一定要以为后缀!spring:cloud:gateway:- PrintAny # 此处直接以自定义的GatewayFilterFactory类名称前缀类声明过滤器@Component。
2025-06-08 16:31:21
1594
原创 MybatisPlus(含自定义SQL、@RequiredArgsConstructor、静态工具类Db)
在刚刚的入门案例中,我们仅仅引入了依赖,继承了BaseMapper就能使用MybatisPlus,非常简单。也就是说我们在扣减用户余额时,需要对用户剩余余额做出判断,如果发现剩余余额为0,则应该将status修改为2,这就是说update语句的set部分是动态的。但是基于自定义SQL结合Wrapper的玩法,我们就可以利用Wrapper来构建查询条件,然后手写SELECT及FROM部分,实现多表查询。其中缺少的仅仅是分页条件,而分页条件不仅仅用户分页查询需要,以后其它业务也都有分页查询的需求。
2025-06-02 13:20:09
1332
原创 (新)MQ高级-消费者的可靠性
当RabbitMQ向消费者投递消息以后,需要知道消费者的处理状态如何。因为消息投递给消费者并不代表就一定被正确消费了,可能出现的故障有很多,比如:消息投递的过程中出现了网络故障消费者接收到消息后突然宕机消费者接收到消息后,因处理不当导致异常...一旦发生上述情况,消息也会丢失。因此,RabbitMQ必须知道消费者的处理状态,一旦消息处理失败才能重新投递消息。但问题来了:RabbitMQ如何得知消费者的处理状态呢?本章我们就一起研究一下消费者处理消息时的可靠性解决方案。
2025-05-31 14:02:53
1155
原创 (新)MQ高级-MQ的可靠性
消息到达MQ以后,如果MQ不能及时保存,也会导致消息丢失,所以MQ的可靠性也非常重要。为了提升性能,默认情况下MQ的数据都是在内存存储的临时数据,重启后就会消失。为了保证数据的可靠性,必须配置数据持久化,包括:交换机持久化队列持久化消息持久化我们以控制台界面为例来说明。在控制台的页面,添加交换机时可以配置交换机的参数:设置为就是持久化模式,就是临时模式。在控制台的Queues页面,添加队列时,同样可以配置队列的参数:除了持久化以外,你可以看到队列还有很多其它参数,有一些我们会在后期学习。在控制台发送消息的时
2025-05-31 13:47:34
1234
原创 (新)MQ高级-发送者的可靠性
每个只能配置一个,因此我们可以在配置类中统一设置。我们在publisher模块定义一个配置类:@Slf4j@Overridelog.error("触发return callback,");});由于每个消息发送时的处理逻辑不一定相同,因此ConfirmCallback需要在每次发消息时定义。具体来说,是在调用RabbitTemplate中的convertAndSend方法时,多传递一个参数:id:消息的唯一标示,MQ对不同的消息的回执以此做判断,避免混淆。
2025-05-05 02:00:00
664
原创 (新)SpringAMQP快速入门
Work模型的使用:多个消费者绑定到一个队列,同一条消息只会被一个消费者处理通过设置prefetch来控制消费者预取的消息数量交换机的作用是什么?接收publisher发送的消息将消息按照规则路由到与之绑定的队列不能缓存消息,路由失败,消息丢失FanoutExchange的会将消息路由到每个绑定的队列描述下Direct交换机与Fanout交换机的差异?Fanout交换机将消息路由给每一个与之绑定的队列Direct交换机根据RoutingKey判断路由给哪个队列。
2025-05-04 16:20:16
1131
原创 (新)RabbitMQ页面的基础用法
RabbitMQ是基于Erlang语言开发的开源消息通信中间件,官网地址:接下来,我们就学习它的基本概念和基础用法。
2025-05-04 14:07:37
995
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅