动态路由数据源(多租户)解决方案

动态路由数据源(多租户)解决方案当下有很多服务都使用了多数据源,或是出于跨库查询或是分库分表、读写分离等,多数据源解决方案早已不是稀罕事 常见的解决方案包括使用多数据源框架(例如Shareding-Jdbc)、在数据库端做代理(例如MYCAT)、对于固定的几个数据源连接,也可以直接手动配置多个数据源,这种相关处理有很多源码,我在github上也有简单的实现:fishstormX/dynamicDataSource: 动态数据源的实现,基于maven自定义多模块骨架 Spring Boot2.0.x,本文实现的是动态数据源,主要为了解决 多租户问题(不同的用户群组有不同的数据源和配置,强调数据的隔离性) 本文技术能实现的是动态数据源,基于Spring框架,即能够将注入的Datasource根据租户不同使用不同的来源,同时根据租户增减动态的增删和缓存数据源(增是因为会有新增租户可能使用到项目启动后的数据源,减是因为租户数不可预料,不可直接缓存所有的数据源)
动态路由数据源(多租户)解决方案2021-01-07鱼鱼

AI 编程工程化迭代中的混沌风险:从规格熵到四个工程控制面

AI 编程工程化迭代中的混沌风险:从规格熵到四个工程控制面过去两年,我们团队把 AI 编程工具真正用进了日常研发:补全式的 Copilot、IDE 里的对话助手,以及能自己读写文件、跑命令的 Agent 收益是实打实的,样板代码、单元测试、脚本、联调、陌生框架的第一版实现,速度都明显提升 但用得越深,我越确信一件事:AI 工程化迭代最危险的地方,不是它“不会写代码”,而是它太会写了 在缺少稳定工程约束的时候,它会持续、高速地产出“单独看都挺合理,放在一起却彼此矛盾”的局部方案 这些矛盾的方案不会立刻表现为一个 Bug 它们表现为一种缓慢累积的混乱:同一个纠正反复被推翻,数据库越改越别扭,代码里一个概念长出两三个名字,线上出事时拼不出一条完整的因果链
AI 编程工程化迭代中的混沌风险:从规格熵到四个工程控制面2026-10-14鱼鱼

把报错贴给 AI 之前,我先做的三件事

把报错贴给 AI 之前,我先做的三件事以前一看到红字堆栈,我的第一反应几乎是:全选、复制、粘贴进 AI 对话框,然后等它告诉我怎么改 说实话,这个习惯有一段时间挺好用 很多常见错误,它一眼就能看出来,比我自己翻文档快 可后来我发现,有一半以上“贴完还是修不好”的情况,并不是 AI 不行,而是我把一坨还没整理过的信息甩给了它 它只能在这坨信息上猜,猜错了也不奇怪 现在我会强迫自己先做三件小事,再决定要不要问、怎么问 这三件事加起来通常不超过五分钟,但后面少绕很多弯路 不是真的要自己把根因找出来,而是先回答两个很朴素的问题: 这条报错,我看得懂“是什么”吗?发生的位置,离我刚改的代码近吗? 很多堆栈很长,真正有用的往往就那么几行:异常类型、消息正文、以及“第一次进入我自己代码”的那一帧
把报错贴给 AI 之前,我先做的三件事2026-10-14鱼鱼

Agent 的流式输出与“停止”按钮:用户点了停止之后,到底该发生什么

Agent 的流式输出与“停止”按钮:用户点了停止之后,到底该发生什么给内部做的一个小 Agent 加“停止”按钮,我原本以为是半天的活:前端加个按钮,点了以后断开流式连接,完事 上线第二天就有同事反馈:他点了停止,文件却还是被改了 我去翻日志,发现事情是这样的:他点停止的时候,模型刚刚生成完一个写文件的工具调用;前端确实停止了渲染,连接也断了,但后端的 Agent 循环根本不知道用户已经喊停,照样把工具执行完了,甚至还又调了一次模型,生成了一段没人看的总结 那之后我才意识到,“停止”这件事远比一个按钮复杂 这篇就聊聊我后来是怎么重新设计的,主要讲三件事:取消信号怎么传到底、中断落在不同阶段该怎么处理、以及中断之后对话历史怎么写 我后来把“停止”拆成了三层,每一层都要单独处理:
Agent 的流式输出与“停止”按钮:用户点了停止之后,到底该发生什么2026-10-14鱼鱼

