 
                                
聊聊 nginx 的那些事
Nginx 目录介绍
- conf: 配置文件
- html: 网页文件
- logs: 日志文件
- sbin: 主要二进制程序
启动Nginx
- 
命令: cd /path/nginx
- 
启动: ./sbin/nginx- 启动时有时会报错:80端口被占用。
- 解决方法是,找到占用80端口的程序,并杀掉进程。
- natstat -antp: 查看端口信息
 
- 
如果没有发现有程序占用80端口,并且nginx启动还是报错的话,有可能是 nginx 试图同时监听 ipv4 和 ipv6 的 80 端口导致的; 解决方法: server { listen 80; listen [::]:80 ipv6only=on; }或 server { listen [::]:80; }
Nginx 常用命令
- nginx -t: 检测配置文件是否正确,如果出错会报错误信息;
- nginx -s reload: 加载最新配置
- nginx -s stop: 立即停止
- nginx -s quit: 优雅停止
- nginx -s reopen: 重新打开配置文件
Nginx 配置段详解
# 全局区
# 有1个工作的子进程,可以自行修改,不需要太大,会消耗CPU资源,    
# 一般设置为 CPU数*核数
worker_processes 1; 
Events {
# 一般是配置nginx连接的特性
# 如1个worker能同时允许多少连接
 worker_connections  1024; # 这是指 一个子进程最大允许连1024个连接
}
http {  #这是配置http服务器的主要段
     Server1 { # 这是虚拟主机段
            Location {  #定位,把特殊的路径或文件再次定位 ,如image目录单独处理
                ...
            }           # 如.php单独处理
     }
     Server2 {
        ...
     }
}Nginx 配置虚拟主机
- 基于域名的虚拟主机
    server {
        listen 80;  #监听端口
        server_name a.com; #监听域名,如有多个,空格隔开
        location / {
                root /var/www/a.com;   #根目录定位
                index index.html; #默认索引页
        }
    }- 基于端口的虚拟域名
 server {
        listen 8080;
        server_name a.com;
        location / {
                root /var/www/html8080;
                index index.html;
        }
    }Nginx 日志管理
- 观察 server段,可以看到如下的信息
   access_log  logs/access.log  main;- 
