十分钟了解Nginx

作者: DemonLms | 来源:发表于2019-04-23 16:03 被阅读10次

    nginx 入门、安装、命令、配置、优化

    操作系统:CentOS Linux 7
    Nginx版本:yum安装1.12.2 、编译安装1.14.2

    一、安装

    1. yum安装

    安装源

    [root@localhost ~]# yum list nginx
    [root@localhost ~]# rm -rf /etc/yum.repos.d/*
    [root@localhost ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
    [root@localhost ~]# curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    [root@localhost ~]# yum clean all && yum makecache
    

    启动一个Nginx

    [root@localhost ~]# yum install -y nginx
    [root@localhost ~]# nginx
    [root@localhost ~]# curl localhost
    

    yum安装Nginx的目录结构

    [root@localhost ~]# find / -name nginx
    /etc/logrotate.d/nginx #滚动日志
    /etc/nginx #配置文件
    /usr/lib64/perl5/vendor_perl/auto/nginx #http-perl
    /usr/lib64/nginx #molules
    /usr/sbin/nginx #bin文件
    /usr/share/nginx #html/molules
    /var/lib/nginx #tmp
    /var/log/nginx #log
    [root@localhost ~]# yum remove -y nginx
    [root@localhost ~]# find / -name nginx
    

    2. 编译安装

    准备环境依赖

    [root@localhost ~]# rm -rf /etc/yum.repos.d/*
    [root@localhost ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
    [root@localhost ~]# curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    [root@localhost ~]# yum install -y gcc gcc-c++ make pcre-devel zlib-devel
    

    编译安装Nginx

    [root@localhost ~]# curl -o nginx-1.14.2.tar.gz http://nginx.org/download/nginx-1.14.2.tar.gz
    [root@localhost ~]# tar -xf nginx-1.14.2.tar.gz
    [root@localhost ~]# cd nginx-1.14.2
    [root@localhost nginx-1.14.2]# ./configure
    [root@localhost nginx-1.14.2]# make && make install
    [root@localhost nginx-1.14.2]# find / -name nginx
    /root/nginx-1.14.2/objs/nginx #编译文件
    /usr/local/nginx #安装目录
    /usr/local/nginx/sbin/nginx #bin文件
    

    启动一个Nginx

    [root@localhost sbin]# ./nginx
    [root@localhost sbin]# curl localhost
    

    3. 编译安装进阶

    3.1. 指定编译参数

    [root@localhost nginx-1.14.2]# ./configure --prefix=$PWD/nginx
    

    3.2. 安装官方模块

    [root@localhost nginx-1.14.2]# ./configure --prefix=$PWD/nginx --with-stream
    

    3.3. 安装自定义模块
    3.3.1 编写Nginx自定义模块

    [root@localhost nginx-1.14.2]# mkdir -p modules/ngx_http_hello_world_module
    [root@localhost nginx-1.14.2]# cd modules/ngx_http_hello_world_module
    [root@localhost ngx_http_hello_world_module]# touch ngx_http_hello_world_module.c config
    

    ngx_http_hello_world_module.c

    #include "ngx_core.h"
    #include "ngx_string.h"
    #include "ngx_buf.h"
    #include "ngx_module.h"
    #include "ngx_conf_file.h"
    #include "ngx_http.h"
    #include "ngx_http_request.h"
    #include "ngx_http_config.h"
    #include "ngx_http_core_module.h"
    static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t *r)
    {
        if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD)))
            return NGX_HTTP_NOT_ALLOWED;
        ngx_int_t rc = ngx_http_discard_request_body(r);
        if (rc != NGX_OK)
            return rc;
        ngx_str_t type = ngx_string("text/plain");
        ngx_str_t response = ngx_string("Hello World!\n");
        r->headers_out.status = NGX_HTTP_OK;
        r->headers_out.content_length_n = response.len;
        r->headers_out.content_type = type;
        rc = ngx_http_send_header(r);
        if (rc == NGX_ERROR || rc > NGX_OK || r->header_only)
            return rc;
        ngx_buf_t *b;
        b = ngx_create_temp_buf(r->pool, response.len);
        if (b == NULL)
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        ngx_memcpy(b->pos, response.data, response.len);
        b->last = b->pos + response.len;
        b->last_buf = 1;
        ngx_chain_t out;
        out.buf = b;
        out.next = NULL;
        return ngx_http_output_filter(r, &out);
    }
    static char *ngx_http_hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
    {
        ngx_http_core_loc_conf_t *clcf;
        clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
        clcf->handler = ngx_http_hello_world_handler;
        return NGX_CONF_OK;
    }
    static ngx_command_t ngx_http_hello_world_commands[] = {
        {ngx_string("hello_world"), NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF |
            NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, ngx_http_hello_world, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL},
        ngx_null_command
    };
    static ngx_http_module_t ngx_http_hello_world_module_ctx = {
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
    };
    ngx_module_t ngx_http_hello_world_module = {
        NGX_MODULE_V1,
        &ngx_http_hello_world_module_ctx,
        ngx_http_hello_world_commands,
        NGX_HTTP_MODULE,
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        NGX_MODULE_V1_PADDING
    };
    

    config

    ngx_addon_name=ngx_http_hello_world_module
    HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module"
    NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c"
    

    3.3.2 编译自定义模块

    [root@localhost nginx-1.14.2]# ./configure --prefix=$PWD/nginx --with-stream --add-module=modules/ngx_http_hello_world_module
    [root@localhost nginx-1.14.2]# make && make install
    [root@localhost nginx-1.14.2]# vim nginx/conf/nginx.conf
    
    server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            # root   html;
            # index  index.html index.htm;
            hello_world;
        }
    }
    

    3.3.3 启动nginx,测试hello world

    [root@localhost nginx-1.14.2]# nginx/sbin/nginx 
    [root@localhost nginx-1.14.2]# curl localhost
    Hello World!
    

    3.3.4 Nginx开发
    ​ Tengine http://tengine.taobao.org/
    ​ Openresty http://openresty.org/cn/

    二、Nginx命令

    [root@localhost ~]# nginx -h 
    nginx version: nginx/1.14.2
    Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
    Options:
      -?,-h         : this help
      -v            : show version and exit
      -V            : show version and configure options then exit
      -t            : test configuration and exit
      -T            : test configuration, dump it and exit
      -q            : suppress non-error messages during configuration testing
      -s signal     : send signal to a master process: stop, quit, reopen, reload
      -p prefix     : set prefix path (default: /root/nginx-1.14.2/nginx/)
      -c filename   : set configuration file (default: conf/nginx.conf)
      -g directives : set global directives out of configuration file
    
    [root@localhost ~]# nginx -v
    nginx version: nginx/1.14.2
    [root@localhost ~]# nginx -V
    nginx version: nginx/1.14.2
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 
    configure arguments: --prefix=/root/nginx-1.14.2/nginx --with-stream --add-module=modules/ngx_http_hello_world_module
    
    [root@localhost ~]# nginx -t
    nginx: the configuration file /root/nginx-1.14.2/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /root/nginx-1.14.2/nginx/conf/nginx.conf test is successful
    
    [root@localhost ~]# nginx -s quit
    [root@localhost ~]# nginx -c /etc/nginx-2.conf
    [root@localhost ~]# nginx -g 'worker_processes 4;'
    

    三、Nginx配置文件

    #user  nobody; #worker用户
    worker_processes  1; #worker进程数,cat /proc/cpuinfo | grep "processor" | wc -l
    #error_log  logs/error.log; #错误日志路径
    #error_log  logs/error.log  notice; #错误日志路径notice级别
    #error_log  logs/error.log  info; #错误日志路径info级别
    #pid        logs/nginx.pid; #pid路径
    events { #events块
        worker_connections  1024; #每个worker最大开启连接数,ulimit -n
    }
    http { #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"';
        # main级别日志输出格式
        #access_log  logs/access.log  main; #访问日志main级别
        sendfile        on; #开启sendfile,作为静态服务器时性能显著提高
        #tcp_nopush     on; #包攒到一定大小再发送,开启sendfile时生效
        #keepalive_timeout  0;
        keepalive_timeout  65; #连接超时(秒)
        #gzip  on; #开启压缩
        server { #server段
            listen       80; #监听80端口
            server_name  localhost; #绑定localhost
            #charset koi8-r;
            #access_log  logs/host.access.log  main;
            location / { #匹配uri
                root   html; #设置root目录
                index  index.html index.htm; #默认首页
            }
            #error_page  404              /404.html;
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html; #错误码和错误页
            location = /50x.html {
                root   html;
            }
        }
    }
    

    main/events块指令集 http://nginx.org/en/docs/ngx_core_module.html
    http块指令集 http://nginx.org/en/docs/http/ngx_http_core_module.html

    四、基本用例

    1. 静态资源服务器

    直接启动Nginx就是个静态资源服务器。
    alias和root的区别

    location /foo {
        root /a/b;
    }
    # 当请求的uri为/foo/c.html时,实际请求的文件路径是/a/b/foo/c.html
    location /bar {
        alias /x/y;
    }
    # 当请求的uri为/bar/z.html时,实际请求的文件路径是/x/y/z.html
    # alias对末尾的/敏感,alias末尾与uri末尾保持一致
    

    rewrite的用法

    location /foo {
        rewrite /foo/(.*) /bar/$1 break;
        root /a/b;
    }
    # 当请求的uri为/foo/c.html时,将请求改写为/bar/c.html,实际请求的文件路径是/a/b/bar/c.html
    location /foo {
        rewrite /foo/(.*) /bar/$1 last;
        root /a/b;
    }
    # 当请求的uri为/foo/c.html时,将请求改写为/bar/c.html,重新寻找location块匹配,实际请求的文件路径是/x/y/c.html
    location /foo {
        rewrite /foo/(.*) /bar/$1 permanent;
    }
    # 当请求的uri为/foo/c.html时,将请求改写为/bar/c.html,直接返回301跳
    location /foo {
        rewrite /foo/(.*) /bar/$1 redirect;
    }
    # 当请求的uri为/foo/c.html时,将请求改写为/bar/c.html,直接返回302跳
    

    break/last是同一个连接的内部处理过程,permanent/redirect是两次连接;
    break不再执行location匹配,last执行多次location匹配,通常在server中使用last,在location中使用break;
    301跳会缓存,302跳不会;

    2. 简单文件服务器

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        location / {
            autoindex on;
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
    

    当路径下存在index.html index.htm 时autoindex不生效

    3.代理服务器

    3.1正向代理

    正向代理:代理客户端称为正向代理,如爬虫使用的代理服务器。基本是固定写法。

    server {  
        resolver 8.8.8.8;
        listen 8888;
        location / {
            proxy_pass http://$http_host$request_uri;
            proxy_set_header HOST $http_host;
        }
    }
    

    3.2 反向代理

    正向代理:代理服务端称为反向代理,如通过代理java隐藏端口。基本是固定写法。

    server {
        listen       80;
        server_name  _;
        location =/index.html {
            return 200 "index\n";
        }
    }
    server {
        listen       81;
        server_name  _;
        location /proxy {
            proxy_pass http://localhost/;
        }
    }
    

    如果不想改变原地址中的uri,proxy_pass中就不要写uri!

    4.负载均衡

    利用一定的策略将网络负载分摊到网络集群的各个服务上,从而减轻服务器负载并提高用户体验。

    server {
        listen       80 default_server;
        server_name  _;
        location / {
            proxy_pass http://balance;
        }
    }
    upstream balance {
        server localhost:81;
        server localhost:82;
    }
    server {
        listen       81;
        server_name  _;
        location / {
            return 200 "1\n";
        }
    }
    server {
        listen       82;
        server_name  _;
        location / {
            return 200 "2\n";
        }
    }
    

    Nginx负载均衡策略:round robin、weight、ip_hash、least_conn、fair(3)、url_hash(3)

    5.TCP/UDP代理

    TCP/UDP协议的反向代理。

    stream{
        upstream mysql{
            server localhost:3306;
        }
        server{
            listen 3307;
            proxy_pass mysql;
        }
    }
    

    需要stream模块支持

    五、深度优化

    1、安全优化

    1.1 隐藏Nginx软件名和版本号

    [root@localhost /]# curl -I localhost
    HTTP/1.1 200 OK
    Server: nginx/1.12.2
    Date: Tue, 23 Apr 2019 06:23:27 GMT
    Content-Type: application/octet-stream
    Content-Length: 2
    Connection: keep-alive
    
    • 方案1:修改nginx.conf添加
    server_tokens off;
    
    • 方案2:修改$NGINX_HOME/src/core/nginx.h(不推荐
    #define NGINX_VERSION      "1.14.2"
    #define NGINX_VER          "nginx/" NGINX_VERSION
    // 随意修改以上两个字段(注意这是C代码,#不是注释的意思)
    #define NGINX_VERSION      "7.5.1"
    #define NGINX_VER          "IIS/" NGINX_VERSION
    
    • 方案3:修改$NGINX_HOME/src/core/nginx.h
    static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
    static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
    // 随意修改以上两个字段
    static u_char ngx_http_server_string[] = "Server: IIS" CRLF;
    static u_char ngx_http_server_full_string[] = "Server: " "IIS/7.5.1" CRLF;
    
    • 隐藏40x、50x页面的软件名版本号:修改nginx.conf添加
    error_page 400 401 402 403 404 405 415 /40x.html;
    location = /40x.html {
        return 200 "not found.";
    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        return 200 "error.";
    }
    

    1.2 非法域名解析

    server {
        listen 80 default_server;
        server_name _;
        rewrite ^(.*) http//:www.example.com/$1 permanent;
    }
    

    1.3 黑白名单

    location / {
       allow 127.0.0.1;
       deny 192.168.1.1;
    }
    

    1.4 DDOS攻击

    # 访问频率限制
    limit_req_zone $binary_remote_addr zone=perip:100m rate=1r/s;
    server {  
        limit_req zone=perip burst=5 nodelay;
    }
    

    2、性能优化

    2.1 优化进程和连接数

    worker_processes    4; #auto=逻辑核数,高io的可以再调大;如果服务器有其他负载按需设置;
    worker_cpu_affinity 0001 0010 0100 1000; #cpu亲和性,指定每个线程运行在哪个核上;
    events {
        use epoll;  #显式指定采用epoll,如果不知道是什么请让Nginx自己决定最优方案;
        worker_connections  1024;#每个进程最大可打开连接数受制于ulimit -n;
    }
    

    2.2 高效文件传输

    # 设置传输参数
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    server_tokens off;
    server_names_hash_bucket_size 128;
    server_names_hash_max_size 512;
    keepalive_timeout 65;
    client_header_timeout 15s;
    client_body_timeout 15s;
    send_timeout 60s;
    # 设置压缩参数
    gzip on;
    gzip_disable "msie6";
    gzip_min_length 1k;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 3;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png;
    # 为静态资源设置合理的过期时间
    expires    -1;
    

    相关文章

      网友评论

        本文标题:十分钟了解Nginx

        本文链接:https://www.haomeiwen.com/subject/glavgqtx.html