0%

nginx

文章字数:2100,阅读全文大约需要8分钟

基础概念

  • nginxmaxterworker线程组成,master接受外部信号,并发送给各个worker线程。监控worker线程的状态,重启异常结束的worker

基本命令

  • ./nginx -s stop停止
  • ./nginx -s quit退出
  • ./nginx -s reload重新加载nginx.conf

配置

  • 结构
1
2
3
4
5
6
main //全局设置
-event // nginx工作模式和连接数上限
-http // 服务器相关属性
-server // 虚拟主机设置
-upstream // 上有服务器设置,主要是反向代理、负载均衡相关
-location // url匹配特定位置后的设置
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
#user www; //work进程的用户权限
worker_processes 1;// 启用一个worker进程,一般和cpu数量一致

#error_log logs/error.log notice; // 日志级别 常用: debug notice warn error crit

events { // 主要配置工作模式和连接数
use epoll; // 默认就是这个,一般不用配置
worker_connections 1024;// 线程都文件限制,不配会默认使用linux的默认值
}

http {
include mine.types; // 引入mine.types这个文件
#log_format main ·remote_addr - $remote_user... // 定义访问日志格式(下面由表格)
# access_log logs/access.log main;// 访问日志及格式,main就是上面定义的那个
sendfile on;// 启用高效文件下载
#tcp_nopush on;// 高效下载使用tcp_nopush

#keepalive_timeout 65;

#gzip on;//开启压缩支持

upstream nginx { // 申明一个负载
# ip_hash;
server 192.168.1.1:8098 weight=2; // 权重为2的负载
server 192.168.1.2:8098 weight=1; // 权重为1的负载
}

server { // 虚拟主机
listen 80;// 监听端口
server_name localhost;// 主机名(域名访问时匹配)
...
location / {// 匹配url
root html; // 根目录路径,即最终取的文件是html/location的url
index index.html index.htm;// 等url以/结尾时,取那个文件。不以/结尾则是location指定的
# root路径+location路径,root代表读取文件的根目录名(nginx目录下的)再加上url后面指定的路径,读取具体文件
# alias html; // 当location =/xxx 时,因为url后面的第一个已经指定了(即location的值),所以root不能指定具体的根目录,此时就能用alias。
# 例如 url: 127.0.0.1/zzz/a.html,设置 alias html;就会读取 html/a.html
# return 500; // 可以直接返回错误
# set $a 32; // 设置变量 nginx 先执行rewrite(定义)相关指令,再执行access(执行),最后是content(读文件)相关命令,所以多次set变量,echo时只会取最后一次的值,不是按照书写顺序执行的。
# echo $a;// 输出a的值到http res
# proxy_pass http://xxx.xxx.xxx/aaa/yyy/ //反向代理,末尾有 / 的情况下将 location匹配的字符之后的内容补充到 yyy/ 后面,没有 / 的情况补充location匹配的字符及后面的字符到 yyy/之后
# proxy_pass http://nginx; // 使用负载
# rewrite ^/ a.html break/replacement // 匹配正则“^/”指定的路径,转发(break,服务器内部转发)或重定向(replacement,url切换)
}



error_page 500 502 503 504 /50x.html // 配置错误页面
location = /50x.html {
root html;
}
}
}
名称 含义
$remote_addr 客户端ip
$remote_user 远程客户端的用户名(一般是‘-’)
$time_local 访问时间和时区
$request url及请求方法
$status 响应码
$body_bytes_sent 给客户的发送的文件主题内容字节数
$http_user_agent 用户使用的代理(一般是浏览器)
$http_x_forwarded_for 可以记录客户端ip
$http_referer 用户从那个链接过来的

url路由配置

优先级 表达式 说明
1 location =/ 精准匹配/
2 location /xxx 开头是/xxx,正常匹配(^~)
2 location ^~/static/ ^~ 正常匹配,以/static/ 开头
3 location ~ /a 正则匹配,严格匹配,区分大小写
3 location ~* /a 不区分大小写正则
  • 同级别会取最长值作为匹配结果
  • 精准匹配会直接返回结果,普通匹配结束后还会再进行正则匹配,如果正则有结果,会返回正则匹配到的结果,正则匹配会覆盖普通匹配。
  • 匹配多条则会进入最长的规则中

负载均衡

  1. 默认使用轮询,逐个转发到配置的服务器中,如果服务器挂了,能够自动剔除
  2. weight,指定轮询记录,和被访问几率成正比
  3. ip_hash 每个请求按访问的ip结果分配,这样每个访客固定再一个服务器上,解决session问题

运作原理

  • url: 域名+端口(port)+路径(path)+参数(param)
  1. 匹配server虚拟主机
  2. 匹配location,根据path从前往后匹配。根据匹配结果分为 匹配到的path1剩余path2
  3. 代理转发
  • root转,整个path1+path2
  • alias只转path2
  • proxy_pass,如果port后面有/则只传path2,没有/则传path1 + path2
  • response根据传过来的信息,生成内容,返回页面
  1. echo内容生成的命令,echo信息到response (需要echo-nginx-module第三方插件)

