实战nginx笔记

作者: hopevow | 来源:发表于2016-09-28 09:57 被阅读694次

    使用理由

    配置文件简单
    支持Rewrite重写规则
    内置健康检查功能
    节省带宽
    稳定性高
    支持热部署```
    ![Paste_Image.png](http:https://img.haomeiwen.com/i3079704/6b2ce4b4b940b7d7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    >平滑重启
    
    ``` kill -HUP \`/usr/local/nginx/logs/nginx.pid\` ```
    
    当Nginx接收到hup信号时,它会尝试先解析配置文件,如果 成功就应用新的配置谁的,之后,Nginx运行新的工作进程并从容关闭旧的工作进程 ,通知工作进程 关闭监听大套接字,但是继续为新的客户提供服务 ,所有客户端的服务完成后旧的工作进程 被关闭。如果 新的配置文件应用失败,Nginx继续使用旧的配置进行工作。
    
    >Nginx支持以下几种信号
    
    - TERM, INT 快速关闭;
    - QUIT 从容关闭;
    -  HUP 一滑重启,重新加载配置文件;
    - USR1 重新的打开日志文件,在切割日志时用途较大;
    - USR2 平滑升级可执行程序 ;
    - WINCH  从容关闭工作进程。
    
    >nginx配置
    
    ```#使用的用户和组
    user www www;
    #指定工作衍生进程数(一般等于CUP的总或总的两倍,例如两个 四核CUP,则总核数为8)
    worker_processes 8;
    #指定错误日志存放的路径,错误日志记录级别可选项为:【debug | info | notice | warn | error | crit 】
    error_log /data1/logs/nginx_error.log crit;
    #指定PID存放的路径
    pid /usr/local/nginx/nginx.pid;
    #指定文件描述符数量 
    worker_rlimit_nofile 51200;
    
    events {
     #使用的网络I/O模型,Linux系统推荐采用epoll模型,FreeBSD系统采用kqueue模型
    use epoll;
    #允许的连接数
    worker_connections 51200;
    }
    
    http {
    include mime types;
    default_type application/octet-stream;
    #设置使用的字符集,如果 一个网站 有多种字符集,请不要随便设置,就让程序 员在html代码中通过meta标签设置
    #charset gb2312;
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    #设置客户端能够上传文件的大小
    client_max_body_size 8m;
    sendfile on;
    tcp_nopush on;
    keepalive_timeout 60;
    tcp_nodelay on;
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fasgcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    #开启gzip压缩
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 2;
    gzip_types text/plain application/x-javascript text/css application/xml;
    gzip_vary on;
    #limit_zone crawler $binary_remote_addr 10m;
    server {
    #监听的IP和端口
     listen 80;
    #主机名称
     server_name www.yourdomain.com yourdomain.com;
    #默认首页文件,顺序从左到右,如果 找不到index.html文件,则查找 index.htm文件作为首页文件
    index index.html index.htm index.php;
    root /data0/htdocs;
    #limit_conn crawler 20;
    location ~  .*\.(gif|jpg|jpeg|png|bmp|swf)${
     expires 30d;
    } 
    location ~ .*\.(js|css)?${
     expires 1h;
    }
    
    log_format access '$remote_addr - $remote_user [$time_local] "$request" ' ' $status $body_bytes_sent "$http_referer" ' '$http_user_agent" $http_x_forwarded_for';
    access_log /data1/logs/access.log access;
    }
    }
    

    虚拟主机

    虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的Internet服务器功能(www、FTP、Email等),同一台主机上的虚拟主机之间是完全独立的。从网站访问者来看,每一台虚拟主机和一台独立的主机完全一样。

    利用虚拟主机,不用为每个要运行的网站 提供一台单独的Nginx服务 器或单独运行一级nginx进程 。虚拟主机提供了在同一台服务器、同一级Nginx进程 上运行多个网站 的功能。

    跟apache一样,Nginx也可以配置多种类型的虚拟主机;一是基于ip的虚拟主机,二是基于域名的虚拟主机,三是基于端口的虚拟主机。

    一段server{......}就是一个虚拟该机,如果要配置多个虚拟主机,建立多段server{}配置即可,非常方便,监听的IP商品也可以不写IP地址,只写端口,把它配置成“listen 80",则表示监听 该服务器所有IP的80端口,可通过 server_name区分不同的虚拟主机。

    反向代理后客户端IP问题

    由于在客户端和web服务器之间增加了蹭层,因此 web服务器无法直接拿到客户端的IP,通过 $remote_addr变量拿到的是反向代理服务器的ip地址,但是,反射代理服务器在转发请求的HTTP头信息中,可以增加X-Forwarded-For信息,用以记录原有的客户端IP地址和原来客户端请求的服务器地址

    日志切割

    #!/bin/bash
    logs_path = "/data1/logs/"
    mkdir -p ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%m")/
    mv ${logs_path}access.log ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%m")/access_$(date -d "yesterday" + "%Y%m%d").log
    kill -USR1 `cat /usr/local/nginx/nginx.pid`
    

    配置crontab每天凌晨00:00定时执行这个脚本:
    crontab -e

    Nginx的压缩输出配置

    gizp(GNU-ZIP)是一种压缩技术。经过gzip压缩后页面的大小可以变为原来的30%甚至更小。这样,用户浏览页面时候会快很多。gzip的压缩页面需要浏览器和服务器双方都支持,实际上就是服务器端压缩,浏览器端解压并解析。大多数浏览器都支持解析gzip过的页面。
    配置在http{}段中:

    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 2;
    gzip_types text/palin application/x-javascript text/css application/xml;
    gzip_vary on;
    

    自动目录配置

    前提:当前目录下不存在index指令设置的默认首页文件。

    location / {
      autoindex on;
    }
    相关指令
    #设定索引时文件大小的单位【B、KB、GB】
    autoindex_exact_xize [on|off]
    #开户本地时间来显示 文件时间的功能。默认为关(GMT时间)
    

    Nginx的浏览器本地缓存设置(Browser Cacging)

    浏览器缓存是为了加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示 文档,这样就可以加速页面的浏览。缓存 的方式节约了网络的资源,提高网络的效率。

    fastcgi

    FastCG是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能,众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCGI进程 管理器调度,则可以提供良好的性能,伸缩性、Fail-Over特性等。

    fastcgi 原理和优点

    Paste_Image.png

    mysql管理shell脚本

    vi /data0/mysql/3306/mysql

    #!/bin/sh
    mysql_port=3306
    mysql_username="admin"
    mysql_password="123456"
    
    function_start_mysql() {
          printf "starting mysql...\n"
          /bin/sh/usr/local/mysql/bin/mysqld_safe --defaults-file=/data0/mysql/${mysql_port}/my.cnf 2>&1>/dev/null &
    }
    
    function_stop_mysql() {
          printf "stoping mysql...\n"
          /usr/local/mysql/bin/mysqladmin -u ${mysql_username} -p ${mysql_password} -S /tmp/mysql.sock shutdown
    }
    
    function_restart_mysql(){
          printf "restarting mysql...\n"
          function_stop_mysql
          sleep 5
          function_start_mysql
    }
    
    function_kill_mysql(){
           kill -9 $(ps -ef | grep 'bin/mysqld_safe' | grep ${mysql_port} | awk '{printf $2}')
            kill -9 $(ps -ef | grep 'libexec/mysqld' | grep ${mysql_port} | awk '{printf $2}')
    }
    
    if [ "$1" = "start"]; then
          function_start_mysql
    elif [ "$1" = "stop" ]; then
          function_stop_mysql
    elif ["$1" = "restart" ]; then
          function_restart_mysql
    elif [ "$1" = "kill" ]; then
           function_kill_mysql
    else
           printf "Usage:/data0/mysql/${mysql_prot}/mysql {start|stop|restart|kill}\n"
    fi
    

    chmod +x /data0/mysql/3306/mysql

    启动mysql:

    /data0/mysql/3306/mysql start

    /usr/local/mysql/bin/mysql -u -root -p -S /tmp/mysql.sock

    创建一个具有root权限的用户和密码

    GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' IDENTIFIED BY '123456';
    GRANT ALL PRIVILEGES ON *.* TO 'admin'@'127.0.01' IDENTIFIED BY '123456';
    

    为什么使用负载 均衡

    随着网站 访问量的快速增长,单台服务器已经无法承担大量用户的并发访问,必须采用多台服务器协同工作,以提高计算机系统的处理能力和计算强度,满足当前业务量的需求。而如何 在完成同样功能的多个网络设备之间实现合理的业务量分配,使之不会出现一台设备过忙,而其它设备却没有充分使用的情况。要解决这一问题,可以采用负载 均衡的方法

    负载均衡

    负载均衡是由多台服务器以对称的方式组成 一个服务器集合,每台服务器具有等价的地位,都可以单独对提供服务而无须其他服务器的辅助。通过某种负载分担技术,将外部送来请求均匀分配到对称的某一台服务器上,而接收到请求的服务器独立 地回应客户的请求。均衡负载 能够平均分配 客户请求到服务器阵列,藉此快速获取重要数据,解决大量并发访问服务问题。这种集群技术可以用最少 的投资获得接近于大型主机的性能 。

    反向代理

    反向代理是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。


    Paste_Image.png

    负载均衡实现方式

    • 用户手动选择
    • DNS轮询方式(可靠性低,负载分配 不均衡)
    Nginx反向代理负载均衡动静分离系统架构图

    upstream 中的ip_hash

    会使相同的用户访问后端同一个服务器
    但是会影响负载均衡

    如果后端有时候要从Nginx负载均衡(已使用ip_hash)中摘除一段时间,你必须将其标记为"down",而不是直接从配置文件中删掉或注释掉该后端服务器信息

    upstream bakcend{
            ip_hash;
            server backend1.example.com;
            server backend2.example.com;
            server bakcend3.example.com down;
            server backend4.example.com;
    }
    

    rewrite规则的用处

    通过Rewrite规则,可以实现规范的URL,根据变量来做URL转向及选择配置。例如,一些使用MVC框架的程序只有一个入口,可以通过 Rewrite来实现 ,一些动态URL地址需要伪装成静态HTML,全球搜索引擎攫取,也需要Rwrite来处理,一些由于目录结构、域名变化的旧URL需要跳转到新的URL上,也可以通过 Rwrite来处理

    if 中的条件


    if 中的条件

    rewrite

    该指令根据表达试来重定向URI,或者修改字符串,指令根据配置文件中的顺序来执行。重写表达式只对相对路径有效,如果你想配对主机名,需要使用if语句:

    if ($host ~* www\.(.*)) {
      set $host_without_www $1;
      rewrite ^(.*)$ http://$host_without_www$1 permanent;
    }
    

    如果字符串以http://开头,将会采用301或302跳转进行URL重定向。

    rewrite指命的flag

    rewrite指命的flag

    last 和break 标记的实现功能类似 ,但二者之间有细微的差别,使用alias指令时必须用last标记,使用proxy_pass指令时要使用break标记,lat标记在本条rewrite规则执行完毕后,终止匹配,不再匹配后面的规则。
    一般在根location中(即location / {})或直接在server标签中编写rewrite规则,推荐使用last标记,在非根location中 (例如location /cms/ {}),则使用break标记。

    如果被替换的URI中含有参数(妈类似/app/test.php?id=5之类的URI),默认情况下参数 会被自动加到替换串上,可以在末尾加上?来解决这个问题。如
    rewrite ^/users/(.*)$ /show?user=$1? last;

    对花括号来说,它们既能用在重定向的正规表达式里,也能用在配置文件里分割代码块,为了避免冲突,正则表达式里如果 带花括号,应该用双引号或单引号包围如:/photos/123456 => /path/to/photos/12/1234/123456.png

    rewrite "/photos/([0-9]{2})([0-9]{2})([0-9]{2})" /path/to/photos/$1/$1$2/$1$2$3.png;

    Nginx的Rwrite规则编写实例

    if (!-e $request_filename) {
         rewrite ^/(.*)$ /index.php last;
    }
    多目录转成参数 abc.domain.com/sort/2 => abc.domain.com/index.php?act=sort&name=abc&id=2;
    
    if ($host ~* (.*)\.domain\.com) {
        set $sub_name $1;
        rewrite ^/sort\/(\d)\/?$ /index.php?act=sort&name=$sub_name&id=$1 last;
    }
    
    目录对换/123456/xxxx => /xxxx?id=1234565:
    rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
    如果 客户端 使用IE浏览器,则重定向到/nginx-ie目录下
    
    if ($http_user_agent ~ MSIE) {
        rewrite ^(.*)$ /nginx-ie/$1 break;
    }
    
    禁止访问多个目录:
    location ~ ^/(cron|templates)/ {
          deny all;
          break;
    }
    
    禁止访问以/data/开头的文件:
    location ~ ^/data {
            deny all;
    }
    
    设置某些类型文件的浏览器缓存时间:
    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
            expires 30d;
    }
    location ~ .*\.(js|css)$ {
            expires 1h;
    }
    
    将多级目录下的文件转换成一个文件/job-123-456-789.html 指向/job/123/456/789.html
    rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$  /job/$1/$2/jobshow_$3.html last;
    
    禁止访问以.sh、.flv、.mp4为文件后缀的URL地址:
    location ~ .*\.(sh|flv|mp4)?$ {
            return 403;
    }
    
    适用于Zend Framework重写规则:
    if ($request_uri ~* "^/pay(.*)") {
            set $var_pay_public '1';
    }
    
    if ($request_uri ~* "."\.(js|ico|gif|jpg|png|css)$") {
            set $var_pay_public '0';
    }
    
    if ($request_pay_public ~ '1') {
            rewirte ^(.*)$  /pay/index.php last;
    }
    
    
    Bo-blog开源PHP博客系统伪静态重写规则
    if (! -x $request_filename) {
            rewrite ^/post/([0-9]+)/?([0-9+])/?([0-9]?/?$) /read.php/entryid=$1&page=$2&part=$3 last
    rewrite ^/page/([0-9]+)/([0-9]+)?/?$ /index.php?mode=$1&page=$2 last;
    rewrite ^/started/([0-9]+)/?([0-9]+)?/?$  /star.php?mode=$1&page=$2 last;
    rewrite ^/category/([^/]+)/?([0-9]+)?/?([0-9]+)?/?$  /index.php?go=category_$1&mode=$2&page=$3 last
    rewrite ^/archiver/([0-9]+)/([0-9]+)/?([0-9]+)?/?([0-9]+)?/?$  /index.php?go=archive&cm=$1&cy=$2&mode=$3&page=$4 last;
    rewrite ^/date/([0-9]+)/([0-9]+)/([0-9]+)/?([0-9]+)?([0-9]+)?/?([0-9]+)?/?$  /index.php?go=showday_$1-$2-$3&mode=$4&page=$5 last;
    rewrite ^/user/([0-9]+)/?$ /view.php?go=user_$1 last;
    rewrite ^/tags/([^/]+)/?([0-9]+)?/?([0-9]+)?/?$  /tag.php?tag=$1&mode=$2&page=$3 last;
    rewrite ^/compnent/id/([0-9]+)/?$  /page.php?pageid=$1 last;
    rewrite ^/component/([^/]+)/?$  /page.php?pagealias=$1 last;
    rewrite  ^/read\.php/([0-9]+)/([0-9]+)\.htm$  http://$host/post/$1/ permanent;
    rewrite  ^/post/([0-9]+)\_([0-9]+)\.htm$  http://$host/post/$1/$2/ permanent;
    rewrite  ^/post/([0-9]+)\_([0-9]+)\_([0-9])\.htm$  http://$host/post/$1/$2/$3/ permanent;
    rewrite  ^/index\_([0-9]+)\_([0-9]+)\.htm$  http://$host/page/$1/$2/ permanent;
    rewrite ^/star\_([0-9]+)\_([0-9]+)\.htm$  http://$host/starred/$1/$2/ permanent;
    rewrite  ^/category\_([0-9]+)\.htm$  http://$host/category/$1/  permanent;
    rewrite ^/category\_([0-9]+)\_([0-9]+)\.htm$  http://$host/category/$1/$2/$3/   permanent;
    rewrite  ^archive\_([0-9]+)\_([0-9]+)\.htm$  http://$host/archiver/$1/$2/ permanent;
    rewrite  ^/archive\_([0-9]+)\_([0-9]+)\_([0-9]+)\_([0-9]+)\.htm$  http://$host/archiver/$1/$2/$3/$4/ permanent;
    rewrite  ^/showday\_([0-9]+)\_([0-9]+)\_([0-9]+)\.htm$   http://$host/date/$1/$2/$3/ permanent;
    rewrite ^/showday\_([0-9]+)\_([0-9]+)\_([0-9]+)\_([0-9]+)\_([0-9])\.htm  http://$host/date/$1/$2/$3/$4/$5 permanent;
    }
    rewrite ^/([a-zA-Z0-9_-]+)/?([0-9]+)?/?$  /read.php?biogalias=$1&page=$2&part=$3 last;
    

    根据referer信息防盗链

    location ~* \.(gif|jpg|jpeg|png|swf|flv)$ {
            valid_referers none blocked www.youdomain.com *.youdomain.com;
            if ($invalid_referer) {
                   rewrite ^/(.*)  http://www.yourdomain.com/blocked.html;
             }
    }
    

    Nginx与Apache的Rewrite规则

    Apache:

    RewriteRule ^/(mianshi|xianjing)/$  /z1/index.php?name=$1 [L]
    

    Apache的RewriteRule指令换成Ngnix的rewrite指令,Apache的[L]标记换成 Nginx的last标记,中间的内容不变。

    Nginx与apache的各种区别

    区别详解

    nginx模块

    要编写一个Nginx模块,你要熟悉Nginx的配置文件。Nginx配置文件主要分成4部分:main(全局配置)、server(虚拟主机配置)、upstream(主要为反向代理、负载均衡相关配置)和location(目录匹配配置),每部分包含若干个指令。main部分的指令将影响其他所有部分;server部分的指令主要用于指定虚拟主机域名、IP端口;upstream的指令用于设置反向代理及后端服务器的负载均衡;location部分用于匹配网页位置(例如,根目录“/"、"/images",等等)。location部分会继承server部分的指令,而server会继承main部分的指令:upstream既不会继承指令也不会影响其他 部分。它有自己的特殊指令,不需要在其他地方应用。

    Nginx的模块不能够像Apache那样动态添加,所有的模块要预先编译进Nginx二进制可执行文件中。

    Nginx模块的三种角色

    • Handlers(处理模块) 用于处理HTTP请求并输出内容
    • Filters(过滤模块) 用于过滤Handler输出的内容
    • Load-balancers (负载均衡模块)当有多于一台的后端服务器供选择时,选择一台后端服务器并将HTTP请求转发到该服务器。

    Nginx模块的处理流程

    客户端改善HTTP请求到Nginx服务器->Nginx基于配置文件中的位置选择一个合适的处理模块->负载均衡模块选择一台后端服务器(反向代理情况下)->处理模块进行处理并把输出缓冲放到第一个过滤模块上->第一个过滤模块处理后输出 给第二个过滤模块->第n个过滤模块->最后把处理结果发送给客户端 。


    模块相当于钩子

    相关文章

      网友评论

        本文标题:实战nginx笔记

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