I will briefly explain the features of NGINX.
--Event-driven web server --Good at delivering static content --Often used as a reverse proxy --Second most used of all active sites (19.60%)
Reference: wikipedia nginx
In the past (although long ago) Apache was the strongest server industry. I'm not very familiar with it, but as the server became cheaper, the C10K problem became a hot topic in the industry and was adopted by Apache. The server with the pre-Fork architecture that used to be used can no longer handle a large number of requests. Among them, NGINX, which is an event-driven architecture, can handle a large number of requests and seems to have attracted attention. Therefore, NGINX receives the very beginning of the Web service request and reverse proxies it. It seems that the configuration is often taken. In addition, websites such as media need to respond at high speed, and there are many characteristics that are static as content, so it seems that NGINX may be adopted.
NGINX-Unit is a product newly announced on September 8, 2017. As its feature,
--NGINX Unit is an application server --Supports PHP, Python, Go --Server settings can be dynamically changed in real time using RESTful API and JSON
It seems that there is a feature. In general, Web services often have a three-layer architecture.
A server that only returns simple static HTML is called a Web server in a narrow sense, and a server that runs a program written in PHP or Python and can bind it to HTTP is called an application server. Until now, I was able to do something like "Run NGINX + gunicorn + Python." However, strictly speaking, WSGI server (application server) such as gunicorn and NGINX are only linked. In this example, it is an image that NGINX Unit replaces the gunicorn part. I have never heard of the feature of server setting by RESTful API on other servers. Generally, it is an image of putting a configuration file in / etc / conf and restarting.
We proceeded with the development environment while borrowing the wisdom of our predecessors.
I tried running PHP, Python, Golang with NGINX Unit
Mostly as per the official documentation. This time too, the environment will use pre-compiled binaries on Ubuntu.
$ wget http://nginx.org/keys/nginx_signing.key
$ sudo apt-key add nginx_signing.key
Add the following text to /etc/apt/sources.list
deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx
And install
$ sudo apt-get update
$ sudo apt-get install unit unit-dev
Start the server
$ sudo service unitd start
The survey took some time, but I think it's relatively easy to get into.
By the way, I also looked at the php and python versions of the NGINX Unit included above.
$ pwd
/usr/lib/unit/modules
$ ls
php.unit.so python.unit.so
It seems that php and python so are included in / usr / lib / unit / modules. this
$ objdump -s php.unit.so | less
$ objdump -s python.unit.so | less
I read the binary dump visually. as a result,
It was a version like this. Probably because the official python of Ubuntu 16.04 is still 2.7 series. If you want to write a program in python3 series, is there no choice but to build from the source code?
This time, the code and configuration file used in the benchmark are prepared in the repository.
https://github.com/kotauchisunsun/nginx_unit_bench
Setting up the server is very easy,
$ sudo curl -X PUT -d @php_config.json \
--unix-socket /run/control.unit.sock http://localhost/
Just throw json like this and you can set it without restarting the server. The points to note on Ubuntu are throwing with sudo and the socket working with /run/control.unit.sock. Also, json in the repository does not work as it is. The path of the source code to be moved and the path of the executable file are written as absolute paths, so please rewrite as appropriate.
Benchmark languages are PHP, Python, Go. The application itself is very simple,
--PHP is "Hello PHP World !!" --Python is "Hello Python World !!" --Go is "Hello Go World !!"
It is an application that just outputs. ** What is the fastest bridge between the NGINX Unit and the programming language, making it as simple as possible? Check **.
The software used for benchmarking is Apache Bench
-Is the Serverless environment more than 600 times slower? ~ I tried benchmarking with Go, Node.js and Python! ~ -Introduction to serverless! Home serverless + serverless thumbnail server created in home S3 environment!
However, it is an easy-to-use load test tool that I used. The command looks like this
$ ab -n 100000 -c 100 http://localhost:8100/
Send 100,000 requests in 100 parallels. (Bench.sh in the repository is the execution script for benchmarking.)
Language | min Response Time[ms] | mean Respones Time[ms] | max Response Time[ms] | Request Per Second |
---|---|---|---|---|
PHP | 6 | 99 | 1,414 | 1005.30 |
Python | 65 | 141 | 1,916 | 708.99 |
Go | 48 | 106 | 2,567 | 946.90 |
Detailed data is placed in Repository as php.result, python.result, go.result.
This may be a disappointing result, but ** the fastest language running on the NGINX Unit was PHP. ** For some reason, I understand. It looks at the code,
index.php
<?php
echo "Hello PHP World!!";
wsgi.py
from flask import Flask
application = Flask(__name__)
@application.route("/")
def index():
return "Hello Python World!!"
hello.go
package main
import (
"fmt"
"net/http"
"unit"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello Go World!!")
})
unit.ListenAndServe(":8300", nil)
}
It is. In the case of python, you need to create an application in the wsgi format. Therefore, it is essential to load Flask and wsgi modules. Also, Go is the same, and it is essential to bind with a module called "unit" for NGINX Unit. On the other hand, PHP does not load any libraries. Personally, I thought "Go running in binary would be the fastest". However, the Go is slow. And, considering that the min response time of PHP is unusually fast of 6 [ms], in summary, Python and Go were slow and PHP was the fastest because the ** module was used. You can see that **.
--I installed NGINX Unit on Ubuntu. --As a result of benchmarking by language, PHP> Go> Python. --It seems that PHP is the fastest because it loads less modules
The result was. After all, what was shocking was that "PHP was the fastest", but honestly PHP and Go are not so different in performance? I think. Ultimately, Go will be faster as you build the logic. I think. On the other hand, is Python a little slow? I have to feel that. Although not mentioned in the benchmark above, ** Go modules may fail to respond. ** I haven't tracked the cause so much, but during the load test
apr_socket_recv: Connection reset by peer (104)
Was output, and it failed with an error. Therefore, I re-benchmarked about 3 times in total. The NGINX Unit is still like the beta version, so I think this may happen. On the other hand, what I think is excellent is that you can set the server with REST Full API. This is fantastic. The bench was also easy to do. However, I wanted you to stick to the making of json a little more. As you can see by looking at the json for config in the repository, the notation of path is slightly different depending on the language. I'm addicted to it, but I hit the API with curl without noticing it, but the error message is unfriendly. The error message didn't tell me what part of json was wrong, so I had to stare at the official docs while looking like a plate myself, which was a pain. Anyway, once you get used to it, NGINX Unit may be easier. I don't like PHP. The reason is that you have to set open_base_dir etc. in php.ini (and you are often addicted to it), but that side can be completely ignored and you can run the source code of any path. The setting can also be specified in one shot with json, so it is very easy. This is also the case with Python, and it's a lot easier to set while holding the unfamiliar settings such as gunicorn and nginx. Moreover, since there is no need to restart the server, development is very easy and Try & Error can be done at high speed. It may be difficult to put it into production, but if it is a light product like a hackathon, it is easier to handle routing and settings than using a language built-in server, so I felt that it might be possible. Please feel it.
Recommended Posts