A preliminary study of nginx

nginx

nginx是俄罗斯人写的轻量级http服务器,Nginx 以事件驱动的方式编写,有非常好的性能,同时也是一个非常高效的反向代理、负载均衡。

Nginx 稳定性高,模块库丰富,配置灵活,系统资源的消耗低。响应静态页面的速度非常快

what nginx does

  1. Handling static files
  2. Reverse proxy, load balancing and fault tolerance
  3. large concurrency
  4. 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

  1. 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
  2. Then fork out multiple child processes, and then the child processes will compete to accept new connections
  3. Three-way handshake with the client to get the socket of the established connection, and then create the Nginx encapsulation of the connection
  4. Nginx or client to actively close the connection

nginx configuration

Divided into several modules:

  1. 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.
  2. http: Some configuration parameters related to providing http services. For example: whether to use keepalive, whether to use gzip for compression, etc.
  3. 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.
  4. 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. .

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324780362&siteId=291194637