What can actually Nginx handle?
포스트
취소

What can actually Nginx handle?

My portfolio site use nginx for reverse proxy. It doesn’t need to have nginx in frontend, because the main purpose of reverse proxy is to hide the backend port(or load-balance). But I made it for the purpose of getting used to nginx.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
http {
	...
    upstream docker-client {
        server client:3000;
    }
    server {
        listen 80;
        # server_name portfolio.hwangbogyumin.com;
        server_name localhost;

        # Frontend React Page
        location / {
            proxy_pass         http://docker-client;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        }
		
		...

    }
    ...
}

Here is a several main functions of Nginx.

1. Request routing

  • With location {path_from}, you can route to other url.

    http://localhost –> http://client:3000

  • This client should be docker container name!
1
2
3
4
gyuminhwangbo@Gyuminui-MacBookPro client % docker ps -a
CONTAINER ID   IMAGE   ...  PORTS                NAMES
363ad79372d0   react-n ...  0.0.0.0:80->80/tcp   nginx
4264e85ea71c   react-c ...  3000/tcp             "client"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
gyuminhwangbo@Gyuminui-MacBookPro client % docker network inspect react-portfolio-website_frontend
[
	{
		"Name": "react-portfolio-website_frontend",
		...
		"Containers": {
			"a387532db6d518ea882c62d985a6b15c1f49f490bc40b36ebb8a525cedffdc1d": {
				"Name": "client",
				...
				"IPv4Address": "172.19.0.3/16",
				...
			},
			...
		},
		...
	}
]

As IPv4Address is definded by Docker, it has dynamic IP address. Thus nginx get this IP address by just saying client to follow dynamic IP address.

So when User request through http://localhost, nginx get this request and pass to http://client:3000(front-end).

2. Load-balancing

1
2
3
4
5
6
7
8
9
10
upstream backend_servers { 
    server server_1:4000; 
    server server_2:4001; 
} 
server { 
    listen 80; 
    location / { 
            proxy_pass  http://backend_servers; 
     }
}
  • Line 1~4 : define server pool called backend_servers with server_1:4000 and server_2:4001
1
2
3
4
gyuminhwangbo@Gyuminui-MacBookPro client % docker ps -a
CONTAINER ID   IMAGE   ...  PORTS       NAMES
363ad79372d0   react-n ...  4000/tcp   server_1
4264e85ea71c   react-c ...  4001/tcp   server_2
  • Line 5~10 : pass http request to backend_servers pool

Here you can also set load-balancing with weight.

1
2
3
4
5
6
7
8
9
10
upstream backend_servers { 
    server server_1:4000 weight=5 max_fails=10 fail_timeout=60s; 
    server server_2:4001 weight=2 max_fails=10 fail_timeout=60s; 
} 
server { 
    listen 80; 
    location / { 
            proxy_pass  http://backend_servers; 
     }
}
  • Line 2: server_1:server_2 = 5:2 is percentage of every reqeust pass. And max_fails,fail_timeout is if 10 times request fails occured, shutdown according server until 60 second passed.

After setting load-balancer and others, you can also set sticky session.

1
2
3
4
5
6
7
8
9
10
11
upstream backend_servers { 
    server server_1:4000 ...; 
    server server_2:4001 ...;
	sticky route $route_cookie $route_uri; 
} 
server { 
    listen 80; 
    location / { 
            proxy_pass  http://backend_servers; 
     }
}

What is Sticky Session?

First request/response server will be handling next request.

  • Advantage
    • Minimized data exchange : When using sticky sessions, servers within your network don’t need to exchange session data, a costly process when done on scale.

      ex) If you login with A server. And by server’s load-balancing, your next reqeust is pass to B server. If so, B server dont have information that you are already logged in. Here Sticky Session in load-balancer makes you to go not B server, but go A server for the next request.
      B server has same function as A server.
      This can be replaced with TOKEN, cookie.

    • RAM cache utilization : Sticky sessions allow for more effective utilization of your application’s RAM cache, resulting in better responsiveness.
  • Disadvantage
    • Reduce performance of Load-balancer : Initial purpose of load-balancing is that make your server to have more scalability and balance the traffic. However, their can be unbalance between A server and B server’s traffic. Because not all the traffic is distributed, but only the initial traffic does.
    • Lack of countermeasure when Session Failed : When if A server failed and A server’s session is maintain by only A server, every connection is loss.

As I said before, sticky session comes up to handle how the servers can sharing their information. And by setting client:server one by one, server can maintain user’s information with stateful. However, pros and cons exist. To handle that issue, token-based methods are emerged.

More information about JWT here, https://ghkdqhrbals.github.io/posts/json-web-token/

1
2
3
4
5
6
7
8
9
10
11
12
13
upstream backend_servers { 
    server server_1:4000 ...; 
    server server_2:4001 ...;
} 
server { 
    listen 80; 
    location / { 
			auth_jwt on;
        	auth_jwt_key_file /etc/nginx/api_secret.jwt; # Secret Key of Server(symmetric key)
			...
        	proxy_pass  http://backend_servers; 
     }
}

To summary, using API Gateway(nginx), you can do balancing the traffics, setting sticky sessions, verify token(jwt), etc.

References

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.