• Nginx教程


    Nginx教程


    1.背景


    介绍
    Nginx是一个高性能的HTTP服务器,以及反向代理服务器

    组成
    Ngnix有内核和模块组成。微结构的内核根据配置文件将一个请求映射到一个location块中,该location内的指令会启动模块来工作。

    模块分类(结构上)
    核心类
    HTTP、EVENT,以及MAIL模块。
    基础类
    HTTP的Access、FastCGI、Proxy,以及Rewrite模块。
    第三方类
    HTTP的 Upstream Request Hash、Access Key模块,以及Notice模块。

    模块分类(功能上)
    Handlers(处理器):处理请求并输出和修改handlers信息,一般只能有一个。
    Filters(过滤器):对Handlers处理过的内容进行修改,最后由Nginx输出,可以有多个。
    Proxies(代理类):HTTP Upstream之类,常与后端的服务,如fastcgi交互,实现服务代理和负载均衡功能。
    处理请求的过程所经过的模块: --> 处理器 --> 过滤器1 [--> 过滤器2 -->过滤器n] --> 

    工作模式
    工作模式有单工作进程和多工作进程两种。前者是除主进程外,只有一个单线程的工作进程;而后者是多个工作进程,每个进程是多线程的。Nginx默认是单工作进程模式。

    优势

    作为Web服务器,处理静态文件时索引效率很高
    作为代理服务器,实现高效的代理
    作为负载均衡服务器,既内部直接支持PHP,也支持代理服务器;同时支持容错和利用算法负载均衡
    性能好,采用了Poll模型支持大并发,而且内存占用少
    稳定性好,采用分阶段资源分配方式,让CPU和内存占用少
    高可用性好,支持热部署,配置修改以及版本更新无需重启服务器

    2.Nginx安装运行和测试(CentOS6)


    在Centos/Redhat上先配置yum
    #/etc/yum.repos.d/nginx.repo
    [nginx]
    name=nginx repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=0
    enabled=1
    参考自:http://nginx.org/en/linux_packages.html#stable

    安装完已经是开机启动的,所以安装完手动启动一下即可
    # yum -y install nginx 
    # service nginx start 


    补充:高级编译安装(下面的实验会用到里面的增强功能)

    ngx_cache_purge:http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
    google-perftools:https://codeload.github.com/gperftools/gperftools/zip/master


    安装正则表达式工具
    yum -y install pcre-devel
    cd /usr/local/src

    安装缓存清理插件
    tar xf ngx_cache_purge-2.3.tar.gz

    安装高性能组件
    tar xf libunwind-1.1.tar.gz
    cd libunwind-1.1
    CFLAGS=-fPIC ./configure
    make CFLAGS=-fPIC
    make CFLAGS=-fPIC install
    cd ..
    unzip gperftools-master.zip 
    cd gperftools-master
    ./autogen.sh 
    ./configure 
    make
    make install
    echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
    ldconfig

    编译安装nginx
    tar xf nginx-1.10.2.tar.gz
    ln -s nginx-1.10.2 nginx
    cd nginx
    ./configure --user=nginx --group=nginx
    --prefix=/usr/local/nginx
    --with-http_stub_status_module
    --with-http_gzip_static_module
    --with-http_ssl_module
    --with-google_perftools_module
    --add-module=/usr/local/src/ngx_cache_purge-2.3
    make
    make install
    在做./configure前优化编译过程,将auto/cc/gcc文件下面两行注释掉,不用debug方式编译
    # debug
    #CFLAGS="$CFLAGS -g"


    3.配置文件


    层次结构

    main
    events
    HTTP
    server1
    upstream1
    upstream2..n
    location1
    location2..n
    server2..n
    main:全局设置
    server:主机设置,指定主机和端口
    upstream:负载均衡设置,指定一系列后端服务器
    location:URL匹配特定位置设置,指定匹配的网页
    它们之间的继承关系为:location -> server -> main;而upstream与这三者没有关系
    这4个部分包含若干指令,这些指令主要位于主模块、EVENT模块以及HTTP模块中,同时每个部分还可以使用其他HTTP模块命令,例如HTTP SSL、HTTPGzip、HTTPAddition等模块

    配置详解

    全局配置
    user  nginx; 
    worker_processes  auto;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    worker_processes: auto会根据主机CPU线程数启动对应数量的工作进程

    events配置
    events {
        worker_connections  65535;
    }
    use epoll:已经没有了此配置,因为这是安装包默认的,会根据当前OS平台选择最优的event机制。
    worker_connections:每个工作进程打开的连接数。此参数受Linux的进程最大打开文件数限制,需要用ulimit -n 65535对应修改。
    客户端最大连接数 = worker_processes * worker_connections。

    HTTP配置
    http {
        include       /etc/nginx/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  /var/log/nginx/access.log  main;
        sendfile        on;
        tcp_nopush     on;
        keepalive_timeout  65;
        gzip  on;
        include /etc/nginx/conf.d/*.conf;
    }
    log_format:定义日志格式,这里定义了一个名为main的格式;下面的access_log日志文件的内容由main日志格式定义
    sendfile:on开启高效的文件传输模式
    tcp_nopush:on开启防止网络阻塞

    server配置
    server {
        listen              80;
        server_name         localhost;
        charset UIF-8;
        access_log          /var/log/nginx/log/host.access.log  main;
        location / {
            root            /web/wwwroot/localhost;
            index           index.html index.htm;
        }
        location ~ .(gif|jpg|jpeg|png|bmp)$ {
            root            /web/wwwroot/localhost;
            expires         30d;
        }
        location ~ ^/(upload|html) {
            root            /web/wwwroot/localhost;
            expires         30d;
        }
        location ~ .jsp$ {
            proxy_pass              http://localhost:8080;
            index                   index.jsp;
        }
        location /NginxStatus {
            stub_status             on;
            access_log              /var/log/nginx/log/NginxStatus.log;
        }   
    error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
    从上到下分别是静态文件、动态文件、服务器状态信息、网站错误页面的设置


    维护技巧


    配置文件校验
    检查配置文件语法是否有无
    nginx -t [-c $nginx.conf] 
    查看nginx版本号
    nginx -v
    查看编译的模块
    nginx -V

    启动、关闭,以及重启
    几个跟nginx有关的信号
    QUIT:处理完请求关闭工作进程
    WINCH: 从容关闭工作进程
    HUP: 重新加载配置文件,平滑重启
    USR1: 日志切换
    USR2:平滑升级可执行文件

    启动
    service nginx start
    ps aux | grep nginx
    平滑重启
    kill -HUP `cat /var/run/nginx.pid`

    4.常用功能


    反向代理

    反向代理服务器能代表所有外部客户端访问,请求内部网络服务,由于它不保存数据,因此能令后端服务器很安全。
    反向代理服务器具有本地缓存后就称为web服务加速器


    多域名跳转
    实现多个域名的访问跳转到后端同一台服务器。
    例子,以反向代理服务器A和后端服务器B为例说名,请求以www.tb.com域名从A跳转到B的/web目录,而请求以www.tb.com/admin的URL从A跳转到B的/admin目录,另外请求m.tb.com则从A跳转到B的/wap目录。配置文件代码主要如下:
    server {
        listen              80;
        server_name         www.tb.com;
        location / {
            proxy_pass      http://127.0.0.1:8080/web/;
        }
        location /admin {
            proxy_pass      http://127.0.0.1:8080/admin;
        }
    }
    server {
        listen              80;
        server_name         m.tb.com;
        location / {
            proxy_pass      http://127.0.0.1:8080/wap/;
        }
    }
    注意,proxy_pass指令启动代理功能,要重点掌握。如果location匹配的是/根目录,则proxy_pass的目标路径需要以/结尾,如果location匹配的是/根目录下的子目录,则此子目录末尾和proxy_pass指定目标路径末尾都不能以/结尾

    新旧域名重定向
    常见需要重定向的场景有:新旧域名的替换,目录结构、网页文件名,以及文件后续名的变更。例子要求如果客户端访问www.taob.com,则自动跳转到新域名www.tb.com,下面是实现代码
    方式一:
    server {
        listen       80;
        server_name   www.tb.com;
        location / {
            proxy_pass http://127.0.0.1:8080/web/;
        }
    }
    server {
        listen       80;
        server_name   www.taob.com;
        rewrite /(.*)$ http://www.tb.com/$1 permanent;
    }
    启动两个主机,一个做反向代理,一个做重定向

    方式二:
    server {
        listen       80;
        server_name   www.taob.com www.tb.com;
        location / {
    if ( $host != 'www.tb.com' ){
    rewrite ^/(.*)$ http://www.tb.com/$1 permanent;
    }
        proxy_pass http://127.0.0.1:8080/web/;
        }
    }
    这里使用了内置的$host变量比较主机名,作为判断是否重定向的条件

    注意,rewrite指令启动了重定向功能,需要终点掌握,其最后的参数 permanent 表示永久重定向。


    本地访问


    别名
    server{
    listen  80;
    server_name     www.tb.com;
    location / {
    root    /mysite/web/;
    }
    location /i {
    alias /mysite/web/images;
    }
    }
    注意,alias指令启动了别名的功能。
    此例中访问http://www.tb.com会指向/mysite/web/目录,而访问http://www.tb.com/i/hello.jpg会指向/mysite/web/images/hello.jpg文件。
    通常给子路径指定本地目录需要用到alias指令,也就是常说的起别名。我们通常在配置/目录时使用root指定路径,而配置/xxx子目录时使用alias指定路径。


    location的优先级


    location [ = | ~ | ~* | ^~ ] uri { ... }
    =:表示精确匹配
    ~:正则表达式匹配,区分大小写
    ~*:正则表达式匹配,不区分大小写
    ^~:URI前半部分匹配,可省略

    优先级顺序
    字符字面量精确匹配 -> 正则表达式匹配 -> 按字符字面量左侧开始匹配
    如果存在多个正则表达式同时匹配,优先选择最前面那个,如果存在URI前半部分多个匹配同时存在,优先选择最长前半部分那个匹配。
    举例
    location = / {
        [ configuration A ]
    }
    location / {
        [ configuration B ]
    }
    location /documents/ {
        [ configuration C ]
    }
    location ^~ /images/ {
        [ configuration D ]
    }
    location ~* .(gif|jpg|jpeg)$ {
        [ configuration E ]
    }
    讲解:
    /匹配A
    /index.html匹配B
    /documents/document.html匹配C
    /images/1.gif匹配D
    /documents/1.jpg匹配E


    权限

    这里列出了目录权限、IP访问权限,以及文件权限
    例一 允许172.16.0.0/24和192.168.68.0/24网段的用户访问,但是192.168.68.1和其他来源IP的用户是不允许的
    location / {
    root    /mysite/web/;
    deny 192.168.68.1;
    allow 172.16.0.0/24;
    allow 192.168.68.0/24;
    deny all;
    }
    这里重点以allow和deny指令为主

    例二 将网页以目录的形式展示
    location / {
    root   /mysite/web/;
        autoindex on;
    autoindex_exact_size on;
    autoindex_localtime on;
    }
    这里重点以autoindex指令为主

    例三 禁止访问/WEB-INF/目录
    location /WEB-INF/ {
    deny all;
    }

    例三 禁止访问资料文件
    location ~* .(txt|doc)$ {
    root   /mysite/web/;
    deny all;
    }


    与URL重写相关的命令


    if指令

    判断表达式1,正则类
    ~:如果匹配正则表达式,则条件为真
    ~*:如果匹配正则表达式且不区分大小写,则条件为真
    !~:如果不匹配正则表达式,则条件为真
    !~*:如果与不区分大小写的正则表达式不匹配,则条件为真
    判断表达式2,文件类
    -f和!-f:判断是否文件
    -d和!-d:判断是否目录
    -e和!-e:判断文件或目录是否存在
    -x和!-x:判断是否可执行

    跟if指令一起使用常见内置变量
    $limit_rate:用来限制连接的速度
    $request_method
    $host:请求头部中的Host
    $uri:请求的URI
    $request_uri:含有完整参数的初始URI
    $args:请求行中的参数
    $rquery_string:与$args相等
    $request_filename:请求的本地文件绝对路径,有URI与alias、root组成
    $document_root:对应当前请求的root指定路径
    $document_uri:相当于$uri5gg3

    $remote_addr:客户端的IP
    $remote_port
    $remote_user:用户名,由auth_basic认证
    $server_name:请求达到的服务器名
    $server_port

    例子
    server{
    listen  80;
    server_name     www.tb.com;
    location ~* .(jpg|jpeg|bmp|gif|css|js|html|htm)$ {
    root    /mysite/web/images/;
    if ( !-f $request_filename ) {
    root    /mysite/web/css/;
    }
    if ( !-f $request_filename ) {
    root    /mysite/web/js/;
    }
    if ( !-f $request_filename ) {
    root    /mysite/web/static/;
    }
    }
    location ~* .(txt)$ {
    root    /mysite/web/pages/ ;
    if ( !-f $request_filename ) {
    root /mysite/web/admin/ ;
    }
    # proxy_pass http://172.16.0.1:8080 ;
    }
    }
    使用if条件和root来查找匹配文件,在第一个location,如果在/mysite/web/images/找不到,则在/mysite/web/css/找,如果也没有,接着在/mysite/web/js/,如果仍旧没有,最后在/mysite/web/static/查找。在第二个location,要注意的是,proxy不能和root一起使用,两者只能存一。

    rewrite指令

    rewrite regex replacement [flag];
    flag标记有下面四个
    last
    break
    redirect
    permanent
    其中,last和break,它们与URL重写有关,也就是说客户端看不到地址发生变化,前者表示后面继续搜索URL或location,而后者表示后面不再匹配。
    而redirect和permanent,它们与URL重定向有关,也就是客户端能看到地址变化,前者表示临时重定向,后者表示永久重定向。

    例子一:访问http://www.tb.com/best/test.html,重写为http://www.tb.com/test/test.html
    location /best {
    rewrite /best/(.*) /test/$1 break;
    proxy_pass http://127.0.0.1:8080/test/;
    }
    这个例子先重写RUI然后转发出去
    下面是更有代表意义的URI重写例子
    rewrite ^/users/(.*)$ /show?user=$1? last;

    set指令
    用来设置一个变量

    location / {
    proxy_pass http://127.0.0.1:8080/;
    set $query $query_string;
    rewrite /wp     /wordpress/?$query?;
    }
    这个例子将/wp/?p=abc重写为/wordpress/?p=abc,利用到了自定义变量,这里要注意一点是rewrite指令的第二个问号表示查询字符串的结束。


    5.做WEB缓存服务器


    安装插件

    缓存插件默认已安装,另外要单独安装清除缓存的插件proxy_cache_purge,见前面的安装过程

    配置:

    在HTTP段加入两个定义
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_one:512m inactive=1d max_size=3g;
    proxy_temp_path /var/cache/nginx/proxy_temp;
    proxy_cache_path表示缓存的目录,levels表示用两层目录结构--第一次单字符目录名而第二层双字符目录名,keys_zone表示缓存对象键的区域名以及分配的内存大小,inactive表示缓存时间d、h、m表示日、时、分,max_file表示内存满后写入磁盘缓存的最大大小
    proxy_temp_path表示临时缓存的目录,它需要跟proxy_cache_path在同一分区

    server段的完整定义如下:
    server {
    listen              80;
    server_name         www.tb.com;
    charset UIF-8;
    location / {
    proxy_cache cache_one;
    proxy_cache_valid 200 304 12h;
    proxy_cache_key $host$uri$is_args$args;

    proxy_set_header Host $Host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_pass http://127.0.0.1:8080;
    expires 1d;
    }

    location ~ /purge(/.*) {
    allow 127.0.0.1;
    allow 172.16.0.0/24;
    deny all;
    proxy_cache_purge cache_one $host$1$is_args$args;
    }

    location ~ .*.(jsp|php|jspx)$ {
    proxy_set_header Host $Host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_pass http://127.0.0.1:8080;
    }

    access_log off;
    }
    proxy_cache:表示当前location所使用的缓存区域
    proxy_cache_valid:对哪些状态的页面缓存多久,例如对200和304缓存12小时
    proxy_cache_key:缓存的对象名字是什么组合
    proxy_cache_purge:对哪个缓存区域的缓存对象做清除

    测试:

    启动nginx会看到多了一个cache manager process进程,说明缓存已启动。
    访问http://www.tb.com/cache/test.html,修改test.html后再访问,仍能看到修改前的内容则表示缓存有效,清楚缓存用地址http://www.tb.com/purge/cache/test.html,在原来地址的主机名后加多一层目录purge表示做清除缓存操作,补充一下,这个清除操作支持通配符

    利用TCMalloc优化Nginx性能


    TCMalloc是谷歌的google-perftools中的成员,比glibc的malloc在内存分配效率方面高很多,能提升服务器在并发时的性能,安装TCMalloc需要安装libunwind和google-perftools两个包,前者提供基本函数调用链和函数调用寄存器

    安装libunwind和google-perftools
    见前面的编译安装章节

    创建线程目录
    mkdir /tmp/tcmalloc
    chown nginx:nginx /tmp/tcmalloc
    chmod 0777 /tmp/tcmalloc

    修改配置
    在main区域的pid下添加一行
    google_perftools_profiles /tmp/tcmalloc;

    查看运行结果
    重启ngins
    [root@node5 sbin]# ps aux | grep nginx
    root     63937  0.0  0.1 581572  1344 ?        Ss   23:42   0:00 nginx: master process ./nginx
    nginx    63938  0.1  3.0 612364 30372 ?        S    23:42   0:00 nginx: worker process
    nginx    63939  0.1  3.1 612364 32000 ?        S    23:42   0:00 nginx: worker process
    nginx    63940  0.0  3.0 612364 30372 ?        S    23:42   0:00 nginx: worker process
    nginx    63941  0.1  3.0 612364 30372 ?        S    23:42   0:00 nginx: worker process
    nginx    63942  0.0  0.3 585924  3976 ?        S    23:42   0:00 nginx: cache manager process
    root     63951  0.0  0.0 103256   844 pts/3    S+   23:43   0:00 grep nginx
    [root@node5 sbin]# lsof -n | grep tcmalloc
    nginx     63938   nginx   12w      REG              253,0        0    1048645 /tmp/tcmalloc.63938
    nginx     63939   nginx   14w      REG              253,0        0    1048643 /tmp/tcmalloc.63939
    nginx     63940   nginx   16w      REG              253,0        0    1048635 /tmp/tcmalloc.63940
    nginx     63941   nginx   18w      REG              253,0        0    1048646 /tmp/tcmalloc.63941
    nginx     63942   nginx   18w      REG              253,0        0    1048632 /tmp/tcmalloc.63942
    启动tcmalloc,每个tcmalloc线程跟一个nginx工作进程关联一起,例如 63938 与 /tmp/tcmalloc.63938






  • 相关阅读:
    Javascript 多浏览器兼容性问题及解决方案
    Vue-学习。
    angular-动画。
    Angular-学习。
    JQuery-学习。
    Bootstrap框架。
    Swiper-轮播图。
    jquery validation表单验证插件2。
    jquery validation表单验证插件。
    Grunt-学习。
  • 原文地址:https://www.cnblogs.com/tsw1107/p/3f1d6928c0b0a117fee286e517c41c2a.html
Copyright © 2020-2023  润新知