- 博客(240)
- 资源 (4)
- 收藏
- 关注
原创 发版那两分钟冒出 3 个 502:Spring Boot 优雅停机,我改了四轮才清零
发版那两分钟,监控上冒出 3 个 502,用户说"支付页面点不动"。这个事我盯了两次发版才定位到,问题不在代码,在停机方式。先说现象:Spring Boot 服务在 K8s 里滚动更新,新 Pod 起来之后,旧 Pod 收到 SIGTERM 就退了。日志里没有任何异常,只有几行正常的,但网关那边确实有请求失败了。
2026-11-10 08:39:54
192
原创 我明明建了唯一索引,怎么还有重复数据?字符集、软删除、NULL 三个坑
我明明建了唯一索引,怎么还有重复数据?”——这句话我在两个项目里都听同事说过,两次的原因还不一样。唯一索引这东西,看起来是把门锁上了,实际上有几把"备用钥匙"能绕过去。这篇把三个最常见的坑一次说清,都是我或同事真踩过的。
2026-11-10 08:37:36
251
原创 小程序主包 3.9MB 快爆了:job-uniapp 用 18 个分包 + preloadRule 拆包
小蓝直聘的页面越加越多,主包一路涨到 3.9MB 的时候,我收到了微信的"代码包超过限制"警告,离 4MB 只差一点。当时的处理很粗暴:把不常用的页面往主包里继续删,能删的都删了还是不够。真正解决问题,还是靠分包。
2026-11-10 08:36:48
163
原创 收藏按钮连点两下,收藏表里多出一条:xllg 收藏 toggle 的竞态排查
一开始我以为是前端没做防抖,加了个 loading 遮罩,结果线上还是有。后来翻日志才发现,问题在服务端。
2026-11-09 08:56:54
216
原创 接口全返回 200,前端却分不清成功失败:qkl-boot 的 R + traceId 落地记
接口全返回 200,前端却分不清成功失败——这事我在 qkl-boot 上折腾了两轮才收口。最早的脚手架里,十几个 Controller 各写各的:有人返回Map,有人直接,有人异常了还给前端 200 加个。前端写请求封装的时候天天问我,“这个接口失败是看 code 还是看 success”,我也答不上来,因为确实每个模块都不一样。后来索性把返回体、错误码、异常翻译、链路 ID 这四件事一次做完,现在新模块照着抄就行。
2026-11-09 08:56:04
400
原创 订单 30 分钟没付款自动取消,集群里却取消了两次:Quartz 重复跑的排查
日结零工系统里,用工订单待确认超过 30 分钟要自动取消,把名额释放出来给别的工人。这个任务以前单机跑得好好的,扩到两台节点之后开始出怪事:同一笔订单被取消了两次,取消通知也发了两遍,老板手机上弹了两条一模一样的消息。这篇把排查过程和最后的处理方式讲清楚。
2026-11-09 08:55:14
486
原创 岗位详情页的缓存,别只 set 一个 key:穿透、击穿、雪崩各自长什么样
缓存方案没有标准答案。岗位详情这种读多写少、能容忍短暂旧值的场景,逻辑过期是最划算的;换成钱包余额,同样的方案就是事故。先想清楚业务能容忍多久的不一致,再决定用哪套。
2026-11-08 08:33:54
283
原创 小程序请求层别散装写:token、401、loading,job-uniapp 的 request.js 踩过的三个坑
小蓝直聘最早那版,每个页面自己写,参数拼一遍、错误提示抄一遍。后来改成统一请求层,看着清爽了,坑也跟着集中爆发——尤其是 loading 和 401 这两块,一个体验问题,一个能把人踢下线。这篇把 request.js 里几个关键位置和踩过的坑摊开讲。
2026-11-08 08:33:24
281
原创 按钮权限挡住了,数据还在裸奔:qkl-boot 的 @DataScope 是怎么拼 SQL 的
做后台系统最容易漏的一件事:菜单和按钮权限都配好了,部门经理点进"用户列表"却能看到全公司的员工。按钮权限管的是"能不能点",数据权限管的是"能看到哪些行",两码事。qkl-boot 里这块是用一个注解 + 一个切面 + 一个 MyBatis-Plus 处理器串起来的,代码不多,但要跑通得想清楚三处衔接。
2026-11-08 08:32:53
299
原创 上班打卡只看距离还不够:xllg 的围栏校验、状态机和工时结算怎么串起来
反过来会出问题——先改状态再校验距离,一旦抛异常事务虽然回滚,但通知消息已经发出去了,工人手机弹出"打卡成功",后台却是失败状态,客服一天要接好几个这种电话。
2026-11-07 08:35:23
328
原创 筛选条件 watch 一改就全表刷新?Vue3 deep+immediate 和 structuredClone 双保险
筛选组件大概是前端最容易被"响应式"坑的地方。job-uniapp 的职位筛选器里有个经典设计:父组件传filter进来,组件内部维护一份draft,用户改完点确认才emit回父组件。听起来没毛病,但 watch 用深监听 + 浅拷贝同步 draft 时,嵌套对象会共享引用——你在 draft 里改一个字段,父组件的 filter 悄悄跟着变了。这篇把坑拆开讲。
2026-11-07 08:34:43
357
原创 报名接口被连点两下,订单建了两条:SETNX 幂等锁 8 秒过期救场
零工平台上最怕什么?用户手抖点两下报名,后台冒出两条工单;结算按钮双击,工资发两遍。靠数据库唯一索引能兜住一部分,但接口层还是该有一道闸。xllg 的做法是一个,Redis SETNX 拿短时锁,报名、结算、提现各配一个专用方法,业务方三行代码搞定。
2026-11-07 08:34:01
297
原创 H5 上选个地址偏了 300 米?chooseWorkAddress 三端统一 + WGS84 转 GCJ02 纠偏
小蓝直聘发职位要选工作地址,简历要填常居地,IM 里也选位置。一开始每个页面各写各的,小程序调,H5 压根不支持这个方法,直接白屏。后来把选地址收成一个,三端一个入口,顺带把坐标系的坑也填了。这篇把 job-uniapp 里的 addressPicker 拆开讲。
2026-11-06 08:34:11
374
原创 腾讯地图密钥别撒前端:后端代理 reverseGeocoder + nearby,10 秒超时兜底
日结零工这种业务,地图是刚需:工人找附近的活、发单选地址、结算看位置。一开始图省事,前端直接调腾讯地图 WebService,key 写死在 JS 里。结果某天控制台看到 key 被拿去刷 POI 搜索,一天几十万次调用,账单直接爆。后来把地图接口全部收进后端代理层,密钥走配置、IP 定位兜底,前端只认自己的接口。这篇把 xllg 里的 TencentMapApiSupport 拆开讲。
2026-11-06 08:33:35
290
原创 接口返回的手机号别再裸奔了:一个 @Desensitize 注解,脱敏还能按权限放行
安全扫描那天下午,运维丢过来一张工单:日志里抓出一堆明文手机号,还是 P0。改完那一轮我就在想,能不能从源头堵住——接口返回、日志输出,两处一起管。qkl-boot 的 qkl-common 里就是这么干的,一个注解加一个序列化器,业务代码几乎零改动。
2026-11-06 08:32:19
287
原创 一个接口串行调 3 个上游,改成 CompletableFuture 并行,P95 从 1.8s 掉到 0.6s
职位详情页要拉用户信息、企业信息、投递状态三份数据,最早写的是 A 等 B、B 等 C 的串行,页面 P95 1.8 秒,测试直接吐槽"转圈转到怀疑人生"。改成 CompletableFuture 并行聚合后掉到 0.6 秒,这篇把线程池隔离、超时、异常兜底一次讲清。
2026-11-05 08:33:00
312
原创 GoEasy 换自研 WebSocket,业务代码一行没改:imClient 兼容层 + 会话列表防抖
现象:用户发完消息,会话列表有时不更新,新会话要等下一次操作才出现。排查:看代码,发消息后调刷新,但紧接着另一个流程又触发了一次刷新——第一次的回调被防抖窗口吞了,第二次的回调里 onSuccess 覆盖了第一次的。防抖合并的是"请求",不是"结果"。两处刷新想要不同的结果(一个要最新会话、一个只要未读数),合并后只剩最后一次的回调,前一次的数据更新就丢了。解决:把"必须立即刷新"的场景单独走直调(比如发完消息后),防抖只留给"消息到达这种高频轻量刷新"。再在flush。
2026-11-05 08:32:22
303
原创 支付回调别直接改订单状态:验签、幂等、事件解耦,qkl-finance 是这么接的
微信支付的回调能重试 8 次、每次都带同样的 out_trade_no,你要是直接在回调里"改订单状态 + 发消息 + 记流水",重复回调来了就是双倍积分、双倍通知。qkl-boot 的 qkl-finance 模块把回调这条路走顺了:验签、幂等、事件解耦、回调日志,一层套一层。
2026-11-05 08:31:45
268
原创 连续签到 7 天领 50 积分:xllg 的 ums_sign 表怎么设计,补签怎么控制
业务代码判断"今天签没签"永远有并发窗口,唯一索引兜底,重复插入直接报 DuplicateKeyException,比任何 if 判断都可靠。
2026-11-04 08:36:48
251
原创 qkl-boot 把 AI 做成独立模块:多 Provider 切换、Key 加密、RAG 开关,业务代码零改动
"换个大模型,要动多少代码?"老板一句话,我对着三个 Service 里的硬编码 OpenAI 客户端发了半小时呆。后来 qkl-boot 里单独起了个qkl-ai模块,把 Deepseek、通义、智谱全收进去,业务层只认一个接口。这篇把模块怎么拆的记下来,配置、代码都能直接抄。
2026-11-04 08:36:15
232
原创 Vue3 列表页别再重复写 loading 和请求了:useTable 一个 hook 收走
列表页多了以后,useTable 的 fetcher 签名偶尔会有人写歪——有的接口返回,有的返回data.list。// api/http.ts 里统一分页响应结构???0 }// 使用分页响应的结构统一收敛成 rows/total,useTable 里永远只认这两种字段,页面不会因为后端换字段名而崩。我见过几个项目最后栽在这上面,越早统一越省事。顺带一提,useTable里我特意没把"请求失败"的 toast 写死——有的页面要提示条,有的要弹窗,有的静默重试。错误处理留给页面自己决定。
2026-11-04 08:35:44
304
原创 连接池到底调多大?HikariCP 参数、泄漏检测、冷启动预热一次说清
连接池参数这玩意,默认值能跑,但一到高峰期就现原形。我们的招聘系统被 DBA 找过两次,一次是连接池打满接口报,一次是池子空转占着数据库不放。这篇把我按监控调参的过程记下来,参数和判断方法都能直接抄。
2026-11-03 08:33:21
290
原创 职位详情页富文本、投递状态、海报二维码:job-uniapp 三块硬骨头
详情页看着就一张卡片的活,真做起来三个坑一个不少:企业介绍是后端吐的富文本 HTML,直接塞进 rich-text 会带一堆样式乱掉;投递按钮的状态一变再变;分享海报要用 canvas 画出来保存到相册。job-uniapp 这三块都趟平了,逐个说。
2026-11-03 08:32:49
329
原创 附近工单搜不到?GeoHash 九宫格检索 + 联合索引,xllg 定位修复实录
在这里插入代码片# 日结零工"附近有活"怎么搜的:xllg 用 GeoHash + 9 宫格把周边工单检索干到 30ms零工 App 打开第一屏就是"附近有活",这个接口要是慢,用户基本就流失了。,工单量到了几十万条,一次全表扫描,接口 500ms 起步。后来改成 GeoHash 前缀索引 + 9 宫格扩展,P95 稳定在 30ms 上下,这篇讲讲怎么落地。
2026-11-03 08:32:18
270
原创 自定义注解校验比 if 判断爽多了:@UniqueCheck 分组校验两个坑,qkl-boot 实战
查重这种"要查数据库"的校验,Bean Validation 内置注解干不了,得自己写。qkl-boot 里留了个String message() default "该值已存在";// 要查哪张表、哪个字段@Component// 更新场景排除自身@Override@Override@NotBlank(message = "手机号不能为空")@Pattern(regexp = "^1\\d{10}$", message = "手机号格式不对")
2026-11-02 09:16:45
176
原创 @Transactional 加了等于没加:五个真实失效场景,第三个最坑
"方法上明明标了 @Transactional,异常也抛了,数据怎么还是写进去了?"这种问题在面试里是送分题,在线上就是事故。我这几年把身边踩过的真实案例归了归类,五个场景,每个都有具体现象,重点说第三个——它坑了我整整一个下午。
2026-11-02 08:41:20
316
原创 LIMIT 100000, 20 为什么还是慢:深分页三件套,游标 / 延迟关联 / 覆盖索引
第 1 页 20ms,第 5000 页 3 秒”,列表接口越翻越慢,这种体验在后台管理系统里几乎人人撞过。看着只取 20 条,MySQL 却要先把前 100000 行全扫出来再丢掉。这篇把深分页的代价算清楚,再给三个能落地的优化。
2026-11-02 08:35:16
284
原创 一个 baseUrl 管三端:job-uniapp 网络层封装,token 失效自动滚回登录页
小程序、H5、App 三端共用一套 uniapp 代码,最烦的就是环境地址和登录态各写各的。之前满天飞,改一次后端地址要全局搜索替换,token 过期了页面卡在空白,用户以为 bug。job-uniapp 的网络层收敛成一个baseUrl.js+ 一个request.js,这套封装救了不少事。
2026-11-01 08:47:33
151
原创 0 到 6 七个状态,xllg 用工单状态机是怎么拦住非法流转的
顺序不能乱——先过状态机再校验当事人,可能一个非法请求把状态机日志刷爆;先落库再过状态机,非法迁移已经写进去了。卡点的顺序本身就是一道防线,这也是 xllg"服务端为准"原则的落地形式:客户端传什么状态都不信,服务端自己推演。为什么强调"服务端为准"?移动端、管理端、定时任务、支付回调四个入口都可能改订单状态,任何一端绕过状态机直接改库,数据就烂了。统一收口到动作接口后,入口就四个,代码审查和日志排查都轻松很多。
2026-11-01 08:45:34
100
原创 数据库脚本放 Git 里还被删库?qkl-boot 的 Liquibase 迁移,我把变更集管到了生产
测试环境跑得好好的,一到生产就缺列、报错、回滚回不去,这种事故我经历过不止一次。根源多半不在 SQL 本身,而在"脚本到底谁在执行、执行了没有、执行过几次"。qkl-boot 后端用管库表变更,这套东西用顺了,库表变更就不再是"发版前手工跑一段 SQL"的玄学。
2026-11-01 08:43:29
102
原创 一条 2.8 秒的慢 SQL:EXPLAIN 说它没走索引,我排查了三个小时
职位列表页某天突然变慢,接口从 50ms 干到 2.8 秒。查了一圈,代码没动过,索引明明建了,数据也就 20 万条——那问题出在哪?type=ALL,全表扫描。索引建了但没走,这种坑排查起来最磨人,把过程完整记下来。
2026-10-31 08:41:45
192
原创 线程池参数到底怎么配?招聘系统三块异步场景,我踩完坑算出来的配置
线程池参数怎么配,网上教程一堆"最佳实践",真到自己项目里还是懵。招聘系统里简历解析、通知推送、消息聚合三块都是异步场景,线程池从"随手 new 一个"到"按业务量算出来",中间踩的坑能写满一屏。这篇不背八股,就说 xllg 相关的异步场景里,我是怎么把参数一步步调出来的。
2026-10-31 08:40:38
203
原创 job-uniapp 职位列表从白屏掉帧到 60 帧:分页、下拉刷新、触底加载三个坑逐个拆
job-uniapp 的职位列表页,第一版写得挺"顺"的:onLoad 里 uni.request 拉一页数据,setData 塞进去,完事。结果一上线就被测试追着打——。后来把列表这块拆成"分页 + 刷新 + 加载"三个独立能力,逐个调优,才稳下来。
2026-10-31 08:38:08
16
原创 日结零工的结算流水表,我是这么设计才没让财务骂娘的:双写、幂等、对账
xllg 里结算这块我前前后后改了四版,最有价值的不是"怎么把钱发出去",而是"怎么保证钱不会多发、漏发、重复发"。把结算流水表的设计思路和防重复结算的实战写出来,这套东西在招聘/零工类项目里基本能直接抄。
2026-10-30 08:46:18
137
原创 qkl-boot 统一返回体没你想的那么简单:业务码、全局异常、字段取舍我踩过的三个坑
抛的是 BizException,但 code 传成了 500。
2026-10-30 08:44:45
207
原创 线上 CPU 飙到 98% 还没人调用?jstack 三分钟定位到一行 split 的正则回溯
top -Hp拿线程号 →转十六进制 →jstack连续抓三次对比 → 堆栈位置一致即死循环/回溯热点。底层是大量数据场景换成indexOfsubstring或。正则回溯是 CPU 飙升的隐形杀手,线上输入不可控时,能不用正则就别用。入口永远校验长度和格式,异常数据在源头截断,别指望后面层层兜底。告警响应顺序:QPS 没涨 + CPU 满 + 多线程同时高 → 优先怀疑正则/序列化/死循环,而不是 GC(GC 一般伴随内存异常或单线程热点)。
2026-10-30 08:33:04
290
原创 MySQL 批量插入 8.6 秒变 0.9 秒:rewriteBatchedStatements 才是真批量
补充一个容易被忽略的点:如果表上有触发器、唯一索引校验这类额外开销,多值 INSERT 的收益会被放大——一条 SQL 只做一次语法解析和一次事务日志组提交,5000 行只触发一次解析,而不是 5000 条 SQL 各解析一遍。压测环境记得关掉,开着它批量插入会慢 30% 以上,很多人优化半天没效果其实是日志在拖后腿。JDBC URL 加,配合,事务包住批量。驱动用 8.x(),老 5.1.x 对 rewrite 支持有坑。每批 500-1000 条分片,别一把梭全塞进去。
2026-10-29 08:50:00
136
原创 uniapp 图片上传链路实战:canvas 压缩、失败重试、七牛回显,iOS 白屏那次排查
→ canvas 等比压缩(最长边≤2048)→→ 上传。安卓后等 300ms 再截图,否则拿空白。上传组件必备:进度回调、线性退避重试(2 次)、abort 取消句柄、res.data容错解析。iOS 的不可靠,像素上限才是真防线。服务端接收后回显统一走 CDN 域名,别用后端服务器直出,带宽和并发都扛不住。
2026-10-29 08:48:31
50
原创 雪花 ID 生成器:时钟回拨、机器位、序列号三个坑,qkl-boot 里的落地写法
ID 结构:1+41+10+12,选个固定的历史时间点(比如 2023-01-01),别用项目启动时间,否则 41 位撑不到 2079 年也至少被压缩了使用年限。回拨处理:≤5ms 锁时间戳续序列号,>5ms 抛异常统一降级,别一刀切。机器位:配置中心下发,IP 哈希是给自己埋雷。AtomicLong+ CAS 替代用nanoTime忙等。自增主键替代场景:雪花 ID 适合写多读少、需要全局唯一、不想依赖 DB 生成器的场景;纯单机小项目,完全够用,别为了炫技引入复杂度。
2026-10-29 08:46:43
283
原创 零工平台消息通知中心:读扩散、未读数 Redis 维护、渠道路由,8 万人公告不卡库
通知业务默认读扩散:主表存内容、关联表存状态,单用户数据量小,写扩散没收益。未读数放 Redis,INCR/DECR即可,但已读扣减必须配合数据库is_read=0的原子 UPDATE 或 Lua 脚本防重复。,覆盖"我的未读"和"我的全部"两个场景。事务内落库 + MQ 异步投递,短信等慢渠道绝不阻塞业务接口。全员公告用批量写关联表,别 for 循环单条插。
2026-10-26 08:44:54
168
Windows 桌面端 PC 微信小程序图片/视频资源抓取工具
2026-07-25
android Wifi开发
2014-07-14
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