说明 nginx 的请求日志保存在 logs/access.log中,日志的保存格式是:main;
- 
什么是 main格式?还有什么其他格式呢?
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';- 还可以自定义格式
log_format  mylog  '$remote_addr [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent"';
server {
        listen 80;
        #下面声明a.com使用mylog格式日志,并保存在logs/a.com.log文件中
        access_log logs/a.com.log mylog;
        server_name a.com www.a.com;
 ....
}  
main格式是自定义好的日志记录格式,自定义名称,便于引用; 以上示例中,main格式中记录的信息有$remote_addr ....http_x_forwarded_for等信息。
- 日志格式 是指记录哪些选项
默认的日志格式: main
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';如默认的
main日志格式,记录这么几项远程IP- 远程用户/用户时间请求方法(如GET/POST)请求体body长度referer来源信息http-user-agent用户代理/蜘蛛,被转发的请求的原始IPhttp_x_forwarded_for: 在经过代理时,代理把你的本来IP加在此头信息中,传输你的原始IP
小应用
shell+ 定时任务 +nginx信号管理,完成日志按日期存储
- 分析思路: 凌晨00:00:01,把昨天的日志重命名,放在相应的目录下 再USR1信息号控制nginx重新生成新的日志文件
#!/bin/bash
base_path='/usr/local/nginx/logs'
log_path=$(date -d yesterday +"%Y%m")
day=$(date -d yesterday +"%d")
mkdir -p $base_path/$log_path
mv $base_path/access.log $base_path/$log_path/access_$day.log
#echo $base_path/$log_path/access_$day.log
/usr/local/nginx/sbin/nginx -s reopen- 定时任务
# Crontab 编辑定时任务
01 00 * * * /xxx/path/b.sh  # 每天0时1分(建议在02-04点之间,系统负载小)Nginx 和 PHP
- 通信原理:
apache一般是把php 当做自己的一个
模块来启动的. 而nginx则是把http请求变量(如get,user_agent等)转发给 php 进程,即 php 独立进程,与 nginx 进行通信. 称为fastcgi运行方式. 因此,为 apache所编译的php,是不能用于nginx的.
- nginx 和 PHP的配置
把请求信息转发到9000端口里的PHP进程,让PHP进程处理,指定目录下的php文件。
# 碰到以 `php` 结尾的文件(碰到php文件)
location ~ \.php$ {
    # 把根目录定位到 html
    root html;
    # 把请求上下文转交给9000端口PHP进程
    fastcgi_pass   127.0.0.1:9000;
    # 并告诉PHP进程,当前的脚本是 
    fastcgi_index  index.php;
    # $document_root$fastcgi_scriptname PHP会去找这个脚本并处理,这个脚本的位置不能错误
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}Nginx 与 Rewrite 规则
- rewrite语法
Rewrite正则表达式 定向后的位置 模式
# 原理
# goods-3.html ---->goods.php?goods_id=3
# goods-([\d]+)\.html ---> goods.php?goods_id = $1  
location / {
    index index.php;
    rewrite goods-([\d]+)\.html$ /shop/goods.php?id=$1;
}
注意:用url重写时, 正则里如果有 {} ,正则要用双引号包起来
pathinfo 支持
# 典型配置
location ~ \.php$ {
    root           html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $DOCUMENT_ROOT$fastcgi_script_name;
    include        fastcgi_params;
}- 第一种修改方式
# 修改第1,5,6行,支持pathinfo
location ~ \.php(.*) { # 正则匹配.php前后的script_name和pathinfo部分
    root html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $DOCUMENT_ROOT$fastcgi_script_name;
    fastcgi_param PATH_INFO $1; # 把pathinfo部分赋给PATH_INFO变量
    include        fastcgi_params;
}- 可以通过rewrite方式代替php中的PATH_INFO
#实例:thinkphp的pathinfo解决方案
#设置URL_MODEL=2
location / {
    if (!-e $request_filename){
        rewrite ^/(.*)$ /index.php?s=/$1 last;
    }
}- nginx配置文件中设置PATH_INFO值
请求的网址是
/abc/index.php/abc
PATH_INFO的值是/abcSCRIPT_FILENAME的值是$doucment_root/abc/index.phpSCRIPT_NAME/abc/index.php
- nginx 可以使用 fastcgi_split_path_info指令来设置PATH_INFO,在 location 段添加如下配置。
location ~ ^.+.php {
  (...)
  fastcgi_split_path_info ^((?U).+.php)(/?.+)$;
  fastcgi_param SCRIPT_FILENAME /path/to/php$fastcgi_script_name;
  fastcgi_param PATH_INFO $fastcgi_path_info;
  fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
  (...)
}- 
try_files : 配置laravel 项目时需要使用改配置; - 
try_files指令也放在server或location上下文中。
- 
try_files指令的参数是一个或多个文件或目录的列表,以及最后面的 URI 参数。
- 
Nginx会按顺序检查文件及目录是否存在(根据 root 和 alias 指令设置的参数构造完整的文件路径),并用找到的第一个文件提供服务。在元素名后面添加斜杠/表示这个是目录。如果文件和目录都不存在,Nginx会执行内部重定向,跳转到命令的最后一个uri参数定义的URI中。
- 
要想 try_files指令工作,必须定义一个location块捕捉内部重定向。最后一个参数可以是命名过的location,由初始符号(@)指示。
- 
try_files指令通常使用$uri变量,表示URL中域名之后的部分。
 
- 
location /images/ {
    try_files $uri $uri/ /images/default.gif;
}
location = /images/default.gif {
    expires 30s;
}Nginx 动静分离和反向代理
- 
动静分离 - 用nginx 做反向代理使用 poxy_pass
- 以反向代理为例,nginx 不自己处理一些图片资源,而是把图片的请求转发给另一台机器进行处理
 
- 用nginx 做反向代理使用 
location ~ \.(jpg|jpeg|png|gif)$ {
        proxy_pass HTTP://IP:port;
}- 可以通过代理服务器使用设置头信息字段,把用户真正的IPIP传到后台服务器去.
location ~ \.(jpg|jpeg|png|gif)$ {
        proxy_set_header X-Forwarded-For $remote_addr;
        
        proxy_pass HTTP://IP:port;
}反向代理+负载均衡
- 在nginx中做集群与负载均衡,步骤都是一样的
Upstream {}模块 把多台服务器加入到一个组, 然后memcached_pass,fastcgi_pass,proxy_pass ==> upstream组
具体配置步骤:
- 1:配置 upstream
# 创建一个负载均衡组
upstream imageserver {
    server 192.168.1.204:8080 weight=1 max_fails=2 fail_timeout=30s;
    server 192.168.1.204:8081 weight=1 max_fails=2 fail_timeout=30s;
}- 2: 下游调用
location ~ \.(jpg|jpeg|png|gif)$ {
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        # 在这里使用创建的负载均衡组
        proxy_pass http://imageserver;
} 
                                                                                     
                                                                                    