nginx 1.19.7, njs 0.5.1 ๋ฐ NGINX Unit 1.22.0 ์ถœ์‹œ

nginx 1.19.7์˜ ๋ฉ”์ธ ๋ธŒ๋žœ์น˜๊ฐ€ ์ถœ์‹œ๋˜์—ˆ์œผ๋ฉฐ, ๊ทธ ์•ˆ์—์„œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์˜ ๊ฐœ๋ฐœ์ด ๊ณ„์†๋ฉ๋‹ˆ๋‹ค(๋ณ‘๋ ฌ ์ง€์› ์•ˆ์ • ๋ธŒ๋žœ์น˜ 1.18์—์„œ๋Š” ์‹ฌ๊ฐํ•œ ์˜ค๋ฅ˜ ๋ฐ ์ทจ์•ฝ์  ์ œ๊ฑฐ์™€ ๊ด€๋ จ๋œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋งŒ ์ ์šฉ๋จ).

์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ :

  • ์ž‘์—…์ž ํ”„๋กœ์„ธ์Šค์— ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์—ฐ๊ฒฐ์ด ๋ถ€์กฑํ•ด์ง€๋ฉด nginx๋Š” ์ด์ œ ์—ฐ๊ฒฐ ์œ ์ง€ ์—ฐ๊ฒฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์†Œ์ผ“์ด ๋‹ซํž ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์—ฐ๊ฒฐ๋„ ๋‹ซ์Šต๋‹ˆ๋‹ค("Lingering close").
  • HTTP/2์˜ ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌ ์ฝ”๋“œ๋Š” HTTP/1.x ๊ตฌํ˜„๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์„ค์ • "http2_recv_timeout", "http2_idle_timeout" ๋ฐ "http2_max_requests"์— ๋Œ€ํ•œ ์ง€์›์€ ์ผ๋ฐ˜ ์ง€์‹œ๋ฌธ "keepalive_timeout" ๋ฐ "keepalive_requests"๋ฅผ ์œ„ํ•ด ์ค‘๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • "http2_max_field_size" ๋ฐ "http2_max_header_size" ์„ค์ •์ด ์ œ๊ฑฐ๋˜์—ˆ์œผ๋ฉฐ ๋Œ€์‹  "large_client_header_buffers"๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋™์‹œ์— nginx ์›น ์„œ๋ฒ„์šฉ JavaScript ์ธํ„ฐํ”„๋ฆฌํ„ฐ์ธ njs 0.5.1์ด ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. njs ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” ECMAScript ํ‘œ์ค€์„ ๊ตฌํ˜„ํ•˜๋ฉฐ ๊ตฌ์„ฑ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” nginx์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ํŒŒ์ผ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ์ฒ˜๋ฆฌ, ๊ตฌ์„ฑ ์ƒ์„ฑ, ๋™์ ์œผ๋กœ ์‘๋‹ต ์ƒ์„ฑ, ์š”์ฒญ/์‘๋‹ต ์ˆ˜์ • ๋˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ์Šคํ… ์‹ ์† ์ƒ์„ฑ์„ ์œ„ํ•œ ๊ณ ๊ธ‰ ๋…ผ๋ฆฌ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ ๋ฒ„์ „์—๋Š” "js_header_filter" ์ง€์‹œ๋ฌธ์ด ์ถ”๊ฐ€๋˜์–ด ์ž„์˜์˜ ์‘๋‹ต ํ—ค๋”๋ฅผ ํ•„ํ„ฐ๋งํ•˜๊ณ  ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•œ JavaScript ํ•จ์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. js_import foo.js; ์œ„์น˜ / { js_header_filter foo.filter; ํ”„๋ก์‹œํŒจ์Šค http://127.0.0.1:8081/; } foo.js: function filter(r) { var cookie = r.headersOut['Set-Cookie']; var len = r.args.len ? ๋ฒˆํ˜ธ(r.args.len) : 0; r.headersOut['Set-Cookie'] = cookie.filter(v=>v.length > len); } ๊ธฐ๋ณธ {ํ•„ํ„ฐ} ๋‚ด๋ณด๋‚ด๊ธฐ;

๋˜ํ•œ HTTP ํด๋ผ์ด์–ธํŠธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” Fetch API๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ngx.fetch() ๋ฉ”์„œ๋“œ๋„ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ณธ๋ฌธ, ํ—ค๋”, buffer_size ๋ฐ max_response_body_size ์˜ต์…˜ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ Response ๊ฐ์ฒด๋Š” arrayBuffer(), bodyUsed, json(), headers, ok, Redirect, status, statusText, text(), type ๋ฐ url ๋ฉ”์†Œ๋“œ๋ฅผ ์ง€์›ํ•˜๊ณ  Header ๊ฐ์ฒด๋Š” get(), getAll() ๋ฐ has()๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๋ฒ•. function fetch(r) { ngx.fetch('http://nginx.org/') .then(reply => reply.text()) .then(body => r.return(200, body)) .catch (e => r.return(501, e.message)); }

๋˜ํ•œ ๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด(Python, PHP, Perl, Ruby, Go, JavaScript/Node.js ๋ฐ Java)๋กœ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•˜๋Š” NGINX Unit 1.22 ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์˜ ๊ณต๊ฐœ์— ์ฃผ๋ชฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. NGINX ์œ ๋‹›์€ ๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋กœ ์—ฌ๋Ÿฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋™์‹œ์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ตฌ์„ฑ ํŒŒ์ผ์„ ํŽธ์ง‘ํ•˜๊ณ  ๋‹ค์‹œ ์‹œ์ž‘ํ•  ํ•„์š” ์—†์ด ์‹คํ–‰ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” C๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ Apache 2.0 ๋ผ์ด์„ผ์Šค์— ๋”ฐ๋ผ ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค.

NGINX Unit์˜ ์ƒˆ ๋ฆด๋ฆฌ์Šค๋Š” ์•ˆ์ •์„ฑ ํ–ฅ์ƒ, ํ…Œ์ŠคํŠธ ๋„๊ตฌ ํ™•์žฅ ๋ฐ ๋ฒ„๊ทธ ์ˆ˜์ •์— ์ค‘์ ์„ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค. Linux์šฉ์œผ๋กœ ์ƒ์„ฑ๋œ ํŒจํ‚ค์ง€์—์„œ NGINX ์œ ๋‹›์ด ์‹คํ–‰๋˜๋Š” ์‚ฌ์šฉ์ž ๋ฐ ๊ทธ๋ฃน์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. none:nobody ๋Œ€์‹  ์ด์ œ ๊ทธ๋ฃน ๋‹จ์œ„์˜ ๊ฐœ๋ณ„ ์‚ฌ์šฉ์ž ๋‹จ์œ„๋กœ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. Node.js ๋ชจ๋“ˆ์˜ ServerRequest ๋ฐ ServerResponse ๊ฐ์ฒด์˜ Stream API์™€์˜ ํ˜ธํ™˜์„ฑ์ด ๋ณด์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Python ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ "๊ฒฝ๋กœ" ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : opennet.ru

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€