Detailed explanation of the pitfalls of nginx proxy socket.io service

Detailed explanation of the pitfalls of nginx proxy socket.io service

Nginx proxies two socket.io servers. The working mode of socket.io is polling upgraded to websocket

Phenomenon

When requesting services through nginx, a large number of 400 errors occurred. Sometimes they could be upgraded to websocket, and sometimes they would keep reporting errors. But when accessing directly through ip+端口, 100% success.

analyze

sid

SID is the key to our problem. When initially creating a connection (polling mode is simulating a long connection), the client will initiate a request like this:

https://***/?EIO=3&transport=polling&t=1540820717277-0

After receiving the message, the server will create an object, bind it to the connection, and return a sid (session id) to mark the session. What does a session mean? A session is a series of interactions, and these interactions are related. In our scenario, when the next http request comes, I need to find the object that was previously bound to the theoretical long connection (there is no websocket here, so it is theoretical). We know that HTTP requests are stateless and each request is independent, so socket.io introduces SID to do this. After receiving the request, the server will generate a sid and look at the response:

Copy the code as follows:
{"sid":"EoGaL3fRQlpTOaLp5eST","upgrades":["websocket"],"pingInterval":8000,"pingTimeout":10000}

Each subsequent request will need to carry this sid, including the one for establishing a websocket request. Therefore, sid is the key to polling and upgrading polling to websocket. The request after this looks like:

https://***/?EIO=3&transport=polling&t=1540820717314-1&sid=EoGaL3fRQlpTOaLp5eST

or

wss://***/?EIO=3&transport=websocket&t=1540820717314-1&sid=EoGaL3fRQlpTOaLp5eST

So the question is, what happens if the SID included in the request is not generated by the server? The server will not recognize it and return a 400 to you, and tell you

invalid sid

This is the problem we encountered. The default load balancing strategy of nginx is polling, so the request may be hit on a machine that is not the one that generated the SID. At this time, we will receive a 400. If we are lucky, it may also be hit on the original machine. If we are luckier, we can even persist until the websocket connection is established.

solve

Here are two solutions

  1. Nginx uses ip_hash for load balancing, which ensures that all requests from a client go to one server.
  2. Do not use polling mode, only use websocket

Both options have their pros and cons. The second one is obvious, old browsers and clients that don't support websockets won't work. The first problem is more hidden. Imagine what would happen if you added or removed machines. At this time, the model of the ip_hash strategy would change, and all previous connections would become invalid. However, for microservices, scaling is a very frequent operation (especially when the product is in the development stage), and this lossy scaling is most likely unacceptable.

In summary, it is recommended to use websocket directly. After all, the old versions that do not support websocket account for a small proportion, and it will take less time than polling first.

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Detailed explanation of nginx reverse proxy webSocket configuration
  • Detailed explanation of the solution to Nginx reverse proxy WebSocket response 403
  • Nginx actual combat reverse proxy WebSocket configuration example
  • Tutorial on using Nginx as a WebSockets proxy
  • Nginx reverse proxy websocket configuration example

<<:  Vue SPA first screen optimization solution

>>:  Solve the error problem caused by modifying mysql data_dir

Recommend

Detailed use cases of MySql escape

MySQL escape Escape means the original semantics ...

An article to solve the echarts map carousel highlight

Table of contents Preface toDoList just do it Pre...

...

Ubuntu Docker installation in vmware (container building)

1. Mind Map 2. How to build a container 2.1 Prepa...

How to implement page jump in Vue project

Table of contents 1. Create a vue-cli default pro...

Detailed explanation of the difference between in and exists in MySQL

1. Prepare in Advance For your convenience, I cre...

Solution to "No input file specified" in nginx+php

Today, the error "No input file specified&qu...

MySQL 8.0.20 installation and configuration tutorial under Win10

MySQL 8.0.20 installation and configuration super...

Vue realizes the function of book shopping cart

This article example shares the specific code of ...

Tkinter uses js canvas to achieve gradient color

Table of contents 1. Use RGB to represent color 2...

Web page comments cause text overflow in IE

The experimental code is as follows: </head>...

Use of Linux sed command

1. Function Introduction sed (Stream EDitor) is a...

Detailed explanation of several examples of insert and batch statements in MySQL

Table of contents Preface 1.insert ignore into 2....

Website background music implementation method

For individual webmasters, how to make their websi...