nginx
nginx是俄罗斯人写的轻量级http服务器,Nginx 以事件驱动的方式编写,有非常好的性能,同时也是一个非常高效的反向代理、负载均衡。
Nginx 稳定性高,模块库丰富,配置灵活,系统资源的消耗低。响应静态页面的速度非常快
what nginx does
- Handling static files
- Reverse proxy, load balancing and fault tolerance
- large concurrency
- Easy to configure and expand
nginx processing
nginx handles requests in an asynchronous, non-blocking way. Using the epoll event loop, multiple independent workers process requests, not concurrently, avoiding performance problems caused by locking and context switching.
Handling of specific requests
- Parse the configuration file, get the port and ip address to be monitored, and then initialize the monitoring socket in the master process of Nginx
- Then fork out multiple child processes, and then the child processes will compete to accept new connections
- Three-way handshake with the client to get the socket of the established connection, and then create the Nginx encapsulation of the connection
- Nginx or client to actively close the connection
nginx configuration
Divided into several modules:
- main: Some parameters that have nothing to do with specific business functions (such as http service or email service proxy) when Nginx is running, such as the number of worker processes, running identity, etc.
- http: Some configuration parameters related to providing http services. For example: whether to use keepalive, whether to use gzip for compression, etc.
- server: Several virtual hosts are supported on the http service. Each virtual host has a corresponding server configuration item, which contains the configuration related to the virtual host.
- location: In the http service, a series of configuration items corresponding to some specific URLs.
By default, this configuration file is usually named nginx.conf and will be placed in /usr/local/nginx/conf, /etc/nginx, or /usr/local/etc/nginx
example configuration
user nobody;
worker_processes 1;
error_log logs/error.log info;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/host.access.log main;
location / {
index index.html;
root /usr/local/openresty/nginx/html;
}
}
}
Use of nginx
enable nginx
nginx -c /usr/local/nginx/conf/nginx.conf
nginx -s signal
signal can be one of the following commands:
- stop — stop nginx directly
- quit — will exit after processing the current request, also known as graceful shutdown
- reload — reload the configuration file, equivalent to restart // rolling upgrade
- reopen — reopen log files
nginx with lua -- openresty
OpenResty® is a high-performance web platform based on Nginx and Lua, which integrates a large number of sophisticated Lua libraries, third-party modules and most dependencies. It is used to easily build dynamic web applications, web services and dynamic gateways that can handle ultra-high concurrency and scalability.
By integrating lua, Nginx can be effectively turned into a powerful web server!
Environment construction
Directly build openresty, nginx + lua package
brew tap homebrew/nginx
brew install homebrew/nginx/openresty
If all went well, OpenResty should already be installed.
For convenience, use docker to install OpenResty directly here:
create a new Dockerfile and write:
#Dockerfile
FROM openresty/openresty:trusty
RUN apt-get update && apt-get install -y vim
You can install openresty directly, but there is no vim in the bash of the container, and it is very troublesome to change the code in it, so I built an image myself.
then build the image
docker build -t openresty .
docker container run -itd -p 80:80 --name test openresty
Build a container named test.
ok, it is running now, visit http://localhost, the welcome page of openresty has appeared
run
docker ps -a
can be seen:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06c9a63607eb openresty "/usr/local/openrest…" 4 hours ago Up 25 minutes 0.0.0.0:80->80/tcp test
Service has already started.
Let's enter the container and take a look:
docker exec -it test bash
Inside is the nginx directory.
Our configuration is
vi usr/local/openresty/nginx/conf/nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
Which introduces /etc/nginx/conf.d/*.conf; our server configuration is here.
Now this etc/nginx/conf.d/default.conf can happily configure nginx.
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
The home page directory we access is index.html under the root designation, root is the designated root directory, and index designates the default access file.
how to combine lua
lua provides many instructions, such as:
- content_by_lua_file directly adds the path of the lua file, accepts the request, and processes the response.
- lua_package_path Set the path of the extension library written in lua code, which is used by require in the lua file.
set_by_lua_file $var
- rewrite_by_lua_file redirection of lua files
- access_by_lua_file access control for lua files
- header_filter_by_lua_file set header and cookie
- init_by_lua_file Executed when the ginx Master process loads the configuration; usually used to initialize the global configuration/preload the Lua module
...
lua commonly used methods and constants:
ngx.arg[index] #ngx指令参数,当这个变量在set_by_lua或者set_by_lua_file内使用的时候是只读的,指的是在配置指令输入的参数
ngx.var.varname #读写NGINX变量的值,最好在lua脚本里缓存变量值,避免在当前请求的生命周期内内存的泄漏
ngx.config.ngx_lua_version #当前ngx_lua模块版本号
ngx.config.nginx_version #nginx版本
ngx.worker.pid #当前worker进程的PID
...
print() #与 ngx.print()方法有区别,print() 相当于ngx.log()
ngx.ctx #这是一个lua的table,用于保存ngx上下文的变量,在整个请求的生命周期内都有效,详细参考官方
ngx.location.capture() #发出一个子请求
ngx.location.capture_multi() #发出多个子请求
ngx.status #读或者写当前请求的相应状态. 必须在输出相应头之前被调用
ngx.header.HEADER #访问或设置http header头信息
ngx.req.set_uri() #设置当前请求的URI
ngx.set_uri_args(args) #根据args参数重新定义当前请求的URI参数
ngx.req.get_uri_args() #返回一个lua table,包含当前请求的全部的URL参数
ngx.req.get_post_args() #返回一个LUA TABLE,包括所有当前请求的POST参数
ngx.req.get_headers() #返回一个包含当前请求头信息的lua table
ngx.req.set_header() #设置当前请求头header某字段值.当前请求的子请求不会受到影响
ngx.req.read_body() #在不阻塞ngnix其他事件的情况下同步读取客户端的body信息
ngx.time() #返回当前时间戳
ngx.re.match(subject,regex,options,ctx) #ngx正则表达式匹配
...
start openresty
Add a sentence under the location of etc/nginx/conf.d/default.conf
location /test {
default_type text/html;
content_by_lua_block {
ngx.say("HelloWorld")
}
}
Restart nginx nginx -s reload
and visit http://localhost/test to see the helloworld we wrote.
Another example
location = /sum {
# 只允许内部调用
internal;
# 这里做了一个求和运算只是一个例子,可以在这里完成一些数据库、
# 缓存服务器的操作,达到基础模块和业务逻辑分离目的
content_by_lua_block {
local args = ngx.req.get_uri_args()
ngx.say(tonumber(args.a) + tonumber(args.b))
}
}
location = /app/test {
content_by_lua_block {
local res = ngx.location.capture(
"/sum", {args={a=3, b=8}}
)
ngx.say("status:", res.status, " response:", res.body)
}
}
Request the internal interface and return the result.
For example:
lua can help us do jumps. Rewrite url and so on.
location = /stream {
rewrite_by_lua_block {
return ngx.redirect('http://open.toutiao.com');
}
}
for example
location /print_param {
default_type text/html;
content_by_lua_block {
local arg = ngx.req.get_uri_args()
for k,v in pairs(arg) do
ngx.say("[GET ] key:", k, " v:", v)
end
ngx.req.read_body() #解析 body 参数之前一定要先读取 body
local arg = ngx.req.get_post_args()
for k,v in pairs(arg) do
ngx.say("[POST] key:", k, " v:", v)
end
}
}
Visit http://localhost/print_param?a=1&b=2&c=3
to see [GET ] key:bv:2 [GET ] key:av:1 [GET ] key:cv:3
location /res {
default_type text/html;
local table = {
"hello, ",
{"world: ", true, " or ", false,
{": ", nil}}
}
ngx.print(table)
}
ngx.print highlights fragmented strings. hello, world: true or false:
location /res {
content_by_lua_block {
ngx.header['Content-Type'] = 'text/json; charset=UTF-8'
local str = '{"a":1,"b":"ss","c":{"c1":1,"c2":2},"d":[10,11],"1":100}'
ngx.say(str)
}
}
Return json, lua does not seem to have a json object similar to js. .