这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
《互联网产品的服务端架构·产品、流量与基础能力》11.1 用户视角的 SLI
监控面板全绿,用户却反馈首页打不开,问题出在 SLI 的采集口径。文章从用户动作出发,区分请求可用性与用户可用性,说明首屏、可交互与接口成功率的差别,给出按请求计算的可用性与最近秩 P95 实现,并列出样本采集与校验边界,帮助团队在事故前把口径定清楚。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
监控面板全绿,用户却反馈首页打不开,问题出在 SLI 的采集口径。文章从用户动作出发,区分请求可用性与用户可用性,说明首屏、可交互与接口成功率的差别,给出按请求计算的可用性与最近秩 P95 实现,并列出样本采集与校验边界,帮助团队在事故前把口径定清楚。
allocateDirect 把字节放到堆外,不受 -Xmx 管,回收却依赖 Cleaner。本节在 32 MB MaxDirectMemorySize 下复现 Cannot reserve 报错,用 BufferPoolMXBean 观察 10000 个短命缓冲区的延迟释放,并说明 linkd 的 BufferPool 何时该用堆外、何时不该用。
一次 read 之后 position 落在末尾,直接 get 什么也读不到;flip 早了丢数据,flip 两次会重放旧数据。本节用 16 字节缓冲区画出 position、limit、capacity 的每次变化,讲清 flip/clear/compact/rewind 与 slice、只读视图,并给出 linkd 读写切换的排错清单。
凌晨发布时直接 rename 列,老 Pod 还在跑,写入全部报未知列,订单创建失败十二分钟。文章把列变更为先扩后收的 expand、migrate、contract 三阶段,说明双写、回填、双读校验与切换的停点,用 Go 校验阶段顺序和双写幂等,并给出表驱动测试与真实运行输出。
帧切出来只是 byte[],还不能说明协议是否正确。本节把 linkd 的 4 字节信封拆成 magic、version、type,再解析后续 payload,用 ProtocolException 区分可恢复与致命错误,给出错误帧、关闭策略和编码解码分离的 FrameEncoder,并完成每连接一份 carry 的 LinkdFrameHandler。
TCP 只保证字节有序,不保证一次 read 等于一条消息。本节实现可运行的定长、分隔符、长度域三种 FrameDecoder,用每 3 字节喂一次的实验复现半包与粘包,讲清长度字段越界、负长度、最大帧限制和返回切片被复用的坑,最后落到 linkd-core 的装配。
90 秒单局与 8–12 分钟对局不该共用一套恢复策略。本节把快照与操作日志放进同一张成本表,用回放预算而不是产品名选择路线,并实现可合并的恢复令牌、幂等重放、乱序重排与快照加尾日志,最后比较消消与方舟各自的选择、恢复上限、检查点间隔与服务端校验。
灰度 5% 时错误率已经从 0.4% 翻到 1.8%,却没人看指标,一路放到 100% 才发现。文章把灰度拆成按用户分桶的递增台阶、独立于发布的开关和带最小样本量的回滚阈值,用 Go 实现计划校验、阶段推进与自动回滚判断,并给出表驱动测试与一次真实的运行输出。
字节序与字符集是 linkd 协议的第一道边界。本节用 ByteBuffer 对比大端与小端的真实字节,拆开 UTF-8 和 UTF-16 对汉字、ASCII、emoji 的编码差异,用 CharsetDecoder 的 REPORT 抓住被截断的 3 字节汉字,并给出每连接独占的 Utf8StreamDecoder 与固定大端的 WireInt。
客户端发完请求只是半关闭,服务端要读到 EOF 才能回响应。本节用 linkd 的 Echo 连接实测 shutdownOutput、SO_LINGER(0) 触发的 RST、Connection reset 与 Broken pipe 的差异,并给出停止 accept、排空写队列、半关闭再 close 的优雅关闭顺序。
一次发布混进三个功能、一个索引重建和一份配置,出故障时没人说得清该回滚哪一段。文章把发布拆成代码、配置、schema、数据修复四类可独立观测、独立回滚的变更单元,用 Go 校验组件冲突、不可逆变更的观测信号与纯配置误标,并给出表驱动测试与真实运行输出。
端能力不是布尔值:同一个支付能力可能是原生、polyfill 或完全缺失,同一个功能可能是必需或可选。本节用能力表与降级计划模块,把「原生、polyfill、降级、阻塞」四种策略写成可测试的判定,并说明快照刷新、探测误差、开关实验的边界与排查清单。
提示改版后旧缓存继续返回旧口径,用户注销后摘要仍能被相似问题命中。本节把失效拆成提示换版、模型切换、权限调整与用户删除四类传播范围,说明作用域纪元如何挡住迟到的旧写回,并给出可运行的 TypeScript 失效器、删除权传播与完整隔离测试。
connect 超时、SO_TIMEOUT 与写阻塞是三件不同的事。本节用 linkd 访问 libraryd 的真实调用,实测 connect 1000ms 超时、read 超时后连接仍可继续读、发送缓冲区写满后线程卡在 SocketDispatcher.write0,并给出 Deadline 总预算与「超时不是重试」的边界。
从 linkd 的最小阻塞 Echo 入口出发,拆开 ServerSocket 的 bind、listen、accept 与 Socket 的读写阻塞点,用本机实测说明 backlog、SO_REUSEADDR 与 TIME_WAIT 重绑行为,给出可停止的 Echo 服务器、半包边界和 netstat 诊断命令。
用户付了钱订单却三天待支付,暴露的是重试、死信与对账三层防线同时缺位。文章把重复、丢失、乱序当作常态,说明指数退避为何必须有上限、死信为什么必须有人处理、对账为何是最后一道防线,并给出 Next 与 Reconcile 的可测试实现与边界测试。
InetAddress 解析可能返回多个地址,localhost 同时是 127.0.0.1 和 ::1。本节观察 getAllByName、IPv4/IPv6 回环、端口 0 的临时端口分配、重复绑定的 BindException 原文,以及 lo0 MTU 16384 与 en0 MTU 1500,并用 netstat/lsof 验证,最后落到 LinkdMain 的绑定日志。
UDP 一次 send 就是一条消息,但消息可能丢、可能被截断。本节用 DatagramSocket/DatagramPacket 实测数据报边界、100 字节缓冲接收 2000 字节报文时的静默截断、70000 字节报文的 Message too long,以及 4096 字节接收缓冲下 5000 个包只收到 3 个的丢包结果,并给出 linkd 指标上报的 UDP 边界。
从 arch-lab 同时服务 Web、移动端和合作方的订单详情页出发,说明 BFF 如何按端定义聚合计划、用白名单裁剪敏感字段,并把可选依赖失败降级为带标记的部分响应;给出并发聚合的 Go 实现,实测字段裁剪、必需与可选依赖的分界以及 section 并行度。
点赞事件重复投递让计数先涨两次又掉回去,问题不在消息队列,而在消费者没有幂等账本。文章区分事件与通知的失败语义,说明至少一次投递下如何用事件 ID 去重、用版本门槛拒绝旧格式、用首次处理时间回答最终一致要多久,并附 Apply 的 Go 实现与测试。