• Nginx:配置


    Nginx 是一个高性能的 HTTP 和反向代理 Web 服务器。Nginx 可以作为一个HTTP服务器进行网站的发布处理,也可以作为反向代理进行负载均衡的实现。

    1、Nginx 工作原理

    Nginx 默认采用多进程工作方式,启动后,生成一个 Master 进程和多个 Woker 进程。

    • Master 进程:读取和评估配置文件,管理 Worker 进程。
    • Worker 进程:处理网络事件

    master 进程根据配置文件生成一个监听相应端口的 socket,然后 fork 多个 worker 子进程,每个 worker 进程都可以监听 socket 消息。为了解决 accept 惊群问题,当一个连接到来,每个 worker 都能收到通知,但是只有一个 worker 能够建立连接,其他 worker 连接失败。nginx 通过互斥锁 accept_mutex 控制 worker 进程接收连接,只有获得了 accept_mutex 的进程才会添加 accept 事件。

    nginx 使用变量 ngx_accept_disabled 来控制是否去竞争 accept_mutex 锁。

    ngx_accept_disabled = nginx单进程的连接总数/8 - 空闲连接数量
    
    • 1

    当 ngx_accept_disabled > 0,不会尝试获取 accept_mutex 锁,该值越大,让出的机会越多,其他进程获取锁的机会越大。不添加 accept,每个 worker 进程的连接数得到控制,实现了连接平衡。

    在这里插入图片描述

    2、Nginx 安装启动

    2.1、安装

    安装第三方软件:prce、zlib、OpenSSL

    # 安装第三方软件
    # prce 库
    wget https://sourceforge.net/projects/pcre/files/pcre/8.44/pcre-8.44.tar.gz
    tar -zxvf pcre-8.44.tar.gz
    cd pcre-8.44/
    ./configure
    make
    make install
    
    # zlib 库
    wget https://nchc.dl.sourceforge.net/project/libpng/zlib/1.2.11/zlib-1.2.11.tar.gz
    tar -zxvf zlib-1.2.11.tar.gz
    cd zlib-1.2.11/
    ./configure
    make
    make install
    
    # OpenSSL 库
    wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz
    tar -zxvf openssl-1.1.1g.tar.gz
    cd openssl-1.1.1g/
    ./config
    make
    make install
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    安装 Nginx

    wget http://nginx.org/download/nginx-1.16.1.tar.gz
    tar -zxvf nginx-1.16.1.tar.gz
    cd nginx-1.16.1/
    ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --with-http_v2_module --with-openssl=../openssl-1.1.1g
    make
    make install
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    configure 命令支持的参数

    --prefix=path # 指定 Nginx 安装目录,默认/usr/local/nginx
    --sbin-path=path # 设置 Nginx 的可执行文件路径,默认 prefix/sbin/nginx
    
    • 1
    • 2

    2.2、启动

    启动 nginx 需要指定配置文件,配置文件路径

    /usr/local/nginx/conf
    /etc/nginx
    /usr/local/etc/nginx
    
    • 1
    • 2
    • 3

    启动 nginx

    # 启动 nginx
    /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
    
    # 重启,nginx 支持热启动
    nginx -s reload
    
    • 1
    • 2
    • 3
    • 4
    • 5

    nginx 命令

    nginx -s signal
    quit 	# 正常关闭
    stop 	# 立即关闭(快速关闭)
    reload 	# 重新加载配置文件
    reopen 	# 重新打开日志文件
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、配置文件

    3.1、块配置

    顶级指令

    • events:工作模式,连接处理
    • http:http 协议
    • mail:mail 协议
    • stream:tcp 协议

    例如:配置 web 服务器

    # work 进程个数,建议修改成 cpu 内核数
    worker_process 4
    # 绑定 cpu
    worker_cpu_affinity 1000 0100 0010 0001
    
    # 工作模式
    events {
    	use epoll;			    # IO 多路复用方式
    	worker_connections 1024; # 单个 worker 进程的最大并发连接数
    }
    
    # 设定 http 服务器
    http {
        # 添加配置文件
        include /etc/nginx/mime.type;
        include /etc/nginx/conf.d/ *.conf;
            
        # 设置日志格式
        access_log /var/log/nginx/access.log;
        
        # 开启 sendfile
        sendfile on;
        
        # 防止网络阻塞,立即发送
        tcp_nopush on;
        tcp_nodelay on;
        
        # 连接超时时间
        keepalive_timeout 60;
        
        # 开启 gzip 压缩
        gzip on;
        gzip_disable "MISE [1-6]\.(?!.*SV1)";
        
        # 设定请求缓冲
        client_header_buffer_size 1k;
        large_client_header_buffers 4k;
        
        # 设定负载均衡的服务器列表
        upstream backend {
            server 192.168.10.1:8080 weight=1;
            server 192.168.10.2:8080 weight=2;
        }
    	
    	# 设置服务器
    	server {
    		# 监听端口,默认80端口
    		listen  8080; 
    		# 主机名称 Host
    		server_name www.example.org;
    		
    		# 配置路径
    		location / {
    			root /root;				  # 资源路径,root + url
    			index index.html index.php; # 首页索引,顺序访问
    		}
            
            # 返回状态码,重定向 url
            location /permanently/moved/url {
     	    	return 301 http://www.example.com/moved/here;
            }
     
    		# 处理错误
    		# error_page code[=answer-code] url|@named_location
    		error_page	404 =301  @fallback;
    		location @fallback {
    			proxy_pass http://backend;
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    3.2、代理 & 负载均衡

    3.2.1、代理
    • 正向代理:代理客户端。当用户无法正常访问外部资源,通过代理的方式,让用户绕过防火墙,从而连接到目标网络或者服务。
    • 反向代理:代理服务器。代理服务器接收网络请求,然后将请求转发给内网上的服务器,并将处理结果返回给用户的过程。

    Nginx 实现动静分离:反向代理过程中,判断资源的类型,如果是静态资源,则直接从 Nginx 发布路径读取,不需要从后端服务器获取。

    正向代理
    resolver 114.114.114.114 8.8.8.8; # 配置正向代理 dns 服务器
    server {
        resolver_timeout 5s;
        listen 80;
        location / {
            proxy_pass http://$host$request_uri;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    反向代理
    upstream backend {
        server localhost:8080 weight=1;
        server localhost:8081 weight=2;
    }
    
    server {
        listen  80;
        server_name localhost;
    
        location / {
            root  /usr/local/nginx/html/www;				
            index  index.html index.php;
        }
    
        # 静态请求,nginx 处理
        location ~ .(images|javascript|js|css|flash|media|static)$ {
            sendfile on;
            root /var/www;   
        }
    
        # 动态请求
        location * .(jsp|do)$ {  
            proxy_pass http://backend; # 反向代理
            proxy_set_header Host $host;
        }
    
        error_page 500 502 503 504 /50x.html;
        location /50x.html {
            root /var/www;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    3.2.2、负载均衡

    upstream 机制提供了负载均衡功能,可以将请求负载分担到集群服务器的某个服务器上。

    工作流程

    • 分析客户端请求报文,构建发往上游服务器的请求报文;
    • 调用 ngx_http_upstream_init 开始与上游服务器建立 tcp 连接;
    • 发送构建的请求报文
    • 接收来自上游服务器的响应头并进行解析,之后往下游转发
    • 接收来自上有服务器的响应体,并进行转发

    支持的负载分配方式,前三种为 Nginx 原生支持的分配方式,后三种为第三方支持的分配方式:

    • 轮询:默认,按照请求的时间顺序轮流分配到不同的后端服务器
    • 权重:轮询的基础上指定轮询比率
    • ip_hash:每个请求按照访问 IP的 hash 值分配,这样同一用户连续的 Web 请求都会被分发到同一服务器进行处理,解决 session 问题。
    • fair 按照后端服务器的响应时间分配请求,响应时间短的优先分配。
    • url_hash:按照访问 url 的 hash 结果来分配请求,使得每个 url 定向到同一个后端服务器,主要应用于后端服务器为缓存时的场景。
    • least_conn:把请求转发给连接数较少的后端服务器。

    3.3、Nginx 缓存

    启用缓存时,Nginx 将响应保存在磁盘缓存中,用来响应客户端,不必每次都为同一内容代理请求。

    配置代码如下

    upstream backend {
        server 192.168.10.1:8080 weight=1;
        server 192.168.10.2:8080 weight=2;
    }
    
    # 设置 nginx 缓存资源的存放地址
    proxy_cache_path /cache keys_zone=cache:10m max_size=10g inactive=60m use_temp_path=off;
    
    server {
        listen 80; 
    
        location / {
            proxy_pass http://backend; 
            
            # 配置缓冲区:数量,大小
            proxy_buffers 8 4k;
            
            # 启用 proxy 缓存,并指定 key_zone
            proxy_cache cache; 			 
    
            # 指定要缓存的请求
            proxy_cache_key "$host$request_uri $cookie_user"; # 缓存的key,一般为URL+请求参数
            proxy_cache_min_uses 5;			  # 缓存响应前,相同 key 请求的最小次数
            proxy_cache_methods GET POST;      # 支持缓存的请求方式
            
            # 限制缓存
            proxy_cache_valid 200 304 6h; # 设置缓存响应有效时间,设置状态码的有效时间
            proxy_cache_valid any 6m;
            
            # 跳过缓存
            proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment; 
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3.4、Nginx 限流

    nginx 使用漏桶算法按请求速率对模块进行限速,能够强行保证请求的实时处理速度不会超过设置的阈值。

    漏桶算法的思想:水(请求)从上方倒入水桶,从水桶下方流出(被处理),来不及流出的水存在水桶中(缓存),以固定速率流出。水桶满后,水溢出(丢弃请求)。请求放入缓存,匀速处理,多余的请求直接丢弃。

    4、http 配置使用

    处理 http 配置项分为 4 个步骤

    • 创建用于存储配置项参数的数据结构
    • 设定配置项的限制条件与回调方法
    • 实现回调方法,自定义或预设
    • 合并不同级别的配置块中出现的同名配置项。

    4.1、配置结构

    定义该模块的配置结构来存储配置项(配置命令)。Nginx 的配置信息分为三个作用域 main, server, location,每个模块提供的配置命令需要定义不同的模块配置结构来存储。

    typedef struct {
    	// 定义配置命令 
    }ngx_http_loc_conf_t;
    
    • 1
    • 2
    • 3

    4.2、配置命令

    4.2.1、设置配置命令

    commands 数组用于定义模块的配置文件参数,每一个数组元素都是 ngx_command_t 类型,用于解析一个配置项,数组的结尾以 ngx_null_command 表示。Nginx 在解析配置文件中的一个配置项时会首先遍历所有的模块,即通过遍历 commands 数组,当遍历到 ngx_null_command 时,会停止使用当前模块解析该配置。

    typedef struct ngx_command_s         ngx_command_t;
    // ngx 命令
    struct ngx_command_s {
        // 配置项名称,"listen"
        ngx_str_t             name; 
        // 配置项类型,配置指令属性合集,指定配置项的位置和携带的参数个数
        ngx_uint_t            type; 
        // 配置项参数处理方法
        char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
        // 在配置文件中的偏移量
        ngx_uint_t            conf;
        // 使用预设的解析方法解析配置项
        ngx_uint_t            offset;
        // 配置项读取后的处理方法,必须是 ngx_conf_post_t 结构的指针
        void                 *post;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    4.2.2、设置回调方法

    当某个配置块出现对应的配置项(配置命令)时,Nginx 回调 set 指向的回调方法,用于解析命令的处理方法。在 set 方法中获取配置信息,设置 handler 回调阶段和回调方法,也可以直接采用预设方法。

    static char *ngx_http_test_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
        ngx_http_core_loc_conf_t *clcf;
        
        // 找到 conf 所属的配置块
        clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
        
        // 在 NGX_HTTP_CONTENT_PHASE 阶段,调用该请求
        clcf->handler = ngx_http_test_handler;
        
    	return NGX_CONF_OK;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4.3、合并配置命令

    合并不同配置块间的同名配置项,如:http,、server、location块出现的同名命令

    5、http 配置解析

    在这里插入图片描述

    流程简单记作:

    • 初始化模块时,调用各模块的 create_(main,srv,loc)_conf
    • 调用各模块的 preconfiguration,也就是模块的初始化方法
    • 解析 http 块配置,对不同作用域块遍历 command 并回调 set 方法
    • 合并不同块内的同名配置项

    6、参考

    • 陶辉. 深入理解Nginx:模块开发与架构解析[M]. 北京:机械工业出版社,2016.
    • 聂松松等. Nginx底层设计与源码分析[M]. 北京:机械工业出版社,2021.
  • 相关阅读:
    Android 底层新增按键系统上层适配详解
    静态代码块和构造代码块
    【PS-7】移动工具
    (十五) 共享模型之工具【线程池】
    数据结构 循环队列
    制作Java小游戏~扫雷游戏
    什么是Verilog
    [unity]保存文件的路径设置
    PDF怎么编辑修改文字?
    tomcat的安装与部署
  • 原文地址:https://blog.csdn.net/you_fathe/article/details/127995926