<div dir="ltr">Hi Roman,<br><br>Thanks a bunch for your quick response, it really made a difference for me.<br><br>I went through Patch 3, and it's pretty cool! And about Patch 4, which also addresses the reload route issue, I would like to share an experience from utilizing this solution in a production environment. Unfortunately, I encountered a significant challenge that surpasses the race condition between bind and connect. Specifically, this solution led to a notable performance degradation in the kernel's UDP packet lookup under high concurrency scenarios. The excessive number of client sockets caused the UDP hash table lookup performance degrade into a linked list, because the udp hashtable is based on target ip and target port hash. To address this lookup performance issue, we implemented a proprietary kernel patch that introduces a 4-tuple hash table for UDP socket lookup. Although effective, it appears that the eBPF solution is more versatile and universal.<br><br>Big thanks again for your attention!<div><br><div>Best Regards,</div><div>Zhenzhong<br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr"><<a href="mailto:nginx-devel-request@nginx.org">nginx-devel-request@nginx.org</a>> 于2024年2月26日周一 20:00写道:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Send nginx-devel mailing list submissions to<br>
<a href="mailto:nginx-devel@nginx.org" target="_blank">nginx-devel@nginx.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
<a href="https://mailman.nginx.org/mailman/listinfo/nginx-devel" rel="noreferrer" target="_blank">https://mailman.nginx.org/mailman/listinfo/nginx-devel</a><br>
or, via email, send a message with subject or body 'help' to<br>
<a href="mailto:nginx-devel-request@nginx.org" target="_blank">nginx-devel-request@nginx.org</a><br>
<br>
You can reach the person managing the list at<br>
<a href="mailto:nginx-devel-owner@nginx.org" target="_blank">nginx-devel-owner@nginx.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of nginx-devel digest..."<br>
<br>
<br>
Today's Topics:<br>
<br>
1. Re: Inquiry Regarding Handling of QUIC Connections During<br>
Nginx Reload (Roman Arutyunyan)<br>
<br>
<br>
----------------------------------------------------------------------<br>
<br>
Message: 1<br>
Date: Mon, 26 Feb 2024 15:49:30 +0400<br>
From: Roman Arutyunyan <<a href="mailto:arut@nginx.com" target="_blank">arut@nginx.com</a>><br>
To: <a href="mailto:nginx-devel@nginx.org" target="_blank">nginx-devel@nginx.org</a><br>
Subject: Re: Inquiry Regarding Handling of QUIC Connections During<br>
Nginx Reload<br>
Message-ID: <20240226114930.izp2quxwsp2usnvg@N00W24XTQX><br>
Content-Type: text/plain; charset=utf-8<br>
<br>
Hi,<br>
<br>
On Sun, Feb 25, 2024 at 03:53:23PM +0800, 上勾拳 wrote:<br>
> Hello,<br>
> <br>
> I hope this email finds you well. I am writing to inquire about the status<br>
> of an issue I have encountered regarding the handling of QUIC connections<br>
> when Nginx is reloaded.<br>
> <br>
> Recently, I delved into the Nginx eBPF implementation, specifically<br>
> examining how QUIC connection packets are handled, especially during Nginx<br>
> reloads. My focus was on ensuring that existing QUIC connection packets are<br>
> correctly routed to the appropriate worker after a reload, and the Nginx<br>
> eBPF prog have done this job perfectly.<br>
> <br>
> However, I observed that during a reload, new QUIC connections might be<br>
> directed to the old worker. The underlying problem stems from the fact that<br>
> new QUIC connections fail to match the eBPF reuseport socket map. The<br>
> kernel default logic then routes UDP packets based on the hash UDP 4-tuple<br>
> in the reuseport group socket array. Since the old worker's listen FDs<br>
> persist in the reuseport group socket array (reuse->socks), there is a<br>
> possibility that the old worker may still be tasked with handling new QUIC<br>
> connections.<br>
> <br>
> Given that the old worker should not process new requests, it results in<br>
> the old worker not responding to the QUIC new connection. Consequently,<br>
> clients have to endure the handshake timeout and retry the connection,<br>
> potentially encountering the old worker again, leading to an ineffective<br>
> cycle.<br>
> <br>
> In my investigation, I came across a thread in the nginx-devel mailing list<br>
> [<a href="https://www.mail-archive.com/nginx-devel@nginx.org/msg10627.html" rel="noreferrer" target="_blank">https://www.mail-archive.com/nginx-devel@nginx.org/msg10627.html</a>], where<br>
> it was mentioned that there would be some work addressing this issue.<br>
> <br>
> Considering my limited experience with eBPF, I propose a potential<br>
> solution. The eBPF program could maintain another eBPF map containing only<br>
> the listen sockets of the new worker. When the eBPF program calls<br>
> `bpf_sk_select_reuseport` and receives `-ENOENT`, it could utilize this new<br>
> eBPF map with the hash UDP 4-tuple to route the new QUIC connection to the<br>
> new worker. This approach aims to circumvent the kernel logic routing the<br>
> packet to the shutting down worker since removing the old worker's listen<br>
> socket from the reuseport group socket array seems unfeasible. Not sure<br>
> about whether this solution is a good idea and I also wonder if there are<br>
> other solutions for this. I would appreciate any insights or updates you<br>
> could provide on this matter. Thank you for your time and consideration.<br>
<br>
It is true QUIC in nginx does not handle reloads well. This is a known issue<br>
and we are working on improving it. I made an effort a while back to address<br>
QUIC reloads in nginx:<br>
<br>
<a href="https://mailman.nginx.org/pipermail/nginx-devel/2023-January/thread.html#16073" rel="noreferrer" target="_blank">https://mailman.nginx.org/pipermail/nginx-devel/2023-January/thread.html#16073</a><br>
<br>
Here patch #3 implements ePBF-based solution and patch #4 implements<br>
client sockets-based solution. The client sockets require extra worker process<br>
privileges to bind to listen port, which is a serious problem for a typical<br>
nginx configuration. The ePBF solution does not seem to have any problems,<br>
but we still need more feedback to proceed with this. If you apply all 4<br>
patches, make sure you disable client sockets using<br>
--without-quic_client_sockets. Otherwise just apply the first 3 patches.<br>
<br>
Here's a relevant trac ticket:<br>
<br>
<a href="https://trac.nginx.org/nginx/ticket/2528" rel="noreferrer" target="_blank">https://trac.nginx.org/nginx/ticket/2528</a><br>
<br>
--<br>
Roman Arutyunyan<br>
<br>
------------------------------<br>
<br>
Subject: Digest Footer<br>
<br>
_______________________________________________<br>
nginx-devel mailing list<br>
<a href="mailto:nginx-devel@nginx.org" target="_blank">nginx-devel@nginx.org</a><br>
<a href="https://mailman.nginx.org/mailman/listinfo/nginx-devel" rel="noreferrer" target="_blank">https://mailman.nginx.org/mailman/listinfo/nginx-devel</a><br>
<br>
<br>
------------------------------<br>
<br>
End of nginx-devel Digest, Vol 162, Issue 26<br>
********************************************<br>
</blockquote></div></div></div></div>