美文网首页
初识Nginx

初识Nginx

作者: 谭英智 | 来源:发表于2020-08-05 17:54 被阅读0次

    使用场景

    nginx-use

    特性

    IO多路复用

    使用epoll模型,高并发处理客户端的请求

    CPU亲和

    把working进程与CPU绑定,避免working进程不必要的在CPU之间切换

    sendfile

    nginx-sendfile

    从读文件到返回socket,都是从内核态完成,不需要经过用户态,减少拷贝和上下文的切换

    模块说明

    功能模块 模块说明
    ngx_http_core_module 包含一些核心的http参数配置,对应Nginx的配置为http区块部分
    ngx_http_access_module 访问控制模块,用来控制网站用户对Nginx的访问
    ngx_http_gzip_module 压缩模块,对返回的数据压缩,属于性能优化模块
    ngx_http_proxy_module proxy代理模块
    ngx_http_upstram_module 负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查
    ngx_http_rewrite_module URL地址重写模块
    ngx_http_limit_conn_module 限制用户并发连接数及请求数模块
    ngx_http_limit_req_module 根据定义的key限制Nginx请求过程的速率
    ngx_http_log_module 访问日志模块,以指定的格式记录Nginx客户访问日志等信息
    ngx_http_auth_basic_module Web认证模块,设置web用户通过账号密码访问Nginx
    ngx_http_ssl_module ssl模块,用于加密的http连接,如https
    ngx_http_stub_status_module 记录Nginx基本访问状态信息等的模块

    常用变量

    变量 说明
    $args 请求中的参数,如[www.123.com/1.php?a=1&b=2args就是a=1&b=2](http://www.123.com/1.php?a=1&b=2的args就是a=1&b=2)
    $content_length HTTP请求信息里的"Content-Length"
    $conten_type HTTP请求信息里的"Content-Type"
    $document_root nginx虚拟主机配置文件中的root参数对应的值
    $document_uri 当前请求中不包含指令的URI,如[www.123.com/1.php?a=1&b=2document_uri就是1.php](http://www.123.com/1.php?a=1&b=2的document_uri就是1.php),不包含后面的参数
    $host 主机头,也就是域名
    $http_user_agent 客户端的详细信息,也就是浏览器的标识,用curl -A可以指定
    $http_cookie 客户端的cookie信息
    $limit_rate 如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
    $remote_addr 客户端的公网ip
    $remote_port 客户端的port
    $remote_user 如果nginx有配置认证,该变量代表客户端认证的用户名
    $request_body_file 做反向代理时发给后端服务器的本地资源的名称
    $request_method 请求资源的方式,GET/PUT/DELETE等
    $request_filename 当前请求的资源文件的路径名称,相当于是document_root/document_uri的组合
    $request_uri 请求的链接,包括document_uri和args
    $scheme 请求的协议,如ftp,http,https
    $server_protocol 客户端请求资源使用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等
    $server_addr 服务器IP地址
    $server_name 服务器的主机名
    $server_port 服务器的端口号
    $uri 和$document_uri相同
    $http_referer 客户端请求时的referer,通俗讲就是该请求是通过哪个链接跳过来的,用curl -e可以指定

    配置文件

    路径

    默认/etc/nginx/nginx.conf

    配置说明

    • Main位于nginx.conf配置文件的最高层
    • Main层下可以有Event/HTTP
    • HTTP层下面可以有多个Server层,用于对不同的网站做配置
    • Server层可以有多个Location,用于对不同的路径进行不同模块的配置
    ########### 每个指令必须有分号结束。#################
    #user administrator administrators;  #配置用户或者组,默认为nobody nobody。
    #worker_processes 2;  #允许生成的进程数,默认为1
    #pid /nginx/pid/nginx.pid;   #指定nginx进程运行文件存放地址
    error_log log/error.log debug;  #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
    events {
        accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为on
        multi_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off
        #use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
        worker_connections  1024;    #最大连接数,默认为512
    }
    http {
        include       mime.types;   #文件扩展名与文件类型映射表
        default_type  application/octet-stream; #默认文件类型,默认为text/plain
        #access_log off; #取消服务日志    
        log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
        access_log log/access.log myFormat;  #combined为日志格式的默认值
        sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
        sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
        keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。
    
        upstream mysvr {   
          server 127.0.0.1:7878;
          server 192.168.10.121:3333 backup;  #热备
        }
        error_page 404 https://www.baidu.com; #错误页
        server {
            keepalive_requests 120; #单连接请求上限次数。
            listen       4545;   #监听端口
            server_name  127.0.0.1;   #监听地址       
            location  ~*^.+$ {       #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
               #root path;  #根目录
               #index vv.txt;  #设置默认页
               proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表
               deny 127.0.0.1;  #拒绝的ip
               allow 172.18.5.54; #允许的ip           
            } 
        }
    } 
    

    热更新配置

    #update conf files
    nginx -s reload
    #会导致除了master进程之外的进程,全部重起
    # kill -SIGHUP <master pid> 同样效果
    # 子进程退出,会发信号给master,master就会再起一个worker
    

    热部署

    cp <dir>/nginx /sbin/nginx
    kill -USR2 <pid> #开启新进程
    kill -WINCH <pid> #退出旧的worker进程
    

    开启新的log文件

    nginx -s reopen #旧的log文件会被改名,生成新的log文件
    

    状态监控

    --with-http_stub_status_module记录Nginx客户端基本访问状态信息,stub_status可以配置在server/loaction中

    location /mystatus{
        stub_status on;
    }
    
    nginx-status

    下载站点

    可以配置在http/server/location中

    location /down {
        root /opt/
        autoindex on;  #开启目录访问
        autoindex_localtime on;  #显示文件的时间
        autoindex_exact_size off; #文件大小,on的单位是bytes,off单位为kb/mb/gb
        charset utf-8; 字符集,解决乱码
    }
    

    访问限制

    limit_conn_module:连接频率限制

    limit_req_module:请求频率限制

    可以配置在http/server/location

    #rate限速速率,一秒一个request,超出则丢弃
    #limit_req_zone只能定义在http
    limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
    limit_req zone=req_zone
    #或者可以允许多3个请求延后处理
    limit_req zone=req_zone burst=3 nodelay;
    #可以使用ab工具来压测
    

    信号

    • CHLD:子进程退出,通知master,此时master会再启动一个worker
    • TERM:worker/master接收,stop
    • QUIT:worker/master接收,表示幽雅的退出,quit
    • HUP:worker/master接收,reload
    • USR1:worker/master接收,reopen
    • USR2:master接收,开启新进程
    • WINCH:master接收,退出旧进程

    reload流程

    • 向master发送HUP
    • master检验配置语法正确性
    • master打开新的监听端口
    • master用新配置启动新worker
    • master向老worker发送quit信号
    • 老worker进程关闭监听句柄,处理完当前连接,并结束自己(老连接出问题,worker进程发现有连接未处理,会导致worker进程一直不退出,master进程会根据配置,启用一个定时器,如果worker在超时之后,依然存活,则强制杀worker)

    热升级流程

    • 把旧的Nginx文件替换程新的Nginx文件,注意备份
    • 向master进程发送USR2信号
    • master进程修改pid文件名,加后缀.oldbin
    • master进程用新Nginx文件启动新master进程
    • 向老master进程发送WINCH信号,关闭老worker
    • 回滚:向老master发送HUP,向新master发送QUIT

    优雅关闭worker

    • 设置定时器,worker_shutdown_timeout
    • 关闭监听句柄
    • 关闭空闲连接
    • 循环等待全部连接关闭(对于TCP/UDP/websocket,无法做到判定连接是否结束,因为它们没有明确的界定,只能对http请求,才可以判定连接是否结束)
    • 退出进程

    用户态切换任务

    • 大量减少进程间的切换,每次切换需要5ms,如果有成万以上的进程在处理,cpu大量的时间会花费在进程切换上,导致大量的浪费cpu资源,在进程内自己切换任务,可以大大的节约cpu的时间
    • 把进程的优先级设置为-19以下,可以让操作系统多分配时间片给进程,以减少进程的切换

    事件模型

    • 使用状态机
    • 异步回调
    • io多路复用,非阻塞io

    连接池

    worker_connection的大小就是连接池的大小,里面保存了fd的相关信息,包括读/写/超时等信息

    内存池

    • connnection_pool_size:连接内存池
    • request_pool_size:请求内存池

    以上配置是内存池的初始值,如果在使用中需要更大的内存,内存池会扩大。连接内存池会在连接关闭的时候释放,请求内存池会在请求结束后释放,对于小块内存的申请,会在内存池里以链表的方式来申请内存,对于大块内存的申请还是使用系统的内除,这样做的好处是大大的减少了内存碎片

    进程间通讯

    基本同步工具

    • 信号
    • 共享内存

    高级通讯方式

    • 锁:自旋锁

      进程必须快速的使用共享内存

    • Slab内存管理器

    共享内存使用的模块

    rbtree:
    • Ngx_stream_limit_conn_module
    • Ngx_http_limit_conn_module
    • Ngx_stream_limit_req_module
    • http cache
    • ssl
    单链表
    • Ngx_http_upstream_zone_module
    • Ngx_stream_upstream_zone_module
    Ngx_http_lua_api

    同时使用红黑树和单链表,lua存的是key:value的数据,使用红黑树来存储,当超出了设定给红黑树的内存大小的时候,会是使用单链表,把最早的内存给淘汰

    Slab内存分配管理

    通过把内存切割成不同大小的slot,例如8b/16b/32b/64b..../2048b,当红黑树需要申请内存时,根据大小从某个slot的链表中申请内存

    hashmap的bucket_size

    bucket_size是用于对齐作用的,因为CPU在取数据的时候是根据cache line来取的,如果不对齐,那么bucket就有可能跨了两个或者多个cache line,导致cpu访问两次或者多次,使用对齐,可以减少cpu访问cache line的次数

    红黑树

    动态模块

    • 静态是把所有模块生成一个执行文件
    • 动态是生成动态库,多个文件,通过配置载入

    指令的合并

    值指令可以合并

    例如root/access_log/gzip

    • 子配置不存在,使用父配置块
    • 子配置存在,覆盖父配置块

    动作类指令不能合并

    例如rewrite/proxy_pass

    正则表达式

    nginx-pcre

    server的匹配顺序

    host匹配server_name

    • 精确匹配
    • *在前的泛域名
    • *在后分泛域名
    • 按文件中顺序匹配正则表达式域名
    • defalut server
      • 第一个
      • listen指定default

    HTTP请求处理时的11个阶段

    • post read
    • server rewrite
    • find configure
    • rewrite
    • post rewrite
    • preaccess: limit_conn, limit_req
    • access: auth
    • post_access
    • precontent: try_files, 分发请求
    • content: index, autoindex,concat,proxy_pass
    • log: access_log
    nginx-11

    readip

    是一个模块,需要把模块编入nginx使用,用于提取客户端的ip地址

    nginx-readip
    • set_read_ip_from: 添加可信用的ip来源,例如那台反向代理是我们自己的代理,那么我们信任在经过他的traffic添加的forward ip/real ip。
    • read_ip_header: 我们是从X-read-ip读取还是X-Forwarded-for读取
    • read_ip_recursive:是否开启读forward for第一个ip

    rewrite

    return指令

    用于重定向或者直接返回

    用法

    return code [text]/URL

    return URL

    返回的状态码
    • 444:关闭连接(Nginx自定义)
    • 301:永久重定向
    • 302:临时重定向,禁止被缓存
    • 303:临时重定向,允许改方法,禁止被缓存
    • 307:临时重定向,不允许改方法,禁止被缓存
    • 308:永久重定向,不允许改方法

    error_page指令

    用法

    error_page code file/url/location

    负载均衡

    • 水平扩展
    • 通过hash扩展
    • 通过拆分业务扩展
    upstream {
        server 127.0.0.1:8080 backup
        server 127.0.0.1:9090 weight=2 max_conns=1 max_fails=10 fail_timeout=10
        server 127.0.0.1:8888 down
    }
    #默认轮询
    

    http keepalived

    proxy_http_version 1.1
    proxy_set_header Connection "";
    keepalive <seconds> #对Server启用keepalive
    resolver address #DNS解析
    

    hash

    ip_hash; #对客户端ip进行hash
    hash key [consistent] #对自定义key进行hash,consistent代表是否启用一致性hash
    

    least_conn

    least_conn;#最少连接负载均衡
    zone name [size] #共享最少连接在worker之间
    

    反向代理

    nginx-upstream
    proxy_path url #配置上有server
    proxy_method #改写http的method
    proxy_http_version 1.0|1.1 #改写http版本
    proxy_set_header field value #改写头部属性
    proxy_pass_request_headers on|off #是否透传header
    pro
    xy_pass_request_body on|off #是否透传body
    proxy_set_body #改写body
    proxy_request_buffering on|off #是否本地缓存请求,再发送到上游
    client_body_buffer_size size #用于缓存body的buffer的大小
    client_max_body_sizr size #body最大长度,超出返回413
    client_body_temp_path path #body临时文件存储目录
    client_body_in_file_only on|clean|off #是否保存body到文件
    proxy_connect_timeout time #建立三次握手超时时间
    proxy_next_upstream http_502|timeout|error|invalid_header|off #如果上游返回502|...则选择下一个上游发送请求
    proxy_next_upstream_timeout time #请求上游得timout
    proxy_next_upstream_tries number #尝试次数
    proxy_intercept_errors on|off #error_page指令是否生效
    proxy_socket_keepalive on|off #是否启用TCP keeaplive,代表每隔一段时间,则发一个探测报文
    proxy_bind address #修改源ip地址
    proxy_send_timeout time #发送超时时间
    keepalive connections #启用http keepalive
    keepalive_requests number #一个socket可以发送的请求数
    proxy_buffer_size size # 接收上有http响应头部得最大长度
    proxy_buffers number size #接收上游http包体
    
    
    • proxy_request_buffering

      • on

        客户端网速慢

        上有并发能力低

        适应高吞吐量

      • off

        即时相应

        降低nginx读写磁盘

    浏览器缓存

    nginx-brower-cache
    etag on|off #使用文件最后修改时间和文件长度生成
    

    cache优化

    proxy_cache_lock on|off

    nginx-cache-lock

    proxy_cache_use_stale

    nginx-cache-stale

    proxy_cache_background_update

    启用后台线程update缓存,暂时先返回就得缓存给客户端

    slice size

    通过range协议将大文件分解成多个小文件缓存

    nginx-slice

    相关文章

      网友评论

          本文标题:初识Nginx

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