第 13 章 HTTP、TLS 与工程化边界
13.1 使用标准协议时,优先使用标准编解码器
处理 HTTP/1.x 通常从 HttpServerCodec 开始。若希望把分片 HTTP 内容聚合成完整请求,可以再使用有明确大小上限的 HttpObjectAggregator。聚合方便开发,但意味着要在内存中保存整个消息,上传大文件时更应考虑流式处理。
WebSocket 通常先经 HTTP 握手,再升级协议;可研究 WebSocketServerProtocolHandler。WebSocket 帧有边界与控制帧语义,不能把 TCP 行协议的逻辑原样套过去。
本章给出方向,不包含完整 HTTP/WebSocket 工程。主线教学工程始终使用 TCP 行协议,避免在一个入门项目里同时引入太多状态。
13.2 TLS 放在什么位置
TLS 处理通常放在 Pipeline 靠前位置,使后续协议处理器接触解密后的应用数据,出站则先编码再加密。可从 SslContextBuilder 与 SslHandler 的官方说明继续学习。
本机练习可以先明文运行。部署时要根据实际访问范围配置证书、密钥保护、身份验证和权限控制;不能把用于测试的信任所有证书配置复制到正式客户端。
13.3 怎样有序停止服务
一个生产服务常见的停机顺序是:停止接受新连接;停止接收新业务请求;等待进行中的业务在限定时间内结束;关闭现有连接;关闭业务线程池;关闭 EventLoopGroup。
本书主线代码便于阅读,只展示了 EventLoopGroup 的清理。若扩展为常驻服务,应跟踪监听通道、子连接和业务任务,并接入应用生命周期或 shutdown hook。关闭要有期限,不能因为一条慢请求让停机无限等待。
13.4 日志与指标
日志至少要能关联连接、请求编号和异常原因。不要直接把口令、令牌与完整敏感正文写入日志。网络日志处理器能帮助观察字节,但在高流量下会产生大量日志和额外开销。
值得观察的指标包括:活动连接数、连接建立失败数、请求延迟、业务队列长度、超时次数、出站积压和直接内存使用情况。先通过指标确认瓶颈,再考虑调整线程数、TCP 参数或内存分配器。
小练习: 为什么服务端把消息写成功的次数,不能直接当作业务成功次数?