rewrite

  • rewrite regex replacement [flag]
  • regex正则,^/代表总是匹配
  • replacement替换值,新值
  • flag处理标志,可选
  1. break内部转发,替换新值,然后走后续的执行阶段
  2. last内部转发,用替换值重新走location,警惕死循环
  3. redirect 301重定向
  4. permanent 302重定向
  5. 没有flag的时候最后一个rewrite会覆盖之前的,有flag则第一个生效

location

  • nginx配置location [=|~|~*|^~] /uri/ { … }用法
  1. = 严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。
  2. ~ 为区分大小写匹配(可用正则表达式)
  3. !~为区分大小写不匹配
  4. ~* 为不区分大小写匹配(可用正则表达式)
  5. !~*为不区分大小写不匹配
  6. ^~ 如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式。

if判断

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
server{

listen 80;
server_name xxx.xx.com;

# set $flag 0;
# if($flag = 0) {
# return 501;
#}

# 客户端完整请求($request_uri) 不区分大小写(~*) 匹配php结尾的正则时返回502
if( $request_uri ~* /(.*)\.php ) {
return 502;
}

# 自动读取linux文件目录,当没有请求的文件时,返回414
if(!-f $request_filename) {
return 414;
}

# 拦截chrome浏览器的请求
if($http_user_agent ~ Chrome) {
return 503;
}
}

文件服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 80;
server_name localhost;

# 开启目录显示
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;

location / {

# 选择文件存储的根目录
root /mnt/d/TDDownload;
}
}

跨域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server{
...
if($http_origin ~ http://(.*).xx.com) {
# http_origin是nginx内置变量,代表请求的origin值,即请求的网址,将它保存为变量http_origin
set $allpw_url $http_origin;
}

# 是否允许请求带验证信息
add_header Access-Controller-Allow-Credentials true;
# 允许跨域的域名,可以是列表也可以是 * 全部允许跨域
add_header Access-Control-Allow-Origin $allow_url;
# 允许脚本访问的返回头
add_header Access-Control-Allow-Headers 'x-requested-whith,content-type,Cache-Control,paragma,Date,x-timestamp';
# 允许请求的方法
add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';
# 允许自定义的头部
add_header Access-Control-Expose-Headers 'WWW-Autenticate,Server-Authorization';
# P3P支持跨域cookie操作
add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR IND ONL UNI COM NAV INT LOC"';

if($request_method = 'OPTIONS') {
return 204;
}
}

防盗链

1
2
3
4
5
6
7
8
location /xxx.png {

valid_referers xx.com;
if($invalid_referer) {
return 404;
}
return ...;
}

缓存静态文件

1
2
3
4
5
location xxx {
# s秒,m分,h小时,d天
expires 2m; # 缓存时间
root img/src;
}

压缩传输

  1. 浏览器请求时会携带支持的解压缩格式Accept-Encoding: gzip, deflate
  2. nginx压缩文件,并携带Content-Encoding: gzip的返回给浏览器,表示当前是用什么方式压缩的。
1
2
3
4
5
6
7
8
9
10
location xx {
gzip on; # 启用gzip压缩,默认off
# 那些文件开启压缩功能
gzip_types application/javascript text/css image/jpeg image/png image/gif;
gzip_min_length 1024;# 超过多少大小才压缩
gzip_buffers 4 1k;# 压缩相应的缓冲块大小和数量,默认是内存一个页大小
gzip_comp_level 1;# 压缩等级,1-9,默认1,取值越大压缩比例越大,越耗时

root src;
}

https

conf文件

1
2
ssl_certificate /xxx/xxx/xx.crt;
ssl_certificate_key /xx/x/server.key;
1
2
3
server {
listen 8080 ssl;
}

高可用

  • 使用keepalive解决高可用问题
  • lvs思想

多个Nginx配置keepalive,就会生成一个虚拟网关(固定ip),虚拟网关按照策略将流量分发给各个Nginx,虚拟网关不是真实网关所以不会挂掉。

  1. 下载对应nginx版本的keepalived压缩包
  2. ./configure --prefix=/data/program/keepalived --sysconf=/etc/指定文件位置(prefix)和配置文件位置(sysconf)
  3. make执行安装
  4. keepalived.conf是配置文件
    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
    global_defs {
    router_id LVS_1 # 设置当前lvs的id
    }

    vrrp_script chk_http_port {
    script "/xxx/chk_nginx_pid.sh"# 设置执行的脚本
    interval 2 # 脚本执行时间,秒
    weight 2
    }

    vrrp_instance VI_1 {
    state MASTER # 主还是从
    interface eth0 # 系统网卡
    virtual_router_id 51 # 主备机器一致
    priority 100 # 优先级 值大的胜出
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }

    virtual_ipaddress {
    192.168.100.1 # 虚拟ip,可以是多个
    }
    srack_script {
    chk_http_port # 调用检测脚本
    }
    }
  • keepalive监控Nginx

chk_http_port.sh内容

1
2
3
4
5
6
7
8
#!/bin/bash
A=`ps -C nginx --no-header |wc -l` # 统计nginx数量
if [$A -eq 0];then
/user/local/nginx/sbin/nginx # 重启nginx
if[ `ps -C nginx --no-header |wc -l` -eq 0 ];then # 如果重启失败,则关闭keepalived服务,进行VIP(虚拟ip)转移(本机keepalived杀死,则流量就会自动转移到其他机子上)
killall keepalived
fi
fi