Agent 的工具调用日志:出了问题我先看哪几行

Agent 的工具调用日志:出了问题我先看哪几行Agent 一跑起来,日志可以很热闹:思考摘要、工具名、参数、返回、重试、最终回答……出了问题时,若从头通读,既慢又容易被模型的“自信叙述”带偏 我逐渐养成一个习惯:先不看它怎么说,先看它调用了什么、参数是否离谱、返回是否被误解 这篇文章记我排查 Agent 故障时的日志阅读顺序 偏工程经验,不是某家产品的官方手册 失败时我最想看的其实不是最终答复 答复是渲染后的故事,故事会把中间的错误抹平 更常见的情况是: 所以我把最终答案降级成线索,把工具轨迹升级成证据 图:先证据后故事:工具轨迹优先于最终答复(原创示意图) 只看序列:读文件 → 搜代码 → 改文件 → 跑测试 这种骨架
Agent 的工具调用日志:出了问题我先看哪几行2026-10-14鱼鱼

并发之AQS全解析

并发之AQS全解析我们知道juc(java.util.concurrent)包下有很多实用的类,提供了很多并发工具,例如线程池、原子类、并发工具、信号量工具、锁等,可以说基本实现都为悲观锁,底层原理基本都使用了AQS(AbstractQueuedSynchronizer),AQS不是一种概念,是并发中实打实的工具类 本篇文章针对AQS做解析 AQS是多线程访问共享资源的同步器框架 AQS的资源可以是独占的也可以是共享的 我们先来简单看一下它的使用方式和ApI(因为是抽象类,是不能直接使用的),下图是AQS的整体脉络 AQS核心就是一个状态值state,同时维护了一个线程的阻塞队列,队列的节点为有两种状态:SHARED(共享)和EXCLUSIVE(独占),节点状态有五种:
并发之AQS全解析2021-03-12鱼鱼

让 AI 写 commit message,我留下的几条规矩

让 AI 写 commit message,我留下的几条规矩现在写完一小段改动,我偶尔会让 AI 根据 diff 拟一条 commit message 省事是真省事,翻车也真实翻过:有的标题漂亮得像广告,读完不知道改了什么;有的把半成品猜想写进历史,后来查问题的人会被带沟里 所以我不是禁用,而是给它加了几条规矩 规矩的核心只有一句:说明白改了什么、为什么改;别写套话,别替我编动机 Commit message 是给未来的自己和同事看的 好的 message 能回答:这次动了哪类东西?动机是修 bug、加能力,还是清债?有没有故意不做的范围? AI 擅长扫 diff、归纳文件级变化,比我在疲惫时随手敲的 fix、update 强 但它也容易:
让 AI 写 commit message,我留下的几条规矩2026-10-14鱼鱼

Agent 的重试与换路:失败了再试一次,还是换条路?

Agent 的重试与换路:失败了再试一次,还是换条路?做 Agent 的人,迟早会碰到同一个设计题:工具调用失败了,下一步是原地再试,还是换个策略? 听起来像工程里的重试策略老话题,放到 Agent 里却更别扭——因为失败的原因经常不是“网络抖了一下”,而是“这条路根本走不通”,或者“模型把错误理解歪了,越重试越执着” 我踩过两边的坑:该重试时太早放弃,任务脆;该换路时死磕重试,账单和日志一起爆炸,最后还是失败 这篇整理一下我现在怎么做判断 不是所有失败都该一视同仁 我大致分成四类: 瞬时故障:超时、限流、连接重置 特征是:同一请求,过一会儿可能就好 输入问题:参数缺了、格式不对、路径不存在 特征是:原样再发,几乎必败 权限/策略拒绝:没权限、被安全策略拦住
Agent 的重试与换路:失败了再试一次,还是换条路?2026-10-14鱼鱼

MySQL tips

