<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nginx on</title><link>https://taetaetae.github.io/tags/nginx/</link><description>Recent content in Nginx on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 01 Jul 2018 02:00:00 +0000</lastBuildDate><atom:link href="https://taetaetae.github.io/tags/nginx/index.xml" rel="self" type="application/rss+xml"/><item><title>초간단 API서버 만들기 - 2부 (Python + Flask + Nginx)</title><link>https://taetaetae.github.io/2018/07/01/simple-web-server-flask-nginx/</link><pubDate>Sun, 01 Jul 2018 02:00:00 +0000</pubDate><guid>https://taetaetae.github.io/2018/07/01/simple-web-server-flask-nginx/</guid><description>&lt;p>&lt;a href="https://taetaetae.github.io/2018/07/01/simple-web-server-flask-apache/" target="_blank" rel="noopener noreffer ">지난포스팅&lt;/a>에 이어 이번엔 Flask와 Nginx를 연동하는 방법을 정리해보고자 한다. Apache로 연동했는데 왜 또 Nginx로 연동하는걸 정리하지(?)하며 의문이 들수 있는데 다른 포스팅을 봐도 &lt;!-- more --> Apache + Flask 조합보다 Nginx + Flask 조합이 더 많고 지난 포스팅에서도 알수있었듯이 (&lt;a href="https://taetaetae.github.io/2018/06/27/apache-vs-nginx/" target="_blank" rel="noopener noreffer ">Apache VS Nginx&lt;/a>) 둘중 어느것이 좋다고 할수도 없고 각 상황에서 연동하는 방법을 알고 있다면 이 또한 나만의 무기가 될것같아 Nginx를 연동하는 방법을 정리해보려 한다.&lt;/p>
&lt;p>1부에서 왜 Flask인가, Flask의 장점에 대해 정리를 했으니 이번 포스팅에서는 별도로 작성하진 않는다.&lt;/p>
&lt;h2 id="nginx-설치---">Nginx 설치 ( &lt;a href="https://nginx.org/en/" target="_blank" rel="noopener noreffer ">https://nginx.org/en/&lt;/a> )&lt;/h2>
&lt;p>역시 소스설치를 한다.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> 다운을 받고
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ https://nginx.org/download/nginx-1.14.0.tar.gz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> 압축을 푼 다음
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ tar -zxvf nginx-1.14.0.tar.gz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> 폴더로 이동해서 
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ cd nginx-1.14.0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> 설치할 디렉토리를 설정하고
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ ./configure --prefix=/~~~/apps/nginx
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> make 파일을 만들고
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ make
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> 설치를 진행한다.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ make install
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>이렇게 하면 일단 Nginx는 설치가 되었다.&lt;/p>
&lt;h2 id="uwsgi-설치---">uWSGI 설치 ( &lt;a href="https://uwsgi-docs.readthedocs.io/" target="_blank" rel="noopener noreffer ">https://uwsgi-docs.readthedocs.io/&lt;/a> )&lt;/h2>
&lt;p>앞서 Apache와 연동할때는 별도의 모듈을 Apache에게 등록하는 형태였다면 Nginx는 WSGI프로토콜을 활용하는 WSGI 어플리케이션을 실행하는 어플리케이션 서버를 활용해야 한다.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> 다운을 받고
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ wget https://projects.unbit.it/downloads/uwsgi-latest.tar.gz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> 압축을 풀고
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ tar zxvf uwsgi-latest.tar.gz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> 폴더로 이동하여
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ cd uwsgi-2.0.17
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> make 명령어를 호출하면 &amp;#39;uwsgi&amp;#39;이라는 실행파일이 생성된다.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ make
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="nginx-설정">Nginx 설정&lt;/h2>
&lt;p>Apache와 비슷하게 uWSGI 관련 설정을 해준다.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">server {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> listen 80;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> server_name localhost;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> location / { # ( / ) 경로로 들어올 경우
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> include uwsgi_params; # GET/POST 등 기본적으로 필요한 환경변수를 include 해준다.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> uwsgi_pass 127.0.0.1:3031; # 요청을 IP:PORT로 전달한다.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>별도의 모듈을 사용하지 않기때문에 전달해주는 (proxy느낌) 설정을 해준다.&lt;/p>
&lt;h2 id="uwsgi-실행-및-nginx-재시작">uWSGI 실행 및 Nginx 재시작&lt;/h2>
&lt;p>앞서 설치한 &lt;code>uwsgi&lt;/code>를 아래처럼 IP:port 를 명시적으로 적어주고 (위에서 전달받은 IP:PORT와 동일하게) Apache 연동시 활용했던 wsgi파일을 이번에도 동일하게 사용하도록 해서 실행한다.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$ ./uwsgi -s 127.0.0.1:3031 --wsgi-file /~~~/python_app/hello_world.wsgi
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>이렇게 하면 background로 실행되는게 아닌 foreground로 실행되기 때문에 &lt;code>&amp;amp;&lt;/code>을 사용한다던지 해서 background로 실행되도록 해준다. 그후 Nginx를 재시작 해주면 원하는 그토록 원했던 &lt;code>Hello World!&lt;/code>를 만날수가 있게 된다.&lt;/p>
&lt;p>Apache연동과 조금 다른점은 모듈을 사용하지않고 별도의 전달 어플리케이션(?)이 필요하다는점이다. 간단히 Apache처럼 모듈만 넣으면 되는게 아니라서 불편할수도 있을것 같지만 한편으로는 관리할수있는 포인트가 더 늘어난 셈이라 어떤 측면에서는 활용할수 있는 방법이 하나 늘어난것으로 볼수도 있다.&lt;/p>
&lt;h2 id="마치며">마치며&lt;/h2>
&lt;p>막상 정리하고 나면 아무것도 아닌데 알기 위해서 몸부림을 쳐가며 책이며 구글링을 하는 과정을 통해 점점 성장을 하는것 같다. (성장통이라고나 할까) 이렇게 단순히 Flask를 할수있다 가 아닌 웹서버를 연동할수있다. 그것도 Apache와 Nginx 두개나. 이것도 언젠간 나만의 무기가 되지 않을까?&lt;/p></description></item><item><title>Apache냐 Nginx냐, 그것이 알고싶다.</title><link>https://taetaetae.github.io/2018/06/27/apache-vs-nginx/</link><pubDate>Wed, 27 Jun 2018 17:17:33 +0000</pubDate><guid>https://taetaetae.github.io/2018/06/27/apache-vs-nginx/</guid><description>&lt;p>웹서버는 HTTP 프로토콜을 통해 읽힐수 있는 문서를 처리를 하며 일반적으로 웹 어플리케이션의 앞단에 배치되곤 한다. 동적인 리소스는 WAS에게 처리하도록 하고 정적인 리소스를 보다 효율적으로 처리하기 위한 방법일수도 있다. 크게 Apache와 Nginx가 사용되곤 하는데 이 둘의 차이는 무엇일까?&lt;!-- more --> 사실 필자는 사내에서 주로 Apache만 사용하다보니 Nginx는 그저 &lt;code>Apache와는 다른 방식의 웹서버다&lt;/code> 또는 &lt;code>보다 경량화 되었다&lt;/code> 정도로만 알고있었는데 이번기회를 통해 제대로 알고 비교를 해보면서 결국 어떤게 좋은지 알아보고자 한다.&lt;/p>
&lt;blockquote>
&lt;p>구글링을 조금만 해보면 Apache와 Nginx를 비교하는 포스팅이 많이 나온다. 이번 포스팅의 목적 이러한 정보들을 단순히 요약/종합 하려는게 아니고, 최대한 실무 서비스를 운영하는 시각으로 정리하고자 함을 밝힌다.&lt;/p>&lt;/blockquote>
&lt;h2 id="apache---">Apache ( &lt;a href="https://httpd.apache.org/" target="_blank" rel="noopener noreffer ">https://httpd.apache.org/&lt;/a> )&lt;/h2>
&lt;p>우리나라에서 웹어플리케이션을 개발하는 사람들은 한번쯤은 들어봤을 &lt;code>Apache&lt;/code>. 국내 일반적인 기업에서 웹서버의 표준으로 자리잡았다고 해도 과언이 아닐것 같다. Client에서 요청을 받으면 MPM (Multi Processing Module : 다중처리모듈) 이라는 방식으로 처리를 하는데 대표적으로는 Prefork와 Worker방식이 있다. 간단하게 어떤식으로 처리하는지 알고 넘어가자.&lt;/p>
&lt;ul>
&lt;li>Prefork MPM
&lt;figure>&lt;a class="lightgallery" href="https://taetaetae.github.io/images/apache-vs-nginx/prefork.gif" title="/images/apache-vs-nginx/prefork.gif" data-thumbnail="/images/apache-vs-nginx/prefork.gif" data-sub-html="&lt;h2>Prefork MPM, http://old.zope.org/Members/ike/Apache2/osx/configure_html&lt;/h2>">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/apache-vs-nginx/prefork.gif"
 data-srcset="https://taetaetae.github.io/images/apache-vs-nginx/prefork.gif, https://taetaetae.github.io/images/apache-vs-nginx/prefork.gif 1.5x, https://taetaetae.github.io/images/apache-vs-nginx/prefork.gif 2x"
 data-sizes="auto"
 alt="/images/apache-vs-nginx/prefork.gif" />
 &lt;/a>&lt;figcaption class="image-caption">Prefork MPM, &lt;a href="http://old.zope.org/Members/ike/Apache2/osx/configure_html" target="_blank" rel="noopener noreffer ">http://old.zope.org/Members/ike/Apache2/osx/configure_html&lt;/a>&lt;/figcaption>
 &lt;/figure>&lt;/li>
&lt;/ul>
&lt;p>실행중인 프로세스를 복제되어 처리가 된다. 각 프로세스는 한번에 한 연결만 처리하고 요청량이 많아질수록 프로세스는 증가하지만 복제시 메모리영역까지 복제되어 동작하므로 프로세스간 메모리 공유가 없어 안정적이라 볼수 있다.&lt;/p>
&lt;ul>
&lt;li>Worker MPM
&lt;figure>&lt;a class="lightgallery" href="https://taetaetae.github.io/images/apache-vs-nginx/worker.gif" title="/images/apache-vs-nginx/worker.gif" data-thumbnail="/images/apache-vs-nginx/worker.gif" data-sub-html="&lt;h2>Worker MPM, http://old.zope.org/Members/ike/Apache2/osx/configure_html&lt;/h2>">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/apache-vs-nginx/worker.gif"
 data-srcset="https://taetaetae.github.io/images/apache-vs-nginx/worker.gif, https://taetaetae.github.io/images/apache-vs-nginx/worker.gif 1.5x, https://taetaetae.github.io/images/apache-vs-nginx/worker.gif 2x"
 data-sizes="auto"
 alt="/images/apache-vs-nginx/worker.gif" />
 &lt;/a>&lt;figcaption class="image-caption">Worker MPM, &lt;a href="http://old.zope.org/Members/ike/Apache2/osx/configure_html" target="_blank" rel="noopener noreffer ">http://old.zope.org/Members/ike/Apache2/osx/configure_html&lt;/a>&lt;/figcaption>
 &lt;/figure>&lt;/li>
&lt;/ul>
&lt;p>Prefork 동작방식이 1개의 프로세스가 1개의 스레드로 처리가 되었다면 Worker 동작방식은 1개의 프로세스가 각각 여러 쓰레드를 사용하게 된다. 쓰레드간의 메모리를 공유하며 PreFork방식보다 메모리를 덜 사용하는 장점이 있다.&lt;/p>
&lt;p>참고로 WAS로 tomcat을 연동하는 경우라면 &lt;a href="https://tomcat.apache.org/download-connectors.cgi" target="_blank" rel="noopener noreffer ">mod_jk&lt;/a>, &lt;a href="https://httpd.apache.org/docs/2.4/mod/mod_proxy.html" target="_blank" rel="noopener noreffer ">mod_proxy&lt;/a>, &lt;a href="https://httpd.apache.org/docs/2.4/mod/mod_proxy_ajp.html" target="_blank" rel="noopener noreffer ">mod_proxy_ajp&lt;/a> 방식을 Apache 자체적으로 지원해주기 때문에 다양하고 효율적으로 tomcat을 연동할수 있다. &lt;a href="https://www.lesstif.com/pages/viewpage.action?pageId=12943367" target="_blank" rel="noopener noreffer ">참고링크&lt;/a>&lt;/p>
&lt;h2 id="nginx---">Nginx ( &lt;a href="https://nginx.org/en/" target="_blank" rel="noopener noreffer ">https://nginx.org/en/&lt;/a> )&lt;/h2>
&lt;p>Nginx에 대해 살펴보기 전에 &lt;a href="https://trends.google.co.kr" target="_blank" rel="noopener noreffer ">구글 트랜드&lt;/a>를 활용하여 Nginx에 대한 관심이 어느정도인지를 보고 넘어가자.&lt;/p>
&lt;figure>&lt;a class="lightgallery" href="https://taetaetae.github.io/images/apache-vs-nginx/google-trand.png" title="/images/apache-vs-nginx/google-trand.png" data-thumbnail="/images/apache-vs-nginx/google-trand.png" data-sub-html="&lt;h2>최근 5년간 구글트랜드, 파란색이 Apache이고 빨간색이 Nginx&lt;/h2>">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/apache-vs-nginx/google-trand.png"
 data-srcset="https://taetaetae.github.io/images/apache-vs-nginx/google-trand.png, https://taetaetae.github.io/images/apache-vs-nginx/google-trand.png 1.5x, https://taetaetae.github.io/images/apache-vs-nginx/google-trand.png 2x"
 data-sizes="auto"
 alt="/images/apache-vs-nginx/google-trand.png" />
 &lt;/a>&lt;figcaption class="image-caption">최근 5년간 구글트랜드, 파란색이 Apache이고 빨간색이 Nginx&lt;/figcaption>
 &lt;/figure>
&lt;p>전세계는 Nginx보다는 Apache에 대한 관심이 많은것으로 보이는데 국내는 아주 조금씩 Nginx에 대한 관심이 오르는것을 볼수있었다. (그래도 아직은 Apache가 월등히 우세한 편이다.)
그럼 Nginx는 어떤식으로 돌아가는 것일까? 가장 유명한(?) 특징이라면 &lt;code>Event Driven 방식&lt;/code>을 꼽을수 있을것 같다. Event Driven 방식에 대해 잠깐 언급을 하고 넘어가면 요청이 들어오면 어떤 동작을 해야하는지만 알려주고 다른요청을 처리하는 방식이다. (&lt;a href="https://dzone.com/articles/producer-consumer-pattern" target="_blank" rel="noopener noreffer ">Producer Consumer Pattern&lt;/a>과 유사하다.) 그러다보니 프로세스를 fork하거나 쓰레드를 사용하는 아파치와는 달리 CPU와 관계없이 모든 IO들을 전부 Event Listener로 미루기 때문에 흐름이 끊기지 않고 응답이 빠르게 진행이 되어 1개의 프로세스로 더 빠른 작업이 가능하게 될수 있다. 이때문에 메모리적인 측면에서 Nginx가 System Resource를 적게 처리한다는 장점이 있다고 한다.&lt;/p>
&lt;figure>&lt;a class="lightgallery" href="https://taetaetae.github.io/images/apache-vs-nginx/nginx_process_model.png" title="/images/apache-vs-nginx/nginx_process_model.png" data-thumbnail="/images/apache-vs-nginx/nginx_process_model.png" data-sub-html="&lt;h2>Nginx Process Model (https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale)&lt;/h2>">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/apache-vs-nginx/nginx_process_model.png"
 data-srcset="https://taetaetae.github.io/images/apache-vs-nginx/nginx_process_model.png, https://taetaetae.github.io/images/apache-vs-nginx/nginx_process_model.png 1.5x, https://taetaetae.github.io/images/apache-vs-nginx/nginx_process_model.png 2x"
 data-sizes="auto"
 alt="/images/apache-vs-nginx/nginx_process_model.png" />
 &lt;/a>&lt;figcaption class="image-caption">Nginx Process Model (&lt;a href="https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale" target="_blank" rel="noopener noreffer ">https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale&lt;/a>)&lt;/figcaption>
 &lt;/figure>
&lt;h2 id="그래서-뭐가-좋은가">그래서 뭐가 좋은가?&lt;/h2>
&lt;p>이 포스팅을 적으면서 마지막엔 &lt;code>Apache가 더좋다&lt;/code> 또는 &lt;code>Nginx가 더좋다&lt;/code>로 마무리를 짓고 싶었는데 어느 시사/교양 프로그램처럼 어쩔수 없는 &lt;code>열린결말&lt;/code>로 마무리를 지을수밖에 없을것 같다. (어찌보면 이게 정답일수도?)&lt;/p>
&lt;p>기술의 선택에 있어서 정답은 없는것 같다.(물론 Spring 을 사용하느냐 서블릿을 직접 구현하는냐 와는 좀 다른 성격의 이야기;;) 운영하고 있는 서비스의 상황을 잘 알고 튜닝을 해가면서 가장 효율적인것을 선택하는게 정답이라고 말할수 밖에&amp;hellip; 커뮤니티 파워를 무시 못하기 때문에 Apache를 선택할수도 있을테고, 점점 관심도가 올라간다는건 그만큼의 장점이 있고 또한 메모리 측면에서 동접자 처리시 효율적인 Nginx를 사용할수 있을것 같다.&lt;/p></description></item></channel></rss>