• nginx - The Architecture of Open Source Applications

  • nginx - 오픈소스 애플리케이션의 아키텍처 (AOSA)

  • nginx (pronounced "engine x") is a free open source web server written by Igor Sysoev, a Russian software engineer. Since its public launch in 2004, nginx has focused on high performance, high concurrency and low memory usage. Additional features on top of the web server functionality, like load balancing, caching, access and bandwidth control, and the ability to integrate efficiently with a variety of applications, have helped to make nginx a good choice for modern website architectures. Currently nginx is the second most popular open source web server on the Internet.
  • nginx ("엔진 엑스"로 읽음) 는 러시아의 소프트웨어 엔지니어인 Igor Sysoev가 만든 무료 오픈소스 웹 서버다. 프로젝트가 공개된 2004년 이래로 nginx는 고성능과 높은 동시 처리 능력, 그리고 보다 적은 메모리 사용에 집중해 왔다. 웹 서버로의 기능뿐 아니라 로드밸런싱, 캐싱, 접근과 전송량 제어, 다양한 애플리케이션과의 효율적인 결합성도 갖추고 있어, nginx를 통해 최신의 웹 사이트 아키텍처를 구축할 수 있다. 현재 nginx는 인터넷에서 두번째로 인기있는 오픈소스 웹 서버다.
  • 14.1. Why Is High Concurrency Important?

  • 14.1. 왜 높은 동시 처리량이 중요한가?

  • These days the Internet is so widespread and ubiquitous it's hard to imagine it wasn't exactly there, as we know it, a decade ago. It has greatly evolved, from simple HTML producing clickable text, based on NCSA and then on Apache web servers, to an always-on communication medium used by more than 2 billion users worldwide. With the proliferation of permanently connected PCs, mobile devices and recently tablets, the Internet landscape is rapidly changing and entire economies have become digitally wired. Online services have become much more elaborate with a clear bias towards instantly available live information and entertainment. Security aspects of running online business have also significantly changed. Accordingly, websites are now much more complex than before, and generally require a lot more engineering efforts to be robust and scalable.
  • 요즘의 인터넷은 예전에는 어떠했는지 상상하기 어려울 정도로 광범위하게 퍼져 언제 어디서든 접속할 수 있게 되었다. NCSA(역주:National Center for Supercomputing Applications)의 클릭 가능한 텍스트로 이뤄진 단순한 HTML에서, 아파치 웹 서버를 통해 세계적으로 20억명 이상이 상시 접속해 사용하는 커뮤니케이션 매체로 엄청난 발전을 이루었다. 늘 연결되있는 PC뿐 아니라 태블릿과 각종 모바일 장치들의 증가로 인터넷 환경은 빠르게 변화하여, 모든 경제 활동이 디지털로 긴밀하게 연결되었다. 온라인 서비스는 즉시 이용 가능한 실시간 정보와 엔터테인먼트를 수용하기 위해 발전하고 있으며, 온라인 비지니스 운영에 대한 보안사항도 확연히 달라지고 있다. 이에, 웹사이트는 예전보다 훨씬 복잡해졌으며, 확장 가능하며 견고한 서비스를 위해 보다 많은 엔지니어링이 필요하다.
  • One of the biggest challenges for a website architect has always been concurrency. Since the beginning of web services, the level of concurrency has been continuously growing. It's not uncommon for a popular website to serve hundreds of thousands and even millions of simultaneous users. A decade ago, the major cause of concurrency was slow clients—users with ADSL or dial-up connections. Nowadays, concurrency is caused by a combination of mobile clients and newer application architectures which are typically based on maintaining a persistent connection that allows the client to be updated with news, tweets, friend feeds, and so on. Another important factor contributing to increased concurrency is the changed behavior of modern browsers, which open four to six simultaneous connections to a website to improve page load speed.
  • 웹 사이트 아키텍처의 가장 큰 과제중 하나는 바로 동시 처리량이다. 웹 서비스 초창기부터 동시 접속자 수준은 지속적으로 증가해왔다. 유명 사이트들이 적게는 수십만에서 수백만의 동시 접속자를 수용하는 것을 찾기 힘들지 않다. 10여년전 동시 접속자 제한의 주요 원인은 ADSL 이나 모뎀 접속과 같은 방법을 이용하는 사용자들의 느린 클라이언트 때문이었다. 하지만 최근 동시 접속자 수준은 각종 모바일 클라이언트의 조합이나 뉴스, 트윗, 친구들의 피드 등이 꾸준히 업데이트되는 클라이언트를 위한 지속적인 연결을 가능하게 해주는 새로운 어플리케이션 구조들에 의해 영향을 받는다. 또한 동시 접속자 수가 증가하는데 주요한 요소는 페이지 로딩 속도를 증가시키기 위한 4개에서 6개의 동시 접속을 진행하는 최신 브라우저의 연결 방식 때문이다.
  • To illustrate the problem with slow clients, imagine a simple Apache-based web server which produces a relatively short 100 KB response—a web page with text or an image. It can be merely a fraction of a second to generate or retrieve this page, but it takes 10 seconds to transmit it to a client with a bandwidth of 80 kbps (10 KB/s). Essentially, the web server would relatively quickly pull 100 KB of content, and then it would be busy for 10 seconds slowly sending this content to the client before freeing its connection. Now imagine that you have 1,000 simultaneously connected clients who have requested similar content. If only 1 MB of additional memory is allocated per client, it would result in 1000 MB (about 1 GB) of extra memory devoted to serving just 1000 clients 100 KB of content. In reality, a typical web server based on Apache commonly allocates more than 1 MB of additional memory per connection, and regrettably tens of kbps is still often the effective speed of mobile communications. Although the situation with sending content to a slow client might be, to some extent, improved by increasing the size of operating system kernel socket buffers, it's not a general solution to the problem and can have undesirable side effects.
  • 느린 클라이언트들로 인한 문제를 살펴보기 위해, 상대적으로 작은 100KB 정도 크기의 텍스트나 이미지로 구성된 웹 페이지 응답을 보내주는 단순한 아파치 기반 웹 서버를 상상해보자. 페이지를 생성하고 받아오는데 단순히 매우 짧은 시간이 소요될 수 있지만, 80kbps(10KB/s)의 대역폭을 갖는 클라이언트에게 전송하는데에는 10초가 걸린다. 기본적으로 웹서버는 상대적으로 빠른 속도로 100KB 의 컨텐트를 생성해내지만, 컨넥션을 잃기 전에 클라이언트로 그 컨텐트를 천천히 보내는데 10초동안 바쁜 상태일 수 있다. 이번에는 비슷한 컨텐트를 요청하는 1000개의 동시 접속된 클라이언트를 생각해보자. 클라이언트당 오직 1MB의 추가적인 메모리가 할당된다면, 100KB 씩 1000 클라이언트를 서비스하는데 1000MB(약1GB)의 추가 메모리가 소모되어야 한다. 현실에서는 아파치 기반의 일반적인 웹 서버는 흔히 연결당 1MB 이상의 메모리를 할당하고, 슬프게도 아직 수십 kbps 정도가 모바일 통신에서의 유효한 통신 속도이다. 느린 클라이언트로 컨텐트를 보내는 상황이 운영체제의 커널 소켓 버퍼 사이즈를 증가시켜 다소 개선된다고 하더라도, 그것은 일반적이지 않은 솔루션이며, 기대하지 않은 부작용을 일으킬 수 있다.
  • With persistent connections the problem of handling concurrency is even more pronounced, because to avoid latency associated with establishing new HTTP connections, clients would stay connected, and for each connected client there's a certain amount of memory allocated by the web server.
  • 새로운 http 연결을 하는데 소요되는 latency 를 피하기 위해 클라이언트들이 접속을 유지하려고 하며, 각각의 연결된 클라이언트들이 웹서버에 일정의 메모리 할당을 점유하기 때문에, 지속적인 연결로 인한 동시 접속 처리의 문제가 더 강조될 수 있다.
  • Consequently, to handle the increased workloads associated with growing audiences and hence higher levels of concurrency—and to be able to continuously do so—a website should be based on a number of very efficient building blocks. While the other parts of the equation such as hardware (CPU, memory, disks), network capacity, application and data storage architectures are obviously important, it is in the web server software that client connections are accepted and processed. Thus, the web server should be able to scale nonlinearly with the growing number of simultaneous connections and requests per second.
  • 결과적으로, 증가하는 사용자와 높은 수준의 동시연결로 인한 부하를 현재 뿐 아니라 앞으로도 계속 처리해내기 위해서 웹사이트는 매우 효율적인 조각들 위에 구축되어야 한다. 하드웨어(CPU, 메모리, 디스크), 네트워크 용량, 애플리케이션과 데이터의 저장 구조와 같은 것들도 물론 중요하지만 클라이언트와의 연결이 이루어지고 처리되는 곳은 바로 웹서버다. 그러므로 웹서버는 증가하는 동시접속과 요청을 비선형적으로 감당할 수 있어야 한다.
  • Isn't Apache Suitable?

  • 아파치는 적합하지 않은가?

  • Apache, the web server software that still largely dominates the Internet today, has its roots in the beginning of the 1990s. Originally, its architecture matched the then-existing operating systems and hardware, but also the state of the Internet, where a website was typically a standalone physical server running a single instance of Apache. By the beginning of the 2000s it was obvious that the standalone web server model could not be easily replicated to satisfy the needs of growing web services. Although Apache provided a solid foundation for future development, it was architected to spawn a copy of itself for each new connection, which was not suitable for nonlinear scalability of a website. Eventually Apache became a general purpose web server focusing on having many different features, a variety of third-party extensions, and universal applicability to practically any kind of web application development. However, nothing comes without a price and the downside to having such a rich and universal combination of tools in a single piece of software is less scalability because of increased CPU and memory usage per connection.
  • 아직까지도 인터넷을 호령하고 있는 웹 서버인 아파치는 1990년대 초반에 그 뿌리를 두고 있다. 아파치의 아키텍쳐는 당시의 운영체제와 하드웨어 그리고 인터넷의 상황에 어울리는 것이었다. 당시 웹사이트는 하나의 독립적이고 물리적인 서버에서 동작하는 하나의 아파치 인스턴스에 불과했다. 하지만 2000년대 초반에 와서 이 독립된 웹서버 모델은 더 이상 증가하는 웹서비스의 요구를 충족시킬만큼 쉽게 복제될 수 없었다. 아파치가 향후 개발을 위한 튼튼한 기반을 제공하기는 했지만 새로운 연결마다 스스로의 복사본을 만들도록 설계되었고 이것은 웹사이트의 비선형적인 확장에 적합하지 않은 것이었다. 결과적으로 아파차는 다양한 기능과 3rd-party 확장기능들 그리고 어떠한 웹 애플리케이션 개발에도 적용 가능한 범용 웹서버가 되었지만 하나의 소프트웨어에 그렇게 많은 범용적인 기능들을 포함하고 있어 접속당 CPU와 메모리 사용량이 증가함으로서 확장성이 떨어진다는 단점을 가지게 됐다.
  • Thus, when server hardware, operating systems and network resources ceased to be major constraints for website growth, web developers worldwide started to look around for a more efficient means of running web servers. Around ten years ago, Daniel Kegel, a prominent software engineer, proclaimed that "it's time for web servers to handle ten thousand clients simultaneously" and predicted what we now call Internet cloud services. Kegel's C10K manifest spurred a number of attempts to solve the problem of web server optimization to handle a large number of clients at the same time, and nginx turned out to be one of the most successful ones.
  • 이리하여, 하드웨어와 OS 및 네트웍 자원이 웹사이트 성장에 있어 중대한 제약으로 중단 되었을 때, 전 세계의 웹개발자들은 웹서버 구동을 위한 좀 더 효과적인 방법을 찾기 시작했다.
    약 10년 전 쯤, 유명한 소프트웨어 엔지니어인 다니엘 케겔이 "웹서버가 10K의 동시 요청을 처리해야 할 때이다." 라고 선언하였고, 요즘 우리가 인터넷 클라우드 서비스라고 부르는 환경에 대하여 예측했다.
    케겔의 C10K는 대량의 클라이언트를 관리하기 위한 웹서버 최적화 문제를 해결하기 위한 시도에 박차를 가했으며, 동시에 nginx는 가장 성공적인 웹서버 중의 하나일 것으로 보였다.
  • Aimed at solving the C10K problem of 10,000 simultaneous connections, nginx was written with a different architecture in mind—one which is much more suitable for nonlinear scalability in both the number of simultaneous connections and requests per second. nginx is event-based, so it does not follow Apache's style of spawning new processes or threads for each web page request. The end result is that even as load increases, memory and CPU usage remain manageable. nginx can now deliver tens of thousands of concurrent connections on a server with typical hardware.
  • 동시 접속자 수가 1만 명일 때의 C10K 문제해결을 목표로 한, nginx는 다른 아키텍처로--동시 연결성과 초당 요청건수 두 가지 측면에서 비선형적 확장성에 훨씬 더 적합하게--만들어졌다.
    nginx는 event-based 이기 때문에 apache와 같이 각각의 웹페이지 요청을 처리하기 위해서 새로운 process나 thread를 생성하지 않는다. 그래서 부하는 증가하더라도 메모리나 CPU usage는 관리할 수 있는 상태로 남아 있는다. nginx는 현재 일반적인 하드웨어로 구성된 단일 서버에서 수만개의 동시 connection을 처리할 수 있다.
  • When the first version of nginx was released, it was meant to be deployed alongside Apache such that static content like HTML, CSS, JavaScript and images were handled by nginx to offload concurrency and latency processing from Apache-based application servers. Over the course of its development, nginx has added integration with applications through the use of FastCGI, uswgi or SCGI protocols, and with distributed memory object caching systems like memcached. Other useful functionality like reverse proxy with load balancing and caching was added as well. These additional features have shaped nginx into an efficient combination of tools to build a scalable web infrastructure upon.
  • nginx의 첫번째 버전이 발표 되었을 때는 apache-based의 어플리케이션 서버 환경에서 동시처리량을 경감시키고, 백그라운드 처리를 위해 apache에 곁다리 형태로 HTML, CSS, JavaScript, 이미지 같은 것들을 서비스 하는데 사용되었다. 개발을 거듭하는 동안, nginx는 FastCGI, uswgi 또는 SCGI protocol을 사용하는 어플리케이션들과 memcached와 같은 분산 메모리 객체 캐시 시스템과의 연동이 추가되었다. 다른 유용한 기능으로 로드 밸런싱을 위한 reverse proxy와 캐싱 같은 것도 추가되었다. 이러한 부가 기능들이 nginx를 확장성이 좋은 웹 인프라스트럭쳐를 구축하는 효율적인 조합의 도구가 되도록 만들어갔다.
  • In February 2012, the Apache 2.4.x branch was released to the public. Although this latest release of Apache has added new multi-processing core modules and new proxy modules aimed at enhancing scalability and performance, it's too soon to tell if its performance, concurrency and resource utilization are now on par with, or better than, pure event-driven web servers. It would be very nice to see Apache application servers scale better with the new version, though, as it could potentially alleviate bottlenecks on the backend side which still often remain unsolved in typical nginx-plus-Apache web configurations.
  • 2012년 2월 apache 2.4.x가 발표되었다. apache의 최신버전이 새로운 multi-processing core module 및 확장성과 성능 향상을 위한 새로운 proxy module을 탑재 했음에도 불구하고, apache의 성능과 동시성, 자원 사용 측면에서 순수 event-driven 웹서버들 보다 좋다거나 혹은 비슷하다고 하기에는 아직도 성급한 면이 있다.
    여전히 종종 일반적인 nginx-apache 웹 구성에서 해결되지 않고 남아있는 back-end 측면의 병목현상을 잠재적으로 완화할 수 있기때문에 Apache 서버가 새로운 버전이 출시됨에 따라 향상되는 모습을 보는 것은 반가운 일이다.
  • Are There More Advantages to Using nginx?

  • nginx를 통해 얻게되는 또 다른 장점은?

  • Handling high concurrency with high performance and efficiency has always been the key benefit of deploying nginx. However, there are now even more interesting benefits.
  • 높은 성능과 효율로 동시성을 처리하는 것은 항상 nginx를 사용하는 주요 이점이다. 하지만 최근에는 더욱 흥미로운 장점이 생겼다.
  • In the last few years, web architects have embraced the idea of decoupling and separating their application infrastructure from the web server. However, what would previously exist in the form of a LAMP (Linux, Apache, MySQL, PHP, Python or Perl)-based website, might now become not merely a LEMP-based one (`E' standing for `Engine x'), but more and more often an exercise in pushing the web server to the edge of the infrastructure and integrating the same or a revamped set of applications and database tools around it in a different way.
  • 지난 몇 년 사이, 웹 아키텍트들은 그들의 어플리케이션 구조를 웹서버로부터 디커플링하고 분리하는 사상을 받아들이고 있다. 그러나 이것이 단순히 이전에 LAMP 기반의 웹 사이트였던 것이 LEMP 형태로 바뀌는 것이 아니라, 웹서버를 점점 더 인프라의 가장자리로 몰면서, 다른 한편으로는 nginx 주변의 응용 프로그램과 데이터베이스들을 동일하거나 향상된 세트로 통합하고 있다.
  • nginx is very well suited for this, as it provides the key features necessary to conveniently offload concurrency, latency processing, SSL (secure sockets layer), static content, compression and caching, connections and requests throttling, and even HTTP media streaming from the application layer to a much more efficient edge web server layer. It also allows integrating directly with memcached/Redis or other "NoSQL" solutions, to boost performance when serving a large number of concurrent users.
  • nginx는 효과적인 동시성 경감과 지연 처리, SSL, 정적 콘텐츠, 압축과 캐싱, connection과 요청 관리, 심지어 응용 layer 부터 훨씬 효율적인 엣지 웹서버 layer에 이르는 HTTP 미디어 스트리밍 서비스에 필요한 핵심 기능들을 제공한다. 또한 대량의 동시 사용자에게 서비스를 제공할 때 성능을 높이기 위한 memcached/Redis 또는 이 외에 "NoSQL"솔루션과 직접 통합 할 수 있다.
  • With recent flavors of development kits and programming languages gaining wide use, more and more companies are changing their application development and deployment habits. nginx has become one of the most important components of these changing paradigms, and it has already helped many companies start and develop their web services quickly and within their budgets.
  • 최근 폭 넓게 사용되고 있는 개발 kit 및 프로그래밍 언어의 추세로 볼 때, 점점 더 많은 기업들이 응용 프로그램 개발 및 배포 형태를 바꾸고 있다. nginx는 이러한 변화의 패러다임에서 가장 중요한 구성 요소 중 하나가 되어가고 있으며, 이미 많은 기업이 회사의 예산 범위 내에서 신속하게 Web 서비스를 개발할 수 있도록 지원하고 있다.
  • The first lines of nginx were written in 2002. In 2004 it was released to the public under the two-clause BSD license. The number of nginx users has been growing ever since, contributing ideas, and submitting bug reports, suggestions and observations that have been immensely helpful and beneficial for the entire community.
  • nginx의 첫 번째 라인은 2002년에 작성되었다. 2004년에 두 조항의 BSD 라이선스로 대중에게 공개되었다. 그 이후로 nginx의 사용자 수는 증가하고 있고, 커뮤니티 전체를 위하여 많은 도움이 되는 아이디어를 기여하고, 버그 리포트 제출하고, 제안과 관찰을 하고 있다.
  • The nginx codebase is original and was written entirely from scratch in the C programming language. nginx has been ported to many architectures and operating systems, including Linux, FreeBSD, Solaris, Mac OS X, AIX and Microsoft Windows. nginx has its own libraries and with its standard modules does not use much beyond the system's C library, except for zlib, PCRE and OpenSSL which can be optionally excluded from a build if not needed or because of potential license conflicts.
  • nginx의 코드 기반은 독창적이며, C 프로그래밍 언어로 완전히 새로 작성되었다. nginx는 많은 아키텍처와 Linux, FreeBSD의, 솔라리스, Mac OS X은 AIX 및 Microsoft Windows를 포함하여 운영 체제에 이식되어 있다. nginx는 자신의 라이브러리를 가지고 있으며, 자체의 표준모듈로 zlib, PCRE 및 OpenSSL을 제외하고는 필요 없거나 잠재적인 라이선스 문제가 있는 경우에는 선택적으로 빌드에서 제외할 수 있게 만들어 꼭 필요한 만큼의 C 라이브러리를 사용하게 만들었다.
  • A few words about the Windows version of nginx. While nginx works in a Windows environment, the Windows version of nginx is more like a proof-of-concept rather than a fully functional port. There are certain limitations of the nginx and Windows kernel architectures that do not interact well at this time. The known issues of the nginx version for Windows include a much lower number of concurrent connections, decreased performance, no caching and no bandwidth policing. Future versions of nginx for Windows will match the mainstream functionality more closely.
  • nginx의 Windows 버전에 대한 몇 마디. nginx가 Windows 환경에서 동작할 때, nginx의 Windows 버전은 완벽한 기능으로 동작한다기 보다는 개념을 증명하는 것에 가깝다. 현재 버전에는 nginx와 Windows 커널 아키텍처 간의 문제로 일부 기능 제한이 있다. Windows 용 nginx 버전의 알려진 버그는 매우 낮은 동시 연결성과 성능저하, 캐싱 기능과 대역폭 관리 기능이 없다. Windows 용 nginx의 향후 버전에서는 Linux 버전의 기능과 더욱 유사할 것이다.
  • 14.2. Overview of nginx Architecture

  • 14.2. nginx 아키텍처 개요

  • Traditional process- or thread-based models of handling concurrent connections involve handling each connection with a separate process or thread, and blocking on network or input/output operations. Depending on the application, it can be very inefficient in terms of memory and CPU consumption. Spawning a separate process or thread requires preparation of a new runtime environment, including allocation of heap and stack memory, and the creation of a new execution context. Additional CPU time is also spent creating these items, which can eventually lead to poor performance due to thread thrashing on excessive context switching. All of these complications manifest themselves in older web server architectures like Apache's. This is a tradeoff between offering a rich set of generally applicable features and optimized usage of server resources.
  • 기존의 동시 연결을 처리하는 프로세스 또는 스레드 기반 모델은 별도의 프로세스 또는 스레드와의 각 연결 처리와 네트워크 또는 입력 / 출력 작업에 대한 차단이 포함된다. 응용에 따라, 메모리 및 CPU 사용 측면에서 매우 비효율적 일 수있다. 별도의 프로세스 또는 스레드를 복제하는 작업은 힙 및 스택 메모리 할당을 포함한 새로운 런타임 환경의 준비와 새로운 실행 컨텍스트의 생성이 필요하다. 추가적인 CPU time 역시 과도한 컨텍스트 스위치에 의한 스레드 스래싱으로 성능 저하를 유발하는 일들에 소요된다. 이러한 복합현상들은 아파치와 같은 오래된 웹서버 아키텍처에서 실제로 나타난다. 이것은 일반적으로 적용할 수 있는 다양한 기능의 제공과 서버 자원 사용을 최적화 하는 것 사이에서 생기는 트레이드 오프이다.
  • From the very beginning, nginx was meant to be a specialized tool to achieve more performance, density and economical use of server resources while enabling dynamic growth of a website, so it has followed a different model. It was actually inspired by the ongoing development of advanced event-based mechanisms in a variety of operating systems. What resulted is a modular, event-driven, asynchronous, single-threaded, non-blocking architecture which became the foundation of nginx code.
  • 처음부터 nginx는 웹 사이트의 역동적인 성장을 가능하게 하면서 보다 좋은 성능, 밀도, 서버 자원의 경제적인 사용을 달성하기 위한 전용도구로 의도되어 다른 모델을 따랐다. 그것은 실제로 다양한 운영 체제에서 향상된 이벤트 기반 메커니즘의 지속적인 개발에 의해 영향을 받았다. 그 결과로 모듈식, 이벤트-드리븐, 비동기, 싱글-스레디드, 논-블러킹 아키텍처가 되었고, 이것은 nginx 코드의 기본이 되었다.
  • nginx uses multiplexing and event notifications heavily, and dedicates specific tasks to separate processes. Connections are processed in a highly efficient run-loop in a limited number of single-threaded processes called workers. Within each workernginx can handle many thousands of concurrent connections and requests per second.
  • nginx는 다중화 및 이벤트 알림을 중점적으로 사용하고, 별도의 프로세스를 분리하기 위하여 특별한 작업을 할당한다. 연결은 worker라 불리는 한정된 싱글-스레디드 프로세스의 매우 효율적인 실행 루프에서 처리된다. 각 workernginx는 초당 수천개의 동시 연결과 요청을 처리할 수 있다.
  • Code Structure

  • 코드 구조

  • The nginx worker code includes the core and the functional modules. The core of nginx is responsible for maintaining a tight run-loop and executing appropriate sections of modules' code on each stage of request processing. Modules constitute most of the presentation and application layer functionality. Modules read from and write to the network and storage, transform content, do outbound filtering, apply server-side include actions and pass the requests to the upstream servers when proxying is activated.
  • nginx worker 코드는 코어 및 기능 모듈을 포함한다. nginx의 핵심은 요청 처리의 각 단계에서 모듈의 코드의 해당 부분을 실행하고 타이트 한 실행-루프를 유지하도록 만들어졌다. 모듈들은 대부분 프리젠테이션과 응용 프로그램 레이어 기능으로 구성된다.
    모듈들은 프록싱이 활성화 될 때 요청을 업스트림 서버(back-end server)에 전달하고, 서버-사이드 작업을 적용하고, 아웃 바운드 필터링을 수행하고, 컨텐츠를 변환하고, 네트워크 및 스토리지에서 읽거나 저장한다.
  • nginx's modular architecture generally allows developers to extend the set of web server features without modifying the nginx core. nginx modules come in slightly different incarnations, namely core modules, event modules, phase handlers, protocols, variable handlers, filters, upstreams and load balancers. At this time, nginx doesn't support dynamically loaded modules; i.e., modules are compiled along with the core at build stage. However, support for loadable modules and ABI is planned for the future major releases. More detailed information about the roles of different modules can be found in Section 14.4.
  • nginx의 모듈형 아키텍처는 일반적으로 개발자가 nginx 코어를 수정하지 않고 웹 서버 기능들을 확장할 수 있게 한다. nginx 모듈은 핵심 모듈, 이벤트 모듈, phase 핸들러, 프로토콜, 변수 핸들러, 필터, 업스트림 및 로드 밸런서와 같이 조금씩 다른 기능을 가진다. 이 때, nginx를 동적으로 로드된 모듈을 지원하지 않는다. 즉, 모듈들은 빌드 단계에서 핵심모듈과 함께 컴파일된다. 그러나,로드 가능한 모듈 및 ABI에 대한 지원은 향후 주요 릴리스에서 지원될 예정이다. 다른 모듈들의 기능에 대한 상세정보는 14.4 절에서 찾을 수 있다.
  • While handling a variety of actions associated with accepting, processing and managing network connections and content retrieval, nginx uses event notification mechanisms and a number of disk I/O performance enhancements in Linux, Solaris and BSD-based operating systems, like kqueue, epoll, and event ports. The goal is to provide as many hints to the operating system as possible, in regards to obtaining timely asynchronous feedback for inbound and outbound traffic, disk operations, reading from or writing to sockets, timeouts and so on. The usage of different methods for multiplexing and advanced I/O operations is heavily optimized for every Unix-based operating system nginx runs on.
  • 네트웍 연결 및 컨텐츠 처리를 위한 접수, 처리 및 관리와 같은 다양한 작업을 처리하는 동안, nginx는 리눅스, Solaris 및 BSD 기반 운영 체제에서 이벤트 알림 메커니즘과 kqueue, epoll, 이벤트 포트들과 같은 약간의 디스크 I/O 성능 향상 기법을 사용한다. 목표는 OS에 가능한 많은 힌트를 제공하여 인바운드 및 아웃바운드, 디스크 처리, 소켓 read/write, 타임아웃 등에 대한 응답을 적시에 비동기식으로 받기 위한 것이다. 멀티플렉싱 및 향상된 I/O 처리를 위한 다른 방법은 최적화 된 유닉스 기반의 OS에서 nginx를 구동하는 것이다.
  • A high-level overview of nginx architecture is presented in Figure 14.1.
Image of 1640 article
  • Figure 14.1: Diagram of nginx's architecture
  • Workers Model

  • 워커 모델

  • As previously mentioned, nginx doesn't spawn a process or thread for every connection. Instead, worker processes accept new requests from a shared "listen" socket and execute a highly efficient run-loop inside each worker to process thousands of connections per worker. There's no specialized arbitration or distribution of connections to the workers in nginx; this work is done by the OS kernel mechanisms. Upon startup, an initial set of listening sockets is created. workers then continuously accept, read from and write to the sockets while processing HTTP requests and responses.
  • 이전에 언급했듯이, nginx는 모든 연결을 위하여 프로세스나 스레드를 복제하지 않는다. 대신, 워커 프로세스들은 listen 소켓으로부터 새로운 요청을 받고, 워커 당 수천 개의 연결을 처리하기 위해 각 워커 내부의 매우 효율적인 실행-루프를 수행한다. nginx에는 각 워커들에게 커넥션을 전달하거나 분배하는 기능은 없다. 이것은 OS 커널 기능으로 이루어진다. nginx가 기동될 때 listen 소켓의 초기 세트가 만들어지면, 워커는 HTTP 요청과 응답을 처리하는 동안 계속해서 소켓에서 접수하고, 읽고, 쓰기를 반복한다.
  • The run-loop is the most complicated part of the nginx worker code. It includes comprehensive inner calls and relies heavily on the idea of asynchronous task handling. Asynchronous operations are implemented through modularity, event notifications, extensive use of callback functions and fine-tuned timers. Overall, the key principle is to be as non-blocking as possible. The only situation where nginx can still block is when there's not enough disk storage performance for a worker process.
  • 실행-루프는 nginx 워커 코드의 가장 복잡한 부분이다. 종합적인 내부 호출을 포함하고 있으며 비동기 작업 처리의 아이디어에 크게 의존적이다. 비동기 작업은 모듈성, 이벤트 알림, 콜백 함수의 광범위한 사용과 잘 조정된 타이머를 통해 구현된다. 전반적으로, 핵심 원칙은 논-블로킹(non-blocking)이 될 것이다. nginx가 block 되는 유일한 상황은 워커 프로세스를 위한 디스크 스토리지 성능이 충분하지 않을 때일 것이다.
  • Because nginx does not fork a process or thread per connection, memory usage is very conservative and extremely efficient in the vast majority of cases. nginx conserves CPU cycles as well because there's no ongoing create-destroy pattern for processes or threads. What nginx does is check the state of the network and storage, initialize new connections, add them to the run-loop, and process asynchronously until completion, at which point the connection is deallocated and removed from the run-loop. Combined with the careful use of syscalls and an accurate implementation of supporting interfaces like pool and slab memory allocators, nginx typically achieves moderate-to-low CPU usage even under extreme workloads.
  • 왜냐하면, nginx는 각 커넥션마다 프로세스나 스레드를 fork 시키지 않으며, 메모리 사용은 대부분의 경우에 매우 적게 그리고 효율적이기 때문이다. nginx는 프로세스나 스레드에 대한 지속적인 생성-파괴 패턴이 없기 때문에 CPU 사이클을 절약한다. nginx가 하는 일은 네트워크와 스토리지의 상태를 확인하고, 새로운 연결을 초기화 하고, 실행 루프에 추가하고, 연결이 완료되어 실행-루프에서 할당해제 및 제거될 때까지 비동기식으로 처리를 한다. syscall의 조심스러운 사용 및 pool과 slab 메모리 할당과 같은 인터페이스를 지원하기 위한 정교한 구현과 결합할 때, nginx는 극한의 부하상황에서도 비교적 낮은 CPU 사용량을 유지할 수 있다.
  • Because nginx spawns several workers to handle connections, it scales well across multiple cores. Generally, a separateworker per core allows full utilization of multicore architectures, and prevents thread thrashing and lock-ups. There's no resource starvation and the resource controlling mechanisms are isolated within single-threaded worker processes. This model also allows more scalability across physical storage devices, facilitates more disk utilization and avoids blocking on disk I/O. As a result, server resources are utilized more efficiently with the workload shared across several workers.
  • 그 이유는 nginx가 커넥션들을 관리하기 위하여 몇 개의 worker들만 생성하기 때문에, multiple core에서 잘 조정된다. 일반적으로, 코어 당 한개의 separateworker는 멀티 코어 아키텍처의 전체 사용을 허용하고, 스레드 스레싱과 락을 방지한다. 자원 고갈은 없고, 자원 조절 메카니즘은 single-threaded worker process 내에서 격리된다. 또한이 모델은 물리적 저장 장치에 걸쳐 더 많은 확장성을 제공하고, 더 많은 디스크 활용을 용이하게 하고, 디스크 I/O 차단을 방지할 수 있다. 결과적으로, 서버 자원은 일부의 workers 간에 부하는 분산하게 되어 보다 효율적으로 이용된다.
  • With some disk use and CPU load patterns, the number of nginx workers should be adjusted. The rules are somewhat basic here, and system administrators should try a couple of configurations for their workloads. General recommendations might be the following: if the load pattern is CPU intensive—for instance, handling a lot of TCP/IP, doing SSL, or compression—the number of nginx workers should match the number of CPU cores; if the load is mostly disk I/O bound—for instance, serving different sets of content from storage, or heavy proxying—the number of workers might be one and a half to two times the number of cores. Some engineers choose the number of workers based on the number of individual storage units instead, though efficiency of this approach depends on the type and configuration of disk storage.
  • nginx의 workers 수는 디스크 사용 및 CPU 부하 패턴을 참고하여 조정해야 한다. 여기 몇몇의 기본적인 규칙들이 있는데, 시스템 관리자는 부하량에 따라 몇 가지의 구성을 시도해야 한다. 일반적인 권장사항은 다음과 같다. 부하패턴이 CPU 위주이면 - 예를 들면, 많은 양은 TCP/IP를 관리하거나, SSL 또는 압축작업 - nginx의 workers 수는 CPU 코어 수에 맞추어야 하고, 부하패턴이 디스크 I/O 위주이면 - 스토리지에서 여러 종류의 컨텐츠를 서비스 하거나, 프록시 기능 - workers 수는 CPU 코어 수의 1.5배 ~ 2배 정도로 맞추면 된다. 이 접근법의 효율은 디스크 스토리지의 종류 및 구성에 달려 있지만. 일부 엔지니어는 개별 스토리지 유닛의 수에 기반하여 workers 수를 결정한다.
  • One major problem that the developers of nginx will be solving in upcoming versions is how to avoid most of the blocking on disk I/O. At the moment, if there's not enough storage performance to serve disk operations generated by a particular worker, thatworker may still block on reading/writing from disk. A number of mechanisms and configuration file directives exist to mitigate such disk I/O blocking scenarios. Most notably, combinations of options like sendfile and AIO typically produce a lot of headroom for disk performance. An nginx installation should be planned based on the data set, the amount of memory available for nginx, and the underlying storage architecture.
  • nginx의 개발자가 차기 버전에서 해결하게 될 하나의 큰 문제는 디스크 I/O에서 발생하는 많은 blocking들을 방지하는 방법이다. 특정 worker에 의해 생성된 디스크 작업을 제공하기에 스토리지 성능이 충분하지 않다면, thatworker는 여전히 디스크에서 읽기/쓰기를 할 때 block 될 것이다. 일련의 메커니즘과 구성 파일은 이와 같은 디스크 I/O 병목 시나리오를 완화하기 위해 존재한다. 특히, sendfile 이나 AIO(AsyncI/O) 같은 옵션의 조합은 일반적으로 디스크 성능을 위하여 많은 도움이 된다. nginx 설치는 데이터 세트, nginx가 사용할 수 있는 메모리의 양 및 스토리지 아키텍처를 기반으로 계획되어야 한다.
  • Another problem with the existing worker model is related to limited support for embedded scripting. For one, with the standard nginx distribution, only embedding Perl scripts is supported. There is a simple explanation for that: the key problem is the possibility of an embedded script to block on any operation or exit unexpectedly. Both types of behavior would immediately lead to a situation where the worker is hung, affecting many thousands of connections at once. More work is planned to make embedded scripting with nginx simpler, more reliable and suitable for a broader range of applications.
  • 기존 worker 모델의 또 다른 문제는 임베디드 스크립트에 대한 제한적인 지원과 관련이 있다. 표준 nginx 배포판 자체는 내장 Perl 스크립트만 지원된다. 이에 대한 간단한 설명이 있다. 중요한 문제는 예상외로 어떤 조작이나 종료 시에 block 되는 임베디드 스크립트의 가능성이다. 이런 유형의 동작은 worker가 한번에 수천 개의 연결에 영향을 미치는 hang 상태에 빠질 수 있다. 다양한 영역의 응용을 위해서 더 쉽게​​, 보다 안정적으로 사용할 수 있도록 nginx에 내장된 스크립트를 만들기 위한 작업이 계획되어 있다.
  • nginx Process Roles

  • nginx 프로세스 역할

  • nginx runs several processes in memory; there is a single master process and several worker processes. There are also a couple of special purpose processes, specifically a cache loader and cache manager. All processes are single-threaded in version 1.x of nginx. All processes primarily use shared-memory mechanisms for inter-process communication. The master process is run as theroot user. The cache loader, cache manager and workers run as an unprivileged user.
  • nginx는 메모리에서 여러 개의 프로세스를 기동한다. 프로세스들은 하나의 마스터 프로세스와 여러 개의 worker 스레드로 구성된다. 여기에는 캐시 로더와 캐시 매니저 같은 특별한 목적의 프로세스들도 일부 있다. nginx 버전 1.x 에서는 모든 프로세스들이 single-threaded 이었다. 모든 프로세스들은 주로 프로세스 간 통신을 위해 공유 메모리 메커니즘을 사용한다. 마스터 프로세스는 root 사용자로 실행된다. 캐시 로더와 캐시 매니저, 그리고 worker들은 권한이 없은 사용자로 실행된다.
  • The master process is responsible for the following tasks:
  • 마스터 프로세스는 다음과 같은 작업을 담당한다.
  • - reading and validating configuration
  • - 구성 파일을 읽고, 유효성을 검사
  • - creating, binding and closing sockets
  • - 소켓의 생성과 할당 및 반납
  • - starting, terminating and maintaining the configured number of worker processes
  • - 설정된 수 만큼의 worker 프로세스들에 대한 기동, 종료, 관리
  • - reconfiguring without service interruption
  • - 서비스 중단 없이 설정 변경
  • - controlling non-stop binary upgrades (starting new binary and rolling back if necessary)
  • - 무중단 엔진 업그레이드 (새로운 버전의 엔진 기동 및 필요 시 롤백)
  • - re-opening log files
  • - 로그 파일의 재생성
  • - compiling embedded Perl scripts
  • - 내장 Perl 스크립드 컴파일
  • The worker processes accept, handle and process connections from clients, provide reverse proxying and filtering functionality and do almost everything else that nginx is capable of. In regards to monitoring the behavior of an nginx instance, a system administrator should keep an eye on workers as they are the processes reflecting the actual day-to-day operations of a web server.
  • worker 프로세스들은 클라이언트로부터의 커넥셕을 연결하고, 관리하고, 처리하며, 리버스 프록시와 필터링 기능을 제공하고, nginx가 할 수 있는 일의 대부분을 한다. 따라서 시스템 관리자는 worker 프로세스가 웹 서버의 실제 업무를 반영하는 프로세스이기 때문에 worker들을 잘 모니터링해야 한다.
  • The cache loader process is responsible for checking the on-disk cache items and populating nginx's in-memory database with cache metadata. Essentially, the cache loader prepares nginx instances to work with files already stored on disk in a specially allocated directory structure. It traverses the directories, checks cache content metadata, updates the relevant entries in shared memory and then exits when everything is clean and ready for use.
  • 캐시 로더 프로세스는 디스크 사의 캐시 아이템들을 체크하는 것과 nginx의 in-memory 데이터베이스에 캐시 메타데이터를 관리하는 부분을 담당한다. 기본적으로 캐시 로더는 nginx 인스턴스가 특별히 할당 된 디렉토리 구조의 디스크에 이미 저장된 파일을 사용하여 작업 할 수 있도록 준비한다. 이것은 디렉토리를 통과하고, 캐시 콘텐츠 메타 데이터를 확인하고, 공유 메모리에서 관련 항목을 업데이트 한 후 모든 것이 완벽하게 사용할 준비가 되면 종료된다.
  • The cache manager is mostly responsible for cache expiration and invalidation. It stays in memory during normal nginx operation and it is restarted by the master process in the case of failure.
  • 캐시 매니저는 캐시 만료 및 무효화를 관리한다. 그것은 정상적인 nginx 동작 중에는 메모리에 유지되고, 오류가 있는 경우에는 마스터 프로세스에 의해 재기동된다.
  • Brief Overview of nginx Caching

  • nginx 캐시 개요

  • Caching in nginx is implemented in the form of hierarchical data storage on a filesystem. Cache keys are configurable, and different request-specific parameters can be used to control what gets into the cache. Cache keys and cache metadata are stored in the shared memory segments, which the cache loader, cache manager and workers can access. Currently there is not any in-memory caching of files, other than optimizations implied by the operating system's virtual filesystem mechanisms. Each cached response is placed in a different file on the filesystem. The hierarchy (levels and naming details) are controlled through nginx configuration directives. When a response is written to the cache directory structure, the path and the name of the file are derived from an MD5 hash of the proxy URL.
  • nginx에서 캐싱은 파일 시스템의 계층적 데이터 스토리지의 형태로 구현된다. 캐시 키들은 설정 가능하며, 다른 요구-특정 매개 변수는 캐시된 것을 제어하기 위해 사용될 수 있다. 캐시 키와 캐시 메타 데이터는 캐시 로더, 캐시 매니저와 worker들이 액세스 할 수 있는 공유 메모리 세그먼트에 저장된다. 현재는 운영 체제의 가상 파일 시스템 메커니즘에 의한 최적화 이외의 in-memory 파일 캐싱은 없다. 각각의 캐시 된 응답은 파일 시스템에서 서로 다른 파일에 저장된다. 계층 구조(수준 및 명명 세부사항)는 nginx의 구성 지시어를 통해 제어된다. 응답이 캐시 디렉토리 구조에 쓰여질 때, 파일의 경로와 이름은 프록시 URL의 MD5 해시로부터 가져온다.
  • The process for placing content in the cache is as follows: When nginx reads the response from an upstream server, the content is first written to a temporary file outside of the cache directory structure. When nginx finishes processing the request it renames the temporary file and moves it to the cache directory. If the temporary files directory for proxying is on another file system, the file will be copied, thus it's recommended to keep both temporary and cache directories on the same file system. It is also quite safe to delete files from the cache directory structure when they need to be explicitly purged. There are third-party extensions for nginx which make it possible to control cached content remotely, and more work is planned to integrate this functionality in the main distribution.
  • 캐시에 컨텐츠를 배치하기 위한 프로세스는 다음과 같다. nginx가 업스트림 서버로부터 응답을 읽을 때, 콘텐츠는 먼저 캐시 디렉토리 구조의 외부의 임시 파일에 기록된다. nginx가 요청 처리를 마치면 임시 파일의 이름을 바꾸고 캐시 디렉토리로 이동시킨다. 프록시에 대한 임시 파일 디렉토리가 다른 파일 시스템에 있는 경우에는 파일이 복제되므로, 임시 디렉토리와 캐시 디렉토리 모두를 같은 파일 시스템에서 관리하기를 권장한다. 또한 명시적으로 제거해야 하는 경우에는 캐시 디렉토리 구조에서 파일을 삭제하는 것이 매우 안전하다. 캐시 컨텐츠를 원격 관리할 수 있게 해주는 nginx를 위한 third-party 제품들도 있으며, 이런 기능의 통합과 같은 더 많은 작업이 메인 배포에 계획되어 있다.
  • 14.3. nginx Configuration

  • 14.3. nginx 설정

  • nginx's configuration system was inspired by Igor Sysoev's experiences with Apache. His main insight was that a scalable configuration system is essential for a web server. The main scaling problem was encountered when maintaining large complicated configurations with lots of virtual servers, directories, locations and datasets. In a relatively big web setup it can be a nightmare if not done properly both at the application level and by the system engineer himself.
  • nginx의 설정 시스템은 이고르 시셰프(Igor Sysoev)의 아파치 경험에서 비롯되었다. 그의 주요 통찰력은 확장이 쉬운 설정 시스템이 웹서버에 필수적이라는 것이었다. 확장성에 있어 가장 큰 문제는 대규모로 복잡하게 설정되어 있는 수 많은 버추얼 서버와 디렉토리들, 위치 및 데이터셋을 관리할 때 직면하게 되었다. 상대적으로 큰 웹 설정의 경우, 응용 레벨이나 시스템 엔지니어 측면 모두에서 제대로 수행되지 않을 경우 그것은 악몽이 될 수 있다.
  • As a result, nginx configuration was designed to simplify day-to-day operations and to provide an easy means for further expansion of web server configuration.
  • 결과적으로, nginx 설정은 일상적인 작업을 단순화하고 향후 웹서버 설정의 확장을 위해 쉬운 방법을 제공하도록 설계되었다.
  • nginx configuration is kept in a number of plain text files which typically reside in /usr/local/etc/nginx or /etc/nginx. The main configuration file is usually called nginx.conf. To keep it uncluttered, parts of the configuration can be put in separate files which can be automatically included in the main one. However, it should be noted here that nginx does not currently support Apache-style distributed configurations (i.e., .htaccess files). All of the configuration relevant to nginx web server behavior should reside in a centralized set of configuration files.
  • nginx의 설정은 일반적으로 /usr/local/etc/nginx 또는 /etc/nginx 경로에 텍스트 파일로 보관된다. 주 설정 파일은 보통 nginx.conf 라고 불리운다. 정리를 유지하기 위해, 설정의 일부는 메인 설정 파일에 자동으로 포함되는 형태로 별도의 파일에 배치될 수 있다. 그러나, 여기서 주목해야 할 부분은 nginx는 현재 아파치 스타일의 분산 설정을 지원하지 않는다는 것이다(apache의 .htaccess 파일). nginx 웹서버 동작에 관련된 모든 설정은 중압 집중화된 설정 파일들에 있어야 한다.
  • The configuration files are initially read and verified by the master process. A compiled read-only form of the nginx configuration is available to the worker processes as they are forked from the master process. Configuration structures are automatically shared by the usual virtual memory management mechanisms.
  • 설정 파일은 처음에 마스터 프로세스에 의해 읽혀지고 검증된다. 컴파일된 read-only 형식의 nginx 설정은 마스터 프로세스로부터 fork 된 worker 프로세스에 사용된다. 설정 구조는 일반적인 가상 메모리 관리 메커니즘에 의해 공유된다.
  • nginx configuration has several different contexts for main, http, server, upstream, location (and also mail for mail proxy) blocks of directives. Contexts never overlap. For instance, there is no such thing as putting a location block in the mainblock of directives. Also, to avoid unnecessary ambiguity there isn't anything like a "global web server" configuration. nginx configuration is meant to be clean and logical, allowing users to maintain complicated configuration files that comprise thousands of directives. In a private conversation, Sysoev said, "Locations, directories, and other blocks in the global server configuration are the features I never liked in Apache, so this is the reason why they were never implemented in nginx."
  • nginx 설정에는 main, http, server, upstream, location (그리고 mail proxy를 위한 main) block의 지시자와 같은 여러 개의 서로 다른 context가 있다. context는 절대 중복되지 않는다. 예를 들면, main block에 location block을 넣는 것과 같은 일은 없다. 또한, 불필요한 모호성을 피하기 위해 "글로벌 웹 서버" 설정과 같은 것도 전혀 없다. nginx의 설정은 사용자가 수 천의 지침을 포함하는 복잡한 설정 파일들을 관리 할 수 있도록 명확하고, 논리적으로 의도되었다. 사적인 자리에서 이고르 시셰프는 이렇게 말했다. "글로벌 서버 설정에 있는 location, directories 그리고 나머지 block들은 내가 Apache에서 절대 좋아하지 않는 기능들이다. nginx에 그런 기능을 구현하지 않은 이유가 바로 이것이다."
  • Configuration syntax, formatting and definitions follow a so-called C-style convention. This particular approach to making configuration files is already being used by a variety of open source and commercial software applications. By design, C-style configuration is well-suited for nested descriptions, being logical and easy to create, read and maintain, and liked by many engineers. C-style configuration of nginx can also be easily automated.
  • 설정 구문, 형식 및 정의는 소위 C-스타일의 규칙이라고 불리우는 것을 따른다. 설정 파일들을 만들기 위한 이런 특별한 접근방식은 이미 다양한 오픈 소스와 상용 소프트웨어의 응용 프로그램에서 사용되고 있다. 디자인으로, C-스타일의 구성은 중첩된 설명에 적합하고, 논리적이며, 생성, 읽기 및 관리가 쉬울뿐 아니라, 많은 엔지니어들이 좋아했다. nginx의 C-스타일 설정은 또한 쉽게 자동화될 수 있다.
  • While some of the nginx directives resemble certain parts of Apache configuration, setting up an nginx instance is quite a different experience. For instance, rewrite rules are supported by nginx, though it would require an administrator to manually adapt a legacy Apache rewrite configuration to match nginx style. The implementation of the rewrite engine differs too.
  • nginx의 지침 중 일부는 Apache 설정의 어떤 부분과 비슷한 반면, nginx 인스턴스를 구성하는 것은 완전히 색다른 경험이다. 예를 들면, nginx 스타일에 맞게 Apache에서 rewrite 설정을 하기 위해서는 관리자가 수동으로 적용해야 하지만, nginx rule에서는 기본적으로 제공된다. rewrite 엔진의 구현은 정말 다르다.
  • In general, nginx settings also provide support for several original mechanisms that can be very useful as part of a lean web server configuration. It makes sense to briefly mention variables and the try_files directive, which are somewhat unique to nginx. Variables in nginx were developed to provide an additional even-more-powerful mechanism to control run-time configuration of a web server. Variables are optimized for quick evaluation and are internally pre-compiled to indices. Evaluation is done on demand; i.e., the value of a variable is typically calculated only once and cached for the lifetime of a particular request. Variables can be used with different configuration directives, providing additional flexibility for describing conditional request processing behavior.
  • 일반적으로, nginx 구성에서는 선형적인 웹서버 설정의 일부로서 매우 유용할 수 있는 몇 가지 원래의 메커니즘에 대한 지원을 제공한다. 단순히 변수와 try_files 지시어를 언급하면 되는데, 이것이 nginx를 다소 독특하게 만들어 준다. nginx에 있는 변수들은 웹 서버의 런타임 설정을 제어하기 위해 추가적으로 더 강력한 메커니즘을 제공하려고 개발되었다. 변수들은 빠른 평가에 최적화 되었고, 내부적으로 인덱스에 미리 컴파일된다. 평가는 요청 시 수행된다. 즉, 변수의 값은 통상적으로 한 번만 계산하고 특정한 요청의 수명기간 동안 캐시된다. 변수들은 서로 다른 설정 지시자들과 사용될 수 있으며, 조건부 요청 처리 동작을 설명하기 위한 추가적인 유연성을 제공한다.
  • The try_files directive was initially meant to gradually replace conditional if configuration statements in a more proper way, and it was designed to quickly and efficiently try/match against different URI-to-content mappings. Overall, the try_filesdirective works well and can be extremely efficient and useful. It is recommended that the reader thoroughly check the try_filesdirective and adopt its use whenever applicable.
  • try_files 지시어는 초기에는 점진적으로 보다 적절한 방식으로 if 설정문을 대체하기 위해서였으며, 신속하고 효율적으로 다른 URI-to-content 매핑에 대해 try/match 동작을 하도록 설계되었다. 전반적으로, try_files 지시어는 잘 작동하며 매우 효율적이고 유용 할 수 있다. 독자들은 try_files 지시어를 완벽하게 확인하여, 적용 가능할 때마다 사용할 것을 권장한다.
  • 14.4. nginx Internals

  • 14.4. nginx의 내부

  • As was mentioned before, the nginx codebase consists of a core and a number of modules. The core of nginx is responsible for providing the foundation of the web server, web and mail reverse proxy functionalities; it enables the use of underlying network protocols, builds the necessary run-time environment, and ensures seamless interaction between different modules. However, most of the protocol- and application-specific features are done by nginx modules, not the core.
  • 이전에 언급 한 것처럼, nginx의 코드베이스는 코어와 다수의 모듈로 구성되어 있다. nginx의 코어는 웹과 메일 리버스 프록시 기능과 같은 웹 서버의 기반을 제공하는 역할을 하는데, 그것은 내부 네트웍 프로토콜을 사용할 수 있게 하고, 필요한 런타임 환경을 구성하고, 다름 모듈간에 원활한 상호작용을 보장한다. 그러나, 프로토콜 및 응용 프로그램에 특정한 기능의 대부분은 코어가 아닌 nginx 모듈에 의해 수행된다.
  • Internally, nginx processes connections through a pipeline, or chain, of modules. In other words, for every operation there's a module which is doing the relevant work; e.g., compression, modifying content, executing server-side includes, communicating to the upstream application servers through FastCGI or uwsgi protocols, or talking to memcached.
  • 내부적으로, nginx 프로세스는 모듈의 파이프 라인, 또는 체인을 통해 연결한다. 다시 말하면, 모든 작업에 대하여 관련 작업을 수행하는 모듈이 있다. 예을 들면, 압축, 컨텐츠 수정, 서버-사이드 실챙을 포함하여, FastCGI 나 uwsgi 프로토콜, 또는 memcached와의 연계를 통한 업스트림 응용 서버와의 통신이 있다.
  • There are a couple of nginx modules that sit somewhere between the core and the real "functional" modules. These modules arehttp and mail. These two modules provide an additional level of abstraction between the core and lower-level components. In these modules, the handling of the sequence of events associated with a respective application layer protocol like HTTP, SMTP or IMAP is implemented. In combination with the nginx core, these upper-level modules are responsible for maintaining the right order of calls to the respective functional modules. While the HTTP protocol is currently implemented as part of the http module, there are plans to separate it into a functional module in the future, due to the need to support other protocols like SPDY (see "SPDY: An experimental protocol for a faster web").
  • 코어와 실제 "기능" 모듈 사이의 어딘가에 위치한 nginx 모듈 몇 가지가 있다. 이 모듈들은 http와 mail 이다. 이 두 모듈은 코어와 낮은 수준의 구성요소 사이의 추상화 수준을 추가로 제공한다. 이러한 모듈에서, HTTP, SMTP 또는 IMAP과 같은 각각의 애플리케이션 계층 프로토콜과 연관된 일련의 이벤트 처리가 구현된다. nginx 코어와의 조합에서는 이러한 상위 수준의 모듈은 각 기능 모듈 호출의 올바른 순서를 유지하기 위한 역할을 한다. HTTP 프로토콜은 현재 http 모듈의 일부로 구현되어 있으나, SPDY와 같은 다른 프로토콜을 지원해야 하는 필요성으로 인해, 향후에는 기능성 모듈로 분리하기 위한 계획이 있다. ("SPDY:빠른 웹에 대한 실험 프로토콜" 참조)
  • The functional modules can be divided into event modules, phase handlers, output filters, variable handlers, protocols, upstreams and load balancers. Most of these modules complement the HTTP functionality of nginx, though event modules and protocols are also used for mail. Event modules provide a particular OS-dependent event notification mechanism like kqueue or epoll. The event module that nginx uses depends on the operating system capabilities and build configuration. Protocol modules allow nginx to communicate through HTTPS, TLS/SSL, SMTP, POP3 and IMAP.
  • 기능성 모듈들은 이벤트 모듈, 위상 처리기, 출력 필터, 변수 처리기, 프로토콜, 업스트림 및 부하 분산 장치로 나눌 수 있다. 이벤트 모듈과 프로토콜은 메일에 사용 되기도 하지만, 이런 모듈들의 대부분은 nginx의 HTTP 기능을 보완하는 역할을 한다. 이벤트 모듈들은 kqueue 또는 epoll과 같은 특정 OS 의존적 이벤트 통지 메커니즘을 제공한다. nginx가 이용하는 이벤트 모듈은 운영 시스템의 기능과 설정 구성에 의존적이다. 프로토콜 모듈은 nginx에서 HTTPS, TLS/SSL, SMTP, POP3 및 IMAP 통신이 가능하도록 한다.
  • A typical HTTP request processing cycle looks like the following.
  • 전형적인 HTTP 요청 처리 주기는 다음과 같다.
  • - Client sends HTTP request.
  • 클라이언트가 HTTP request 를 보낸다.
  • - nginx core chooses the appropriate phase handler based on the configured location matching the request.
  • nginx 코어는 request 에 맞는 설정된 영역에 기반한 적절한 페이즈 핸들러를 선택한다.
  • - If configured to do so, a load balancer picks an upstream server for proxying.
  • 설정된 경우에는 로드밸런서가 프록시을 위한 업스트림 서버를 선택한다.
  • - Phase handler does its job and passes each output buffer to the first filter.
  • 페이즈 핸들러가 데이터 처리를 하고 첫번째 필터로 각각의 출력 버퍼를 보낸다.
  • - First filter passes the output to the second filter.
  • 첫번째 필터는 출력된 결과를 두번째 필터로 보낸다.
  • - Second filter passes the output to third (and so on).
  • 두번째 필터는 출력된 결과를 세번째 필터로 보낸다. (이하 필터로 반복된다.)
  • - Final response is sent to the client.
  • 최종 response 가 클라이언트로 전송된다.
  • nginx module invocation is extremely customizable. It is performed through a series of callbacks using pointers to the executable functions. However, the downside of this is that it may place a big burden on programmers who would like to write their own modules, because they must define exactly how and when the module should run. Both the nginx API and developers' documentation are being improved and made more available to alleviate this.
  • Nginx 모듈 호출은 매우 사용자 정의적이다. 이것은 실행 함수에 대한 포인터를 이용하는 일련의 콜백을 통해 수행된다. 그러나, 단점은 자신의 모듈을 작성하고 싶은 개발자에게 큰 부담이 될 수 있는데 왜냐하면, 개발자는 반드시 모듈이 어떻게 그리고 언제 실행되어야 하는지 정확하게 정의해야 하기 때문이다. nginx API와 개발자 문서는 이런 부담을 완화시키기 위해서 개선되고 더 사용하기 편하게 제공되고 있다.
  • Some examples of where a module can attach are:
  • 모듈을 장착 할 수 있는 위치의 몇 가지 예는 다음과 같다.
  • - Before the configuration file is read and processed
  • - 설정 파일을 읽고 처리되기 전
  • - For each configuration directive for the location and the server where it appears
  • - location과 server의 각 설정 지시어가 있는 곳
  • - When the main configuration is initialized
  • - 메인 설정이 초기화될 때
  • - When the server (i.e., host/port) is initialized
  • - host/port 등을 설정하는 server가 초기화될 때
  • - When the server configuration is merged with the main configuration
  • - server 설정이 메인 설정에 통합될 때
  • - When the location configuration is initialized or merged with its parent server configuration
  • - location 설정이 시작되거나 그것의 상위 server 설정과 통합될 때
  • - When the master process starts or exits
  • - 마스터 프로세스가 시작되거나 끝날 때
  • - When a new worker process starts or exits
  • - 새로운 worker 프로세스가 시작하거나 끝날 때
  • - When handling a request
  • - 요청을 처리할 때
  • - When filtering the response header and the body
  • - 응답 헤더와 바디를 필터링할 때
  • - When picking, initiating and re-initiating a request to an upstream server
  • - 업스트립 서버로의 요청을 선별하고 시작하고 재시작할 때
  • - When processing the response from an upstream server
  • - 업스트립 서버로부터의 응답을 처리할 때
  • - When finishing an interaction with an upstream server
  • - 업스트림 서버와의 연동을 종료할 때
  • Inside a worker, the sequence of actions leading to the run-loop where the response is generated looks like the following:
  • worker 내부에서, 응답이 생성될 때 실행-루프로 이어지는 동작의 순서는 다음과 같다.
  • - Begin ngx_worker_process_cycle().
  • - ngx_worker_process_cycle() 시작
  • - Process events with OS specific mechanisms (such as epoll or kqueue).
  • - OS 특정 메커니즘에 따른 이벤트 처리 (epoll 또는 kqueue와 같은)
  • - Accept events and dispatch the relevant actions.
  • - 이벤트 접수 및 관련 작업 디스패치
  • - Process/proxy request header and body.
  • - 요청 헤더와 바디에 대한 처리/프록시
  • - Generate response content (header, body) and stream it to the client.
  • - 응답 컨텐츠(헤더, 바디) 생성과 클라이언트로 전송
  • - Finalize request.
  • - 요청 마감
  • - Re-initialize timers and events.
  • - 타이머와 이벤트의 재 초기화
  • The run-loop itself (steps 5 and 6) ensures incremental generation of a response and streaming it to the client.
  • 런-루프 자체는 (5단계 ​​및 6단계) 응답의 증분 생성 및 클라이언트로 스트리밍을 보장
    * 5단계 : 응답 컨텐츠(헤더, 바디) 생성과 클라이언트로 전송
    * 6단계 : 요청 마감
  • A more detailed view of processing an HTTP request might look like this:
  • HTTP 요청 처리의 더욱 상세한 내용은 다음과 같다.
  • - Initialize request processing.
  • - 요청 처리 초기화
  • - Process header.
  • - 헤더 처리
  • - Process body.
  • - 바디 처리
  • - Call the associated handler.
  • - 관련 핸들러 호출
  • - Run through the processing phases.
  • - 처리 단계를 거쳐 실행
  • Which brings us to the phases. When nginx handles an HTTP request, it passes it through a number of processing phases. At each phase there are handlers to call. In general, phase handlers process a request and produce the relevant output. Phase handlers are attached to the locations defined in the configuration file.
  • 이런 것들은 우리에게 단계를 제공한다. nginx는 HTTP 요청을 처리 할 때, 다수의 처리 단계의 통해 수행된다. 각 단계에는 호출하는 핸들러가 있다. 일반적으로, 위상 처리기는 요청을 처리하고 해당 출력을 생성한다. 위상 처리기는 설정 파일에 정의된 위치에서 사용된다.
  • Phase handlers typically do four things: get the location configuration, generate an appropriate response, send the header, and send the body. A handler has one argument: a specific structure describing the request. A request structure has a lot of useful information about the client request, such as the request method, URI, and header.
  • 위상 처리기는 일반적으로 4가지 일을 한다. 위치 설정을 가져오고, 적정한 응답을 생성하고, 헤더를 전송하고, 바디를 전송한다. 처리기는 요청을 설명하는 구체적인 구조를 하나의 아규먼트로 갖는다. 요청 구조는 요청 방법, URI, 헤더와 같이 클라이언트의 요청에 대한 많은 유용한 정보를 제공한다.
  • When the HTTP request header is read, nginx does a lookup of the associated virtual server configuration. If the virtual server is found, the request goes through six phases:
  • HTTP 요청 헤더를 읽을 때, nginx는 관련된 가상 서버 설정을 조회하고, 가상 서버가 발견되면, 요청은 6 단계를 통해 수행된다.
  • - server rewrite phase
  • - 서버 rewrite 단계
  • - location phase
  • - 위치 단계
  • - location rewrite phase (which can bring the request back to the previous phase)
  • - 위치 rewrite 단계 (이 단계에서 요청은 이전 단계로 갈 수도 있다.)
  • - access control phase
  • - 접근 제어 단계
  • - try_files phase
  • - try_files 단계
  • - log phase
  • - 로깅 단계
  • In an attempt to generate the necessary content in response to the request, nginx passes the request to a suitable content handler. Depending on the exact location configuration, nginx may try so-called unconditional handlers first, like perl, proxy_pass,flv, mp4, etc. If the request does not match any of the above content handlers, it is picked by one of the following handlers, in this exact order: random index, index, autoindex, gzip_static, static.
  • 요청에 대한 응답에 필요한 컨텐츠를 생성하는 시도에서, nginx는 요청을 적당한 컨텐츠 핸들러에게 전달한다. 정확한 위치 설정에 따라, nginx는 perl, proxy_pass, flv, mp4 등과 같이 소위 말하는 무조건 핸들러에게 가장 먼저 시도할 수도 있다. 만약 요청이 이전의 컨텐츠 핸들러와 맞는게 없으면, 정확한 순서에 따라 랜덤 인덱스, 인덱스, 오토인덱스, gzip_static, static 중 하나의 핸들러로 선별된다.
  • Indexing module details can be found in the nginx documentation, but these are the modules which handle requests with a trailing slash. If a specialized module like mp4 or autoindex isn't appropriate, the content is considered to be just a file or directory on disk (that is, static) and is served by the static content handler. For a directory it would automatically rewrite the URI so that the trailing slash is always there (and then issue an HTTP redirect).
  • 인덱싱 모듈의 상세 내용은 nginx 문서에서 찾을 수 있으나, 이들은 슬래시와 함께 요청을 처리하는 모듈이다. mp4 또는 autoindex와 같이 특정 모듈이 적절하지 않은 경우, content는 단지 디스크 상의 파일이나 디렉토리로 간주되고 (즉, 정적) 정적 컨텐츠 핸들러에 의해 처리된다. 디렉토리에 대해서는 자동으로 URI가 rewrite 되어, 항상 슬래시가 붙도록 할 것이다. (다음 HTTP redirection 수행)
  • The content handlers' content is then passed to the filters. Filters are also attached to locations, and there can be several filters configured for a location. Filters do the task of manipulating the output produced by a handler. The order of filter execution is determined at compile time. For the out-of-the-box filters it's predefined, and for a third-party filter it can be configured at the build stage. In the existing nginx implementation, filters can only do outbound changes and there is currently no mechanism to write and attach filters to do input content transformation. Input filtering will appear in future versions of nginx.
  • 컨텐트 핸들러의 컨텐츠는 다음 필터에 전달된다. 필터들은 또한 locations에 부착되며, 그 곳에는 location을 위해 설정된 여러 필터가 있을 수있다. 필터는 처리기에 의해 생성되는 출력을 조작하는 작업을 한다. 필터의 실행 순서는 컴파일 시점에 결정된다. 미리 정의된 out-of-the-box 필터와 3rd-party 필터는 빌드 단계에서 설정할 수 있다. 기존의 nginx 구현에서, 필터는 단지 아웃 바운드 변경만 시킬 수 있고, 입력 내용의 변환을 수행하는 필터를 작성하고 첨부하는 메커니즘은 없다. Input 필터 기능은 nginx의 향후 버전에서나 선보일 것이다.
  • Filters follow a particular design pattern. A filter gets called, starts working, and calls the next filter until the final filter in the chain is called. After that, nginx finalizes the response. Filters don't have to wait for the previous filter to finish. The next filter in a chain can start its own work as soon as the input from the previous one is available (functionally much like the Unix pipeline). In turn, the output response being generated can be passed to the client before the entire response from the upstream server is received.
  • 필터들은 특별한 디자인 패턴을 따른다. 필터는 호출되고, 작업을 시작하고, 체인의 마지막 필터가 호출될 때까지 다음 필터를 호출한다. 그런 다음 nginx는 응답을 종료한다. 필터들은 이전 필터가 끝날때까지 기다리지 않아도 된다. 체인에있는 다음 필터는 바로 이전의 입력이 가능한 상태로 자신의 작업을 시작할 수 있다 (기능적으로 유닉스의 파이프라인과 아주 유사함). 그 다음, 생성된 출력 응답은 업스트림 서버로부터 전체 응답을 수신하기 전에 클라이언트로 전달될 수 있다.
  • There are header filters and body filters; nginx feeds the header and the body of the response to the associated filters separately.
  • 헤더 필터와 바디 필터가 있다. nginx는 연결된 필터에 대한 응답의 헤더와 바디를 별도로 공급한다.
  • A header filter consists of three basic steps:
  • 헤더 필터는 세 가지 기본 단계로 구성된다.
  • - Decide whether to operate on this response.
  • - 이 응답에 대한 작동 여부를 결정
  • - Operate on the response.
  • - 응답에 대한 작동
  • - Call the next filter.
  • - 다음 필터 호출
  • Body filters transform the generated content. Examples of body filters include:
  • 바디 필터는 생성된 컨텐츠를 변환. 바디 필터의 예.
  • - server-side includes
  • - 서버 측 포함
  • - XSLT filtering
  • - XSLT(Extensible Stylesheet Language Transformations) 필터링
  • - image filtering (for instance, resizing images on the fly)
  • - 이미지 필터링 (예, 이미지 즉석 크기 조정)
  • - charset modification
  • - 캐릭터셋 변경
  • - gzip compression
  • - gzip 압축
  • - chunked encoding
  • - chunked 인코딩
  • After the filter chain, the response is passed to the writer. Along with the writer there are a couple of additional special purpose filters, namely the copy filter, and the postpone filter. The copy filter is responsible for filling memory buffers with the relevant response content which might be stored in a proxy temporary directory. The postpone filter is used for subrequests.
  • 필터 체인 후, 응답은 writer로 전달된다. writer와 함께 복사필터라고 하는 추가적인 특수 목적의 필터 몇 가지와 연기필터가 있다. 복사 필터는 프록시 임시 디렉토리에 저장되어 있는 관련된 응답 컨텐츠들을 메모리 버퍼에 담는 역할을 한다. 연기필터는 하위 요청에 사용된다.
  • Subrequests are a very important mechanism for request/response processing. Subrequests are also one of the most powerful aspects of nginx. With subrequests nginx can return the results from a different URL than the one the client originally requested. Some web frameworks call this an internal redirect. However, nginx goes further—not only can filters perform multiple subrequests and combine the outputs into a single response, but subrequests can also be nested and hierarchical. A subrequest can perform its own sub-subrequest, and a sub-subrequest can initiate sub-sub-subrequests. Subrequests can map to files on the hard disk, other handlers, or upstream servers. Subrequests are most useful for inserting additional content based on data from the original response. For example, the SSI (server-side include) module uses a filter to parse the contents of the returned document, and then replaces include directives with the contents of specified URLs. Or, it can be an example of making a filter that treats the entire contents of a document as a URL to be retrieved, and then appends the new document to the URL itself.
  • 하위 요청은 요청/응답 처리를 위한 매우 중요한 메커니즘이다. 하위 요청도의 nginx의 가장 강력한 측면 중 하나이다. 하위 요청으로 nginx는 클라이언트의 원래 요청이 아닌 다른 URL로부터의 결과를 반환할 수 있다. 어떤 웹 프레임웍에서는 이것을 내부 redirect라고 부른다. 하지만, nginx는 필터가 여러 개의 하위 요청을 수행하고 하나의 응답으로 출력을 결합할 수 있을 뿐 아니라, 하위 요청이 중첩되고 계층적이게도 할 수 있다. 하위 요청은 자신의 하위-하위 요청을 수행 할 수 있으며, 하위-하위 요청은 하위-하위-하위 요청을 시작할 수 있다. 하위 요청은 하드 디스크의 파일, 다른 처리기 또는 업스트림 서버에 매핑 할 수 있다. 하위 요청은 원래의 응답 데이터를 기반으로 추가 콘텐츠를 삽입하기에 가장 유용하다. 예를 들면, SSI(server-side include) 모듈은 반환된 문서의 내용을 파싱하는데 필터를 사용하고, include 지시어를 지정된 URL의 내용으로 대체한다. 또는 검색할 URL로 문서의 전체 내용을 취급하고, URL 자체에 새 문서를 추가하는 것이 필터를 만드는 예제가 될 수 있다.
  • Upstream and load balancers are also worth describing briefly. Upstreams are used to implement what can be identified as a content handler which is a reverse proxy (proxy_pass handler). Upstream modules mostly prepare the request to be sent to an upstream server (or "backend") and receive the response from the upstream server. There are no calls to output filters here. What an upstream module does exactly is set callbacks to be invoked when the upstream server is ready to be written to and read from. Callbacks implementing the following functionality exist:
  • upstream 및 부하 분산 장치도 간단하게 설명하는 가치가 있다. upstream은 리버스 프록시(proxy_pass 핸들러)의 컨텐츠 핸들러로 식별 할 수 있는 것을 구현하는 데 사용된다. upstream 모듈은 대부분 upstream 서버 (또는 "backend")로 보내어지는 요청을 준비하고, upstream 서버로 부터 응답을 받는다. 여기에는 output 필터 호출이 없다. upstream 모듈이 정확하게 하는 것은 upstream 서버가 읽거나 쓸 준비가 되었을 때 호출되게 하는 일련의 callback 이다. Callback은 다음과 같은 기능을 구현한다.
  • - Crafting a request buffer (or a chain of them) to be sent to the upstream server
  • - upstream 서버로 전송되는 요청 버퍼(또는 버퍼 체인) 기술
  • - Re-initializing/resetting the connection to the upstream server (which happens right before creating the request again)
  • - upstream 서버에 대한 연결의 재초기화/재설정 (요청을 다시 작성하기 직전에 발생하는)
  • - Processing the first bits of an upstream response and saving pointers to the payload received from the upstream server
  • - upstream 응답의 첫번째 비트 처리 및 upstream 서버로부터 수신된 내용에 대한 포인터 저장
  • - Aborting requests (which happens when the client terminates prematurely)
  • - 요청 취소 (클라이언트의 종료로 발생하는)
  • - Finalizing the request when nginx finishes reading from the upstream server
  • - nginx가 upstream 서버로부터 읽기가 끝나면 요청을 마무리
  • - Trimming the response body (e.g. removing a trailer)
  • - 응답 바디 정리 (예, 트레일러 제거)
  • Load balancer modules attach to the proxy_pass handler to provide the ability to choose an upstream server when more than one upstream server is eligible. A load balancer registers an enabling configuration file directive, provides additional upstream initialization functions (to resolve upstream names in DNS, etc.), initializes the connection structures, decides where to route the requests, and updates stats information. Currently nginx supports two standard disciplines for load balancing to upstream servers: round-robin and ip-hash.
  • 로드 밸런서 모듈은 한 개 이상의 upstream 서버를 사용할 수 있을 때 upstream 서버를 선택할 수 있게 하는 가용성을 제공하는 proxy_pass 처리기에 붙일 수 있다. 로드 밸런서는 구성 파일 지시어 활성화를 등록하고, 추가적인 upstream 초기화 기능을 제공하고 (DNS 등에 등록되어 있는 upstream 이름을 해석하기 위한), 연결 구조를 초기화하고, 요청을 분기시킬 위치를 결정하고, 통계정보를 업데이트 한다. 현재 nginx에서는 upstream 서버에 대한 로드 밸런싱에 round-robin과 ip-hash 2가지 표준 규칙을 제공한다.
  • Upstream and load balancing handling mechanisms include algorithms to detect failed upstream servers and to re-route new requests to the remaining ones—though a lot of additional work is planned to enhance this functionality. In general, more work on load balancers is planned, and in the next versions of nginx the mechanisms for distributing the load across different upstream servers as well as health checks will be greatly improved.
  • upstream과 로드 밸런싱 처리 매커니즘은 upstream 서버 실패 감지와 살아 있는 서버에 대한 새로운 요청의 재전달 알고리즘이 포함되어 있고, 이러한 기능의 고도화에 대하여 많은 추가적인 작업이 계획되어 있다. 일반적으로, 부하 분산에 더 많은 작업이 계획되어 있고, 다음 버전에서는 health-check 뿐만 아니라, 서로 다른 upstream 서버 간의 부하에 대한 분산을 위한 매커니즘이 크게 향상될 것이다.
  • There are also a couple of other interesting modules which provide an additional set of variables for use in the configuration file. While the variables in nginx are created and updated across different modules, there are two modules that are entirely dedicated to variables: geo and map. The geo module is used to facilitate tracking of clients based on their IP addresses. This module can create arbitrary variables that depend on the client's IP address. The other module, map, allows for the creation of variables from other variables, essentially providing the ability to do flexible mappings of hostnames and other run-time variables. This kind of module may be called the variable handler.
  • 구성 파일에 사용하기 위한 변수의 추가 세트를 제공하는 다른 흥미로운 모듈의 몇 가지가 있다. nginx의 변수가 다른 모듈 간의 생성 및 업데이트를 하는 동안, 두 개의 모듈은 완전히 변수에 할당된다. geo와 map. geo 모듈은 클라이언트의 IP 주소에 기초하여 클라이언트의 추적을 용이하게 하기 위해 사용된다. 이 모듈은 클라이언트의 IP 주소에 따라 임의의 변수를 만들 수 있다. 다른 모듈인 map은 호스트 및 다른 런타임 변수의 유연한 매핑을 수행하는 가용성을 필수적으로 제공하는 다른 변수로부터 변수들의 생성을 허용한다. 이런 종류의 모듈은 변수 처리기라고 불리운다.
  • Memory allocation mechanisms implemented inside a single nginx worker were, to some extent, inspired by Apache. A high-level description of nginx memory management would be the following: For each connection, the necessary memory buffers are dynamically allocated, linked, used for storing and manipulating the header and body of the request and the response, and then freed upon connection release. It is very important to note that nginx tries to avoid copying data in memory as much as possible and most of the data is passed along by pointer values, not by calling memcpy.
  • Going a bit deeper, when the response is generated by a module, the retrieved content is put in a memory buffer which is then added to a buffer chain link. Subsequent processing works with this buffer chain link as well. Buffer chains are quite complicated in nginx because there are several processing scenarios which differ depending on the module type. For instance, it can be quite tricky to manage the buffers precisely while implementing a body filter module. Such a module can only operate on one buffer (chain link) at a time and it must decide whether to overwrite the input buffer, replace the buffer with a newly allocated buffer, or insert a new buffer before or after the buffer in question. To complicate things, sometimes a module will receive several buffers so that it has an incomplete buffer chain that it must operate on. However, at this time nginx provides only a low-level API for manipulating buffer chains, so before doing any actual implementation a third-party module developer should become really fluent with this arcane part of nginx.
  • A note on the above approach is that there are memory buffers allocated for the entire life of a connection, thus for long-lived connections some extra memory is kept. At the same time, on an idle keepalive connection, nginx spends just 550 bytes of memory. A possible optimization for future releases of nginx would be to reuse and share memory buffers for long-lived connections.
  • The task of managing memory allocation is done by the nginx pool allocator. Shared memory areas are used to accept mutex, cache metadata, the SSL session cache and the information associated with bandwidth policing and management (limits). There is a slab allocator implemented in nginx to manage shared memory allocation. To allow simultaneous safe use of shared memory, a number of locking mechanisms are available (mutexes and semaphores). In order to organize complex data structures, nginx also provides a red-black tree implementation. Red-black trees are used to keep cache metadata in shared memory, track non-regex location definitions and for a couple of other tasks.
  • Unfortunately, all of the above was never described in a consistent and simple manner, making the job of developing third-party extensions for nginx quite complicated. Although some good documents on nginx internals exist—for instance, those produced by Evan Miller—such documents required a huge reverse engineering effort, and the implementation of nginx modules is still a black art for many.
  • Despite certain difficulties associated with third-party module development, the nginx user community recently saw a lot of useful third-party modules. There is, for instance, an embedded Lua interpreter module for nginx, additional modules for load balancing, full WebDAV support, advanced cache control and other interesting third-party work that the authors of this chapter encourage and will support in the future.
  • 14.5. Lessons Learned

  • 14.5. 배운점

  • When Igor Sysoev started to write nginx, most of the software enabling the Internet already existed, and the architecture of such software typically followed definitions of legacy server and network hardware, operating systems, and old Internet architecture in general. However, this didn't prevent Igor from thinking he might be able to improve things in the web servers area. So, while the first lesson might seem obvious, it is this: there is always room for improvement.
  • With the idea of better web software in mind, Igor spent a lot of time developing the initial code structure and studying different ways of optimizing the code for a variety of operating systems. Ten years later he is developing a prototype of nginx version 2.0, taking into account the years of active development on version 1. It is clear that the initial prototype of a new architecture, and the initial code structure, are vitally important for the future of a software product.
  • Another point worth mentioning is that development should be focused. The Windows version of nginx is probably a good example of how it is worth avoiding the dilution of development efforts on something that is neither the developer's core competence or the target application. It is equally applicable to the rewrite engine that appeared during several attempts to enhance nginx with more features for backward compatibility with the existing legacy setups.
  • Last but not least, it is worth mentioning that despite the fact that the nginx developer community is not very large, third-party modules and extensions for nginx have always been a very important part of its popularity. The work done by Evan Miller, Piotr Sikora, Valery Kholodkov, Zhang Yichun (agentzh) and other talented software engineers has been much appreciated by the nginx user community and its original developers.
0 Comments