MySQL tips一些日常接触到的MySQL优化tips,比较散乱 假设有一个用户表,对于一句很简单的查询语句: 假设name与age字段均有单列索引,容易想到的是,MySQL应该会分别走两次索引,并将其结合起来,EXPLAIN也是如此,大多数时候MySQL会进行优化,我们可能会看到EXPLAIN的结果中有Using union或Using soft union,这是MySQL针对OR做了隐性的优化,但当SQL复杂或数据极端情况下,这一语句极容易变成全表扫描,偶尔使用联合索引可能解决问题,更多情况则是MySQL“昏了头”,即使OR条件均涉及数据条数不多,依旧没能在查询语句中使用索引,此时应调整为UNION语句(可以权衡一下重复及顺序是否有影响,可以使用更快的UNION ALL):
MySQL tips2021-01-13鱼鱼

让 AI 重构老代码,我宁可它一次只动一小步

让 AI 重构老代码,我宁可它一次只动一小步我手上有个老项目,里面有一个结算相关的 Service 类,六百多行 最长的一个方法两百多行,if-else 套了五六层,中间还夹着几段被注释掉、但没人敢删的代码 每次需求要动它,大家都绕着走,能加个分支就加个分支 有一天我终于下决心收拾它 那时候我已经用 AI 写了不少代码,心想重构这种“体力活”,交给它正合适 结果第一次尝试,差点让我对“用 AI 重构”这件事彻底失去信心 后来换了一种做法,才算顺利做完 这篇就讲讲这两次的区别 我把整个类贴给 AI,说:“这个类太乱了,帮我重构得清晰一点,保持功能不变 ” 它给我的结果,单看确实漂亮:长方法拆成了十几个小方法,几种结算方式抽成了策略类,变量名全换成了更有意义的名字
让 AI 重构老代码,我宁可它一次只动一小步2026-10-14鱼鱼

Agent 并行调用工具:哪些能一起跑,哪些必须排队

Agent 并行调用工具:哪些能一起跑,哪些必须排队现在不少模型接口都允许模型在一轮回复里同时发起多个工具调用 对写 Agent 的人来说,这是个很诱人的能力:读五个文件不用等五轮,查三个接口可以一起发,整体耗时一下子降下来 我第一次给自己的 Agent 打开并行执行时,体感确实快了不少 然后就开始出怪事:有一次它在同一批调用里既改了一个文件,又跑了测试,测试跑的却是改之前的代码,结果它看着“通过”的测试,宣布任务完成 还有一次,两个写文件的调用同时改同一个配置文件,后写的把先写的覆盖了,日志里两个调用都显示成功 这些问题让我明白:模型愿意并行,不代表这些调用适合并行 模型给出的只是“我想做这几件事”,至于能不能同时做,得由执行层来判断
Agent 并行调用工具:哪些能一起跑,哪些必须排队2026-10-16鱼鱼

AI 生成测试我怎么取舍:哪些让它写,哪些必须人写

AI 生成测试我怎么取舍:哪些让它写,哪些必须人写用 AI 写业务代码越来越顺手之后,下一件很自然的事就是:让它把测试也补上 说实话,这一步的爽感很强——几分钟冒出一堆 should_xxx,覆盖率数字往上跳,CI 绿灯 问题也正好出在这里:绿灯不等于有保险 我经历过一次挺丢脸的事 AI 帮我补了十几个单测,覆盖率从 40% 拉到 75%,合并后第三天生产就炸了 回头看测试,几乎每个都在验证“mock 对象有没有按我设定的方式被调用”,真正的业务不变量一个都没钉住 测试在保护 mock,不在保护系统 这篇文章想说清楚三件事:哪些测例我愿意交给 AI;哪些我坚持人手写;以及怎么减少“假绿” 图片来源:原创示意图 我不想装清高
AI 生成测试我怎么取舍:哪些让它写,哪些必须人写2026-10-14鱼鱼
网站地图
1
首页 博客 {{screen}} 第 {{page}} 页
博客索引
{{blog.createDate}} ◔ {{blog.timeline}} 小头像 {{blog.author}} {{tag}}
{{blog.likeCount}}{{blog.commentCount}}
分类下暂时没有文章哦!
主题分类
{{taggroup.label}} 

{{tag.value}}