Blog #19
Hãy tưởng tượng bạn đang sở hữu một API production có lượng requests
bất kể ngày đêm, giờ giấc và bạn cần deploy
để update một vài thay đổi. Trong khi deploy
thì Puma
có cơ chế kill current puma.sock
và tạo ra một puma.sock
mới.
Vậy thì có liên quan gì???
Khi một request
được gửi tới server
thì Nginx
sẽ hứng request
đó và gửi đến puma.sock
. Vậy khi request
gửi trong khi Puma
restart thì sao? Thì error 502
chứ sao
Nó làm gián đoạn server
và người dùng sẽ bị ức chế. Kiểu như wtf sao tao đang chạy mà bị lỗi, debug các kiểu xong mới phát hiện ra à là do cái thằng API kia bị lỗi. Vậy thì sẽ giảm chất lượng dịch vụ của bạn đúng không? Rồi dần dần đ*o ai thèm dùng dịch vụ của bạn luôn @@
Trước đây khi chưa biết cơ chế này mình rất ngại deploy
, phải kiếm khung giờ mà ít người dùng nhất và cầu trời đừng có request nào gửi tới khi deploy
, kiểu như lén lút deploy
vậy :D. Thôi bắt đầu cùng mình giải quyết vấn đề nào.
Puma
restart mất đâu đó khoảng 0.1s → hơn 1s chút (đó là đối với các server của mình, các bạn có thể cao hơn)
Vậy chúng ta sẽ bắt Nginx
chờ 10s sau khi Puma
restarted vậy là oke :v
À quên trước khi bắt đầu thì phải cài đặt các nginx modules
thích hợp nha, ở đây chúng ta cần ngx_http_echo_module
$ sudo apt-get install nginx-extras
Gói này bao gồm các modules bổ sung, bao gồm ngx_http_echo_module
.
Cấu hình nginx
lại như sau:
server {
server_name xxx;
root xxx;
# Try serving static files first, then pass to the application
try_files $uri/index.html $uri @app;
# Main location block for proxying requests to the application
location / {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_redirect off;
proxy_set_header Connection '';
proxy_pass upstreams_name;
# Retry requests and handle errors
proxy_intercept_errors on;
error_page 502 @delay;
}
# Delayed location block for retrying requests
location @delay {
proxy_pass upstreams_name;
echo_sleep 10; # Delay for 10 seconds
}
}
Mình thì để 10s
cho an toàn :v các bạn tuỳ chỉnh theo nhu cầu là được.
Reload Nginx:
$ sudo systemctl reload nginx
Vậy là xong rồi nha :D. Giờ đây mình không cần phải lén lút deploy
nữa mà chỉ cần lén lút fix bugs rồi deploy
mà không một ai biết