您的浏览器禁用了JavaScript(一种计算机语言,用以实现您与网页的交互),请解除该禁用,或者联系我们。 [矩尺网络]:NGINX上实现HTTP3及其性能优化之道 - 发现报告

NGINX上实现HTTP3及其性能优化之道

2023-01-01 矩尺网络 阿杰
报告封面

陶辉矩尺网络CTO 个人介绍 陶辉矩尺网络CTO 《深入理解Nginx》作者极客时间《系统性能优化必知必会》专栏作者视频课《Web协议详解与抓包实战》《Nginx核心知识100讲》讲师腾讯云TVP H T T P 3协 议 概 述 1 目录 s t r e a m层 : 多 路 复 用 2 CONTENTS c o n n e c t i o n层 : 连 接 迁 移 3 性能优化&安全加固 4 01 HTTP3协议概述 队头阻塞:HTTP2 over TCP RTT减少:握手速度的提升 连接迁移的意义:移动网络 HTTP3的特性 •QUIC•报文格式•UDP•Packet•QUIC Frame•HTTP3 Frame•安全•TLS实现•放大攻击防御•连接ID•连接迁移•stream•可靠有序•多路复用•HTTP3•stream流•单向流•推送流•QPACK•控制流•双向流:请求 部署Nginx支持HTTP3 •仅client七层•四层不支持QUIC•拥塞控制算法不可更改•仅RFC9002,类似TCPNewReno•初始拥塞窗口遵循RFC6928•编译 •--with-http_v3_module•--with-cc-opt="-DNGX_QUIC_DEBUG_PACKETS-DNGX_QUIC_DEBUG_CRYPTO“•开启服务•listen 8443quicreuseport;•http3 on;•协议升级•add_headerAlt-Svc 'h3=":8443"; ma=86400'; ngx_min(10*qc->tp.max_udp_payload_size,ngx_max(2*qc->tp.max_udp_payload_size,14720)); 02 stream多路复用 无队头阻塞版多路复用 HTTP3 QPACK Syntax:http3_max_concurrent_streamsnumber;Default:http3_max_concurrent_streams 128;Context:http,server QUIC STREAM 核心概念:抓包分析 •UDP Packet•QUIC Connection•QUIC Packet•QUIC Frame•QUIC Stream•HTTP3 Frame QUIC报文格式--为什么一个UDP报文包含多个Packet? --为什么一个Packet包含多个Frame? QUICStreamFrame Nginx QUIC Frame HTTP Frame:基于QUIC Stream HTTP请求示例 服务器推送 •双向QUIC Stream•HTTP消息•PUSH_PROMISE•由服务器在正常消息流中发送•应在DATA前发送•客户端可先收到失序PUSH流•PUSH ID对应PUSH流•CANCEL_PUSH•客户端/服务器都可发送•通过PUSH ID取消推送•单向QUIC Stream:类型字段•0x00:CONTROL•0x01:PUSH•PUSH ID对应PROMISE帧 流控 •STREAM流层•MAX_STREAM_DATA•通知对端可发送最大数据•STREAM_DATA_BLOCKED•通知对端无法发送 发送状态变迁 typedefenum{NGX_QUIC_STREAM_SEND_READY=0,NGX_QUIC_STREAM_SEND_SEND,NGX_QUIC_STREAM_SEND_DATA_SENT,NGX_QUIC_STREAM_SEND_DATA_RECVD,NGX_QUIC_STREAM_SEND_RESET_SENT,NGX_QUIC_STREAM_SEND_RESET_RECVD}ngx_quic_stream_send_state_e; 接收状态变迁 typedefenum{NGX_QUIC_STREAM_RECV_RECV=0,NGX_QUIC_STREAM_RECV_SIZE_KNOWN,NGX_QUIC_STREAM_RECV_DATA_RECVD,NGX_QUIC_STREAM_RECV_DATA_READ,NGX_QUIC_STREAM_RECV_RESET_RECVD,NGX_QUIC_STREAM_RECV_RESET_READ}ngx_quic_stream_recv_state_e; 03connection连接迁移 建立连接为何1个UDP有多个Packet? •典型Packet•Long Packet Type •Initial•Handshake•0-RTT•Retry•Short Packet•1-RTT •典型Frame•CRYPTO•ACK•STREAM•HANDSHAKE_DONE 超时关连接:HTTP3的指令在哪? CRYPTOFrame Type: CRYPTO (0x0000000000000006)TLSv1.3 Record Layer: Handshake Protocol: Client HelloHandshake Protocol: Client HelloHandshake Type: Client Hello (1)Length: 347Version: TLS 1.2 (0x0303)Extensions Length: 296Extension: quic_transport_parameters (len=69)Type: quic_transport_parameters (57)Length: 69Parameter: max_idle_timeout (len=4) 30000 ms 2023/10/11 09:12:46 [info] 4082546#0:*13 quic client timed out (110:Connection timed out) while handlingquic input, client: 10.1.9.4, server:0.0.0.0:8443 初始传输参数1 Syntax:http3_max_concurrent_streamsnumber;Default:http3_max_concurrent_streams 128;Context:http,server Syntax:http3_stream_buffer_sizesize;Default:http3_stream_buffer_size 64k;Context:http,server Syntax:keepalive_timeouttimeout[header_timeout];Default:keepalive_timeout75s;Context:http,server,location 初始传输参数2 连接ID •QUIC1版本:8-20字节•无连接ID•退化为四元组 连接迁移的限制 Syntax:quic_active_connection_id_limitnumber;Default:quic_active_connection_id_limit2;Context:http,server structngx_quic_connection_s{ngx_queue_tclient_ids;ngx_uint_tnclient_ids;} 连接迁移:多进程负载均衡方案Linux 5.7以上内核 支持QUIC的负载均衡 Syntax:quic_bpfon|off;Default:quic_bpfoff;Context:main 04性能&安全 Generic Segmentation Offload:减少系统调用 Linux 4.18以上版本 Syntax:quic_gsoon|off;Default:quic_gsooff;Context:http,server staticssize_tngx_quic_send_segments(ngx_connection_t*c,u_char *buf,size_t len,structsockaddr*sockaddr,socklen_tsocklen,size_t segment){cmsg->cmsg_level=SOL_UDP;cmsg->cmsg_type=UDP_SEGMENT;valp=(void*)CMSG_DATA(cmsg);*valp=segment;n=ngx_sendmsg(c,&msg,0);} 内核旁路:ByPass的优点 •直接操作网卡•dpdk•xdp•…•协议栈•TCP协议栈•UDP协议栈•IP协议栈 绕过内核协议栈的缺点 gQUIC性能优化历程2017 VS 2020 性能:稳定网络VS高丢包率 放大攻击:客户端地址验证 RFC9002:客户端>1200字节,服务器<3倍响应 Syntax:quic_host_keyfile;Default:—Context:http,server Syntax:quic_retryon|off;Default:quic_retryoff;Context:http,server 开放运维联盟高效运维社区DevOps时代 荣誉出品