1. Review of HTTP protocol upgrade mechanism
- Upgrade/Connection Header
When the client initiates a WebSocket handshake, it will be added to a normal HTTP request.
Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: <Random value> Sec-WebSocket-Version: 13
If the server accepts the protocol switch, it will101 Switching Protocols
Response and returnUpgrade
andConnection
Header.
- Hop-by-Hop header limit
In HTTP/1.1,Upgrade
andConnection
All belong to the Hop-by-Hop header, which can only take effect between adjacent nodes and will not be forwarded by ordinary reverse proxy. Therefore, it is necessary to explicitly take these two out of the client request in Nginx and set them to the request header forwarded to the backend.
2. The key configuration of Nginx proxy WebSocket
1. Basic examples
location /chat/ { # Forward the request to the backend WebSocket service proxy_pass http://backend; # Use the HTTP/1.1 protocol to support Upgrade proxy_http_version 1.1; # Forward the Upgrade and Connection headers in the client request to the backend proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
proxy_http_version 1.1
Force HTTP/1.1, otherwise the default HTTP/1.0 cannot support protocol upgrades.
proxy_set_header Upgrade $http_upgrade
Passed the clientUpgrade: websocket
Pass to the backend.
proxy_set_header Connection “upgrade”
Identify andUpgrade
Use together.
2. Intelligent Connection Settings
In some scenarios, I hope to issue only if there is a real need for upgrading"upgrade"
, otherwise keep the connection closed.
Can be used with Nginxmap
Module:
# Map the Upgrade header into variables if it existsmap $http_upgrade $connection_upgrade { default upgrade; '' close; } server { ... location /chat/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } }
- If there is no client request
Upgrade
, then send to the backendConnection: close
, more in line with the semantics of general HTTP requests.
3. Timeout and heartbeat optimization
By default, when Nginx proxys WebSocket connection, if the backend does not have any data back in 60 seconds, it will actively close the connection.
This is not friendly for scenarios where you are idle for a long time but may still have to push messages in the future.
There are two commonly used optimization solutions:
1. Extend Nginx'sproxy_read_timeout
existlocation
orhttp
、server
Level Add:
proxy_read_timeout 3600s; # Increase the timeout to 1 Hour
2. Backend sending WebSocket Ping
Let the backend application periodically send ping frames to the client (via Nginx), triggering Nginx to read data, thus resetting the timeout timer, and detecting the connection health status.
4. Complete example
http { map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream backend { server 127.0.0.1:8080; # Backend WebSocket service address # Multiple servers can be added according to actual conditions to achieve load balancing } server { listen 80; server_name ; # Static resource processing (optional) location /static/ { root /var/www/html; } # WebSocket proxy portal location /chat/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # Forward the client's real IP (optional) proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Timeout configuration proxy_read_timeout 3600s; proxy_send_timeout 3600s; } } }
5. Practical points and precautions
- HTTPS + WSS
If used on the front endwss://
(i.e. TLS-encrypted WebSocket), the corresponding SSL certificate must be configured on Nginx and theserver
Used in blocksssl_certificate
、ssl_certificate_key
Wait for instructions.
- Load balancing and Sticky Session
For services that require session consistency across multiple instances, consider Sticky Session configuration based on cookies or IP hashing, or design the service as stateless.
- Safety reinforcement
Can be added in Nginxlimit_conn
、limit_req
Equal current limiting instructions to prevent malicious connections from exhausting resources;lua-nginx-module
Implement more complex authentication or dynamic routing.
Summarize
Through the above method, Nginx can efficiently and stably forward the client's HTTP upgrade request (Upgrade) to the backend WebSocket service, realizing reverse proxy and load balancing.
On this basis, combined with reasonable timeout adjustment, heartbeat detection and safe current limit, a highly available and scalable real-time communication platform for the production environment can be built.
I hope this article can help you quickly get started with Nginx WebSocket agents and create a real-time architecture that meets business needs.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.