这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
《Java 网络编程基础》9.3 多路复用、流量控制与优先级
从 linkd 一条连接上 6 个并发请求抢 65535 字节窗口出发,讲清 stream id 分配、WINDOW_UPDATE、连接级与流级窗口的区别,给出 Http2Connection 的写数据、窗口回收与轮转调度骨架,并说明 RFC 9113 弃用优先树后的取舍。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
从 linkd 一条连接上 6 个并发请求抢 65535 字节窗口出发,讲清 stream id 分配、WINDOW_UPDATE、连接级与流级窗口的区别,给出 Http2Connection 的写数据、窗口回收与轮转调度骨架,并说明 RFC 9113 弃用优先树后的取舍。
账号、资料和 BFF 三个模块共用一个 models 包时,边界只剩目录名。文章用一次越权读取说明数据所有权、依赖方向和对外契约如何划分,并给出可校验重复、缺失依赖与循环依赖的模块图实现,让拓扑序在每次构建中都可重复,也让三个模块能各自独立发布。
同一条按钮 token 在暗色主题下解析成透明文字,往往不是样式写错,而是三层 token 的解析链断了。本节用可运行的 TypeScript 模块演示 primitive、semantic、component 三层解析、主题覆盖优先级、别名环检测与缺失回退,并给出组件库接入主题前的验收判据。
手写 HPACK 的最小可用实现:静态表、动态表、整数编码与 Huffman 解码,用 RFC 7541 的 C.4.1、C.6.1 测试向量逐字节验证解码结果,并说明编码端不支持 Huffman 时如何通过 H=0 字面量合法降级、解码端为何仍必须支持。
从 linkd 一条连接只能串行处理请求的瓶颈出发,拆开 HTTP/2 的 9 字节帧头,逐字节解析 SETTINGS、HEADERS、DATA、RST_STREAM 与 GOAWAY,给出 Http2Frame、Http2FrameCodec 的编解码实现,并用 preface 握手把帧接进 9090 的读循环。
从大促前自动扩容却因镜像拉取与预热耗时六分钟、流量提前到达的事故写起,讨论预留 30% 与留两倍容量的判断依据,把目标利用率、步长与冷却时间写成 Decide 纯函数,给出夹紧边界、死区与冷却期的测试和真实输出,并说明缩容为何要比扩容更保守。
路由决定一个 HttpRequest 最终由谁处理。本节实现 HttpRouter 与 HttpRouterImpl,注册 /healthz 与 /books/{id},区分 404、405 与 500,并在静态文件服务里做百分号解码、路径规范化与根目录前缀校验,挡住 ../、%2e%2e、符号链接与编码斜杠。
HTTP/1.1 的连接复用依赖消息边界。本节实现 ChunkedCodec 的 chunk 解码与响应编码,用 KeepAliveHandler 处理 Connection: keep-alive/close、HTTP/1.0 兼容、分块请求与按序回写,并在 loopback 的真实 SocketChannel 上验证两个请求的响应顺序。
从「回声」只估了数据库、上线后被带宽与备份账单打回的事故写起,把存储、带宽与机器成本拆成可核算的账本,说明保留天数、副本数与 CDN 回源如何放大费用,给出 SteadyState、AfterDays 与 Monthly 的可测试实现和真实测试输出。
HTTP/1.1 的第一层是字节到消息的边界。本节实现 HttpRequest、HttpResponse 与 HttpParser,解析请求行和头部,给请求行、头部总字节与消息体设上限,用 400、413、431、414 区分格式错误与超限,并用分片读取、管线化输入验证解析器的增量行为。
连接卡在 CLOSE_WAIT、空闲连接占着内存,靠 if-else 堆状态迟早漏分支。本节用 linkd 的 ConnectionStateMachine 枚举 CONNECTED、READING、CLOSING、CLOSED 四种状态,配合 lastReadNanos 与 IdleTimeoutHandler 定时扫描,给出半关闭与资源释放顺序。
从「回声」三次容量评审给出相差数倍的数字写起,拆解 DAU、每用户请求数、峰值系数与活跃秒数各自的标定来源和常见偏差,用区间估算替代单点,给出可测试的 Bounds 实现、非法区间测试与一次真实 go test 输出,并解释按平均 QPS 买机器为何会在晚高峰排队。
一次 read 可能只拿到半个帧,一次 write 也可能只写出一部分。本节用 linkd 的 AccumulatingReader 累积字节、compact 保留残余、按帧上限扩容,并用 WriteQueue 暂存未写完的 ByteBuffer,给出半包、粘包与背压的可编译实现和实测输出。
非阻塞通道上的 accept、read、write 不再阻塞,返回值变成 null、0 和 -1 三种信号。本节用 linkd 的 NonBlockingEchoServer 实测这三种返回值,讲清读循环、写队列与 OP_WRITE 开关,以及漏摘 OP_WRITE 导致 CPU 空转的排查方法。
复盘报告只写“数据库连接数打满”,解释不了为什么监控二十分钟后才报警。文章把线上问题拆成检测、确认、缓解、解决四段,用时间线还原每一段的耗时,给出可测试的分析实现,并说明缺阶段、乱序与时间回退为什么必须报错,避免半截报告误导结论与改进方向。
本节把单线程 Reactor 扩成 accept 线程加多个 I/O 线程的主从模型:round-robin 分配连接、跨线程 execute 提交注册任务、ConcurrentLinkedQueue 与 volatile 的可见性边界。给出与单线程版同一压测脚本的对照实验和真实耗时。
本节用 JDK 25 手写 linkd 的单线程 Reactor:BufferPool、Handler、Connection、EventLoop 四个共享类型,完整实现 accept、read、写队列与 interestOps 开关。给出可运行的 Echo 服务、真实往返输出,并说明线程归属、阻塞 handler 的代价与常见错误。
日志、指标与追踪都接上了,故障时仍然查不出原因,往往是因为采集没有边界。文章说明三种信号各自回答什么问题,用高基数标签打爆时序库的案例解释成本从哪来,并给出可测试的采集审计规则与去重排序实现,帮助团队用最小集覆盖排障所需信息,避免工具越多越慢。
《Java 网络编程基础》6.1 讲 Selector 的 OP_ACCEPT、OP_READ、OP_WRITE 与 interestOps/readyOps 的区别。用 linkd 的真实探针演示 selectedKeys 不 remove 导致就绪位残留、CancelledKeyException、wakeup 唤醒与 macOS kqueue 空轮询防御,给出单线程事件循环的骨架。
FileChannel 能把文件字节送到 socket,但 transferTo 可能只传一部分,非阻塞 channel 还会返回 0。本节用 64 MB 文件在本机 loopback 对比 transferTo 与 64 KB 拷贝循环,讲清 Scatter/Gather、mmap、sendfile 的平台差异,并给出 linkd 静态文件发送的边界。