nginx의 next_upstream이 완벽하게 HA를 제공하는지 테스트하는 예시이다.
다음 코드를 참조했다.
https://gist.github.com/bradmontgomery/2219997#file-dummy-web-server-py
#!/usr/bin/env python
"""
Very simple HTTP server in python.
Usage::
./dummy-web-server.py [<port>]
Send a GET request::
curl http://localhost
Send a HEAD request::
curl -I http://localhost
Send a POST request::
curl -d "foo=bar&bin=baz" http://localhost
"""
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import SocketServer
class S(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
self._set_headers()
self.wfile.write("<html><body><h1>hi!</h1></body></html>")
def do_HEAD(self):
self._set_headers()
def do_POST(self):
# Doesn't do anything with posted data
self._set_headers()
self.wfile.write("<html><body><h1>POST!</h1></body></html>")
def run(server_class=HTTPServer, handler_class=S, port=80):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print 'Starting httpd...'
httpd.serve_forever()
if __name__ == "__main__":
from sys import argv
if len(argv) == 2:
run(port=int(argv[1]))
else:
run()
nginx 설정은 다음과 같다.
server {
listen 8888;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://backends;
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
두 디렉토리에 각각 파이썬 simple web server 를 다운받고 포트를 각각 8080, 8081로 바꿔 개별 디렉토리에서 실행한다.
$ python server.py
테스트를 해보면, 정상적으로 잘 동작한다. proxy_pass설정에 따라 처음은 8080, 다음은 8081로 잘 돌아가면서 동작한다.
$ curl http://localhost:8888
<html><body><h1>hi!</h1></body></html>
이번에는 8081포트로 실행한 파이썬 서버에서 GET을 호출시 503 헤더 응답을 보내도록 수정하고 다시 실행한다.
curl로 get 요청을 하나 보낸다.
127.0.0.1 - - [29/Dec/2016 20:51:05] "GET / HTTP/1.1" 503 -
내부적으로 문제가 발생한 것을 보고 8081 파이썬 서버로 GET을 보낸다. (retry 확인)
127.0.0.1 - - [29/Dec/2016 20:51:05] "GET / HTTP/1.1" 200 -
이번에는 8081포트로 실행한 파이썬 서버에 POST를 호출시 503 헤더 응답을 보내도록 수정한다.
http 요청이 8081에 전달되면 에러가 발생한다.
$ curl -X POST http://localhost:8888
<html><body><h1>POST!</h1></body></html>[/usr/local/nginx/conf] curl -X POST http://localhost:8888
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>An error occurred.</h1>
<p>Sorry, the page you are looking for is currently unavailable.<br/>
Please try again later.</p>
<p>If you are the system administrator of this resource then you should check
the <a href="http://nginx.org/r/error_log">error log</a> for details.</p>
<p><em>Faithfully yours, nginx.</em></p>
</body>
</html>
그리고 파이썬 서버에서는 에러가 발생했다.
127.0.0.1 - - [29/Dec/2016 11:56:48] "POST / HTTP/1.1" 503 -
그리고 retry는 되지 않는다. 비멱등 메소드는 retry를 지원하지 않는다.
의외로 nginx의 next stream(proxy_next_upstream)이 완벽한 L7 health check 대용으로 생각하는 분이 많다는 점이다.
1.9.12까지는 비멱등 메소드(POST, LOCK, PATCH)에 대해서 retry를 지원했으나, 1.9.13부터는 비멱등 메소드 호출시 retry를 해주지 않는다.
문서로 명시적으로 설명되어 있다.
Changes with nginx 1.9.13 29 Mar 2016 *) Change: non-idempotent requests (POST, LOCK, PATCH) are no longer passed to the next server by default if a request has been sent to a backend; the "non_idempotent" parameter of the "proxy_next_upstream" directive explicitly allows retrying such requests.
참고로 proxy_request_buffering를 사용한다 하더라도 동일하다.
'nginx' 카테고리의 다른 글
[openresty] lua 처음 다루기 (0) | 2017.01.24 |
---|---|
openresty 1.11.2 설치 (0) | 2017.01.19 |
[nginx+passenger] 설치 (0) | 2016.06.30 |
[nginx] http2 적용하기 (0) | 2016.06.18 |
[nginx] 499 에러 (0) | 2016.06.10 |