2026
05月
消息可靠性:用 outbox 模式把 IM 消息投递变得靠谱
本文介绍了使用outbox模式解决即时通讯消息投递可靠性的问题。作者通过分析WebSocket推送存在的三个核心缺陷——双写不一致、离线丢失和服务重启状态丢失,提出采用事务性写入outbox表+异步调度的方案。具体实现包含三个关键环节:将推送事件与消息数据在同一个事务中写入outbox表;通过定时任务轮询待处理事件;采用状态机管理投递过程并支持重试机制。文中详细说明了表结构设计、索引优化、状态转换逻辑和重试策略等技术细节,实测显示该方案可将投递成功率提升至99.7%。该模式既保证了投递可靠性,又为后续引入消息队列预留了扩展空间。
WebSocket 基础架构:从零搭建企业 IM 的实时通信底座
文章介绍了基于WebSocket实现IM系统的技术方案,重点解决传统轮询方式存在的性能问题。核心内容包括:采用原生WebSocket而非STOMP协议,通过复用HTTP Session实现鉴权,设计SessionRegistry管理多设备连接,以及30秒应用层心跳机制确保连接活跃。系统使用ConcurrentHashMap和CopyOnWriteArraySet实现线程安全的连接管理,并详细处理了连接建立、消息接收、异常关闭等生命周期事件。前端实现断线重连策略,前三次采用递增延迟(0.8s→2s→3.2s),超过三次则固定60秒重试。文章强调连接管理的可靠性是IM系统的关键,尤其需要注意异常时的资源清理。
Spring AI + pgvector 实战:把企业文档变成 AI 的记忆
本文介绍了中小企业协同办公平台Workforce Hub的AI知识库构建经验。针对日常制度问答需求,团队选择Spring AI + pgvector搭建RAG(检索增强生成)方案,避免了Elasticsearch的高部署成本,更适合中小企业。实施过程中重点解决了文档分段、向量化、相似度检索和提示词工程四个环节的难题:文档需按语义(而非机械长度)分段并设置重叠防止信息割裂;需确保向量模型维度与数据库一致;使用相似度阈值过滤无关问题;并通过精心设计的提示词限制AI回答范围。最终在零额外依赖下实现了制度问答准确率90%以上、响应速度2秒以内的效果,核心经验是:合理的文档分段和提示词设置比模型选择更重要,对中小企业而言,稳定简洁(如pgvector)的解决方案优于追求技术酷炫。
Flowable 工作流引擎实战:从 if-else 状态机到 BPMN 流程编排
本文介绍了作者在使用Flowable工作流引擎实现企业请假审批模块的经历。最初使用if-else硬编码来处理多变的审批流程(如不同假期类型、跨天免复核、超时提醒等),导致代码复杂难维护。通过引入Flowable,将流程逻辑从业务代码中剥离,用可配置的BPMN图实现一个包含AI预审、主管审批、人事复核的多分支审批流,并支持自动触发考勤重算等后续任务。文章分享了选择Flowable的原因、Spring Boot集成方法、关键代码示例(启动流程、查询任务、完成任务)及遇到的流程变量、多实例任务等典型“坑”,并着重介绍了扩展自定义AI审核节点来预检申请及申诉通道的独特设计。最终总结认为,工作流引擎的核心价值在于提升流程的可维护性和灵活性。
Workforce Hub 项目简介:从零构建企业级协同办公平台的技术选型之路
本文是一位大三学生分享其个人项目“Workforce Hub”的核心内容。该项目是一个企业协同人事平台,可部署在自有服务器上,提供聊天、请假、打卡、审批等类似钉钉的功能。其核心差异化在于将AI Agent深度集成到业务流程中,用于预审、知识问答和主动提醒。 在技术架构上,作者选择模块化单体架构(而非微服务)以提高个人开发效率,后端采用Spring Boot 3 + MyBatis-Plus,前端使用Vue3 + TypeScript,并同时接入MySQL、PostgreSQL(用于RAG向量检索)、Redis和MinIO四种存储。 该项目目前仍在开发中,核心设计思路是:用模块化单体保障效率,用Agent平台创造差异,并用Docker Compose降低部署复杂度。作者强调,此项目最大的价值在于获得了构建完整系统的工程实践经验。
模块之间如何优雅地说话:Java SPI 解耦的实战与应用
本文探讨了在模块化单体架构中,采用SPI(Service Provider Interface)作为模块间通信方案的价值与实践。文章比较了直接import、消息队列和SPI三种方式的优劣,指出直接import会导致紧耦合,消息队列过重且不适合同步场景,而SPI则在接口依赖与实现解耦间取得了平衡。通过考勤模块查询请假记录的实例,文章详细说明了如何定义SPI接口、业务模块实现接口以及调用方仅依赖接口的协作流程。此外,文章以文件中心因直接调用导致问题的反例,强调了编译时隔离的重要性。总结指出,SPI不仅保障了当前架构的清晰与可维护性,更为未来可能的微服务拆分提供了平滑演进路径,是面向变化设计的有效投资。
没有最好的架构,只有合适的架构:模块化单体的选型与演进
本文分享了作者为一个学生系统Workforce Hub选择并实施模块化单体架构的实践经验。项目从一个考勤模块起步,随着功能(假期、审批、消息等)不断扩展,并加入Agent等复杂模块,最初简单的代码结构已不能满足需求。面对微服务的流行诱惑,作者基于开发周期、运维复杂度和当前单企业部署的实际规模,理性选择了模块化单体架构。 核心实践包括:1) 业务模块物理目录隔离;2) 引入SPI接口层,在保障模块间通信的同时,实现编译时的零依赖,为未来可能的微服务拆分预留了接口。文中重点反思了文件模块因未严格隔离导致的强耦合“踩坑”经历,强调了编译器级别隔离的重要性。 总结认为,架构选型应遵循“最合适”而非“最先进”原则。模块化单体在当前是性价比最高的方案,通过清晰的边界与SPI解耦,既保证了系统的可维护性,也为未来的演进做好了准备。
从RBAC到三层动态裁剪:企业级Agent平台的权限模型设计
本文介绍了一个名为Workforce Hub的智能协作平台在Agent权限管理上的创新方案。平台发现传统RBAC模型无法满足AI Agent代理用户操作时的权限需求,因为Agent非用户身份,其权限需额外考虑自身能力边界和用户授权的叠加。文章提出三层权限动态裁剪模型:**Agent能力集**(注册时定义的工具集)、**用户权限集**(传统RBAC角色权限)与**数据可见域集**(基于组织、时间等的ABAC属性),三者每次操作时实时求交集成最终有效权限。该模型在网关层与服务层双层校验,实现精细控制,尤其突出数据可见域对Agent场景的关键意义。相比静态权限配置,此方案以更高复杂度换取了Agent协作场景的原生安全支持。
03月
我开始用问题引导式笔记补课了,效果比我想的更实在
作者借复习JavaEE和微信小程序开发的经历,反思了过去“看PPT即学会”的被动学习方式。在补MyBatis知识点时,他发现仅阅读课件仅留下模糊印象,动手实践时却无从下手。为此,他改为采用“问题引导文件”的方法:针对每章内容预先列出核心问题,再带着问题学习,并尝试用自己的语言解答和梳理概念关系,之后结合最小实践与复盘批注来巩固理解。这种方法帮助他从“盲目扫读”转向“目标导向”,更清晰地识别自身知识的薄弱点,尽管初期速度较慢且需克服追求形式完整的倾向,但切实提升了学习的深度与效率。
MyBatis入门踩坑记:一个寒假后遗症患者的自救指南
这篇学习笔记记录了作者在学习MyBatis框架过程中遇到的主要困惑与解决方法。作者基于寒假后复习JavaWeb的痛苦经历,从对原生JDBC的繁琐操作(如SQL硬编码、连接管理、结果集解析)的抵触出发,阐述了转向MyBatis的动机(一、为什么我要学MyBatis?)。 笔记的核心在于**理解MyBatis三大核心对象及其生命周期**(二、三大核心对象——我卡壳的地方): 1. **SqlSessionFactoryBuilder**是临时“建筑工人”,仅用于初始化。 2. **SqlSessionFactory**是全局唯一的“餐厅老板”,应配置为单例。 3. **SqlSession**则是每次请求对应的“服务员”,必须在使用后及时关闭,否则会耗尽数据库连接。 作者还分享了个人的**配置与实操经验**(三、配置文件那些坑 / 四、映射文件实战——namespace差点让我放弃),例如:配置文件编写有严格的顺序;连接池优先使用`POOLED`以提升性能;映射文件中`namespace`的作用类似包名,用于区分重名方法;以及`#{}`占位符在不同参数类型下的用法区别。 通过构建**标准项目结构**(五)、**利用JUnit编写测试类**(六)和解决**MySQL 8.0驱动与连接时区**等真实问题(七),作者最终掌握了MyBatis的基本CRUD操作。**总结**(八)强调学习要理论结合实践,并计划进阶动态SQL和Spring Boot集成。整个过程虽是“踩坑”之旅,但对MyBatis的工作原理和核心概念有了深刻理解。