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
clientshould 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. Andmax_fails,fail_timeoutis if10times request fails occured, shutdown according server until60 secondpassed.
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 toB server. If so,B serverdont have information that you are already logged in. Here Sticky Session in load-balancer makes you to go notB server, but goA serverfor the next request.
B serverhas same function asA 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.
- 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.
- 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 serverandB 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 serverfailed andA server’s session is maintain by onlyA server, every connection is loss.
- 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
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.