Nginx

post thumb
Ops
作者 Louis 发表于 2018年7月8日

摘要:

  • Nginx简介
  • 源码编译安装Nginx
  • Nginx服务器性能优化
  • Nginx模块介绍

Nginx简介

​ Nginx(发音同engine x)是一个异步框架的 Web服务器,也可以用作反向代理,负载平衡器 和 HTTP缓存。该软件由 Igor Sysoev 创建,并于2004年首次公开发布。同名公司成立于2011年,以提供支持。

NGINX是免费,开源,高性能的HTTP和反向代理服务器,邮件代理服务器,通用TCP/UDP代理服务器

Nginx在官方测试的结果中,能够支持五万个并行连接,而在实际的运作中,可以支持二万至四万个并行连接。

Nginx 的编写有一个明确目标就是超越 Apache Web 服务器的性能。Nginx 提供开箱即用的静态文件,使用的内存比 Apache 少得多,每秒可以处理大约四倍于 Apache 的请求。低并发下性能与 Apache 相当,有时候还低于,但是在高并发下 Nginx 能保持低资源低消耗高性能。还有高度模块化的设计,模块编写简单。配置文件简洁。

官网:http://nginx.org

文档:https://nginx.org/en/docs/

特性:

  • 模块化设计,较好的扩展性
  • 高可靠性
  • 支持热部署:不停机更新配置文件、升级版本、更换日志文件
  • 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
  • event-driven(事件驱动)、aio(异步IO)、mmap(内存映射)、sendfile

功能:

  • 静态资源的web服务器,html,图片,js,css,txt等静态资源
  • http协议反向代理服务器
  • pop3/imap4协议反向代理服务器
  • FastCGI(LNMP)、uWSGI(python)等协议
  • 模块化(非DSO),如zip、SSL模块

web服务功能:

  • 虚拟主机(server)
  • 支持 keep-alive 和管道连接
  • 访问日志(支持基于日志缓冲提高其性能)
  • url重写(rewirte)
  • 路径别名
  • 基于IP及用户的访问控制
  • 支持速率限制及并发数限制
  • 重新配置和在线升级而无须中断客户的工作进程
  • Memcached 的 GET 接口

1531021483355

nginx的安装

yum源安装

官方源:http://nginx.org/packages/centos/7/x86_64/

epel源:https://mirrors.aliyun.com/epel/7/x86_64/

安装:yum install nginx -y

默认主站点目录:/usr/share/nginx/html

主程序:/usr/sbin/nginx

# nginx 启动服务
# nginx -v|-V 查看版本
# nginx -t 检查配置文件
# nginx -c filename 指定配置文件(default: /etc/nginx/nginx.conf)
# nginx -s signal 发送信号给master进程,signal:stop, quit, reopen, reload
# nginx -g directives 在命令行中指明全局指令

主配文件:/etc/nginx/nginx.conf

子配文件:/etc/nginx/conf.d/*

配置文件格式:

main block:主配置段,即全局配置段,对http,mail都有效
event { 
	... 
}   事件驱动相关的配置

http { 
	... 
}   http/https 协议相关配置段

mail { 
	... 
}   mail 协议相关配置段

stream {
	... 
}   stream 服务器相关配置段

默认配置文件示例:

http {
    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;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        location / {
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

编译安装

[root@centos7 ~]# yum install pcre-devel openssl-devel zlib-devel -y
[root@centos7 ~]# useradd -r -s /sbin/nologin nginx
[root@centos7 ~]# wget https://nginx.org/download/nginx-1.14.0.tar.gz
[root@centos7 ~]# tar xf nginx-1.14.0.tar.gz
[root@centos7 ~]# cd nginx-1.14.0/
[root@centos7 nginx-1.14.0]# vim src/http/ngx_http_header_filter_module.c
static u_char ngx_http_server_string[] = "Server: feijikesi" CRLF;
[root@centos7 nginx-1.14.0]# vim src/core/nginx.h
#define NGINX_VERSION      "6.6.6"					   #Server_tokens 显示的版本号
#define NGINX_VER          "honginx/" NGINX_VERSION		#Server_tokens 显示的服务名称
[root@centos7 nginx-1.14.0]# ./configure --prefix=/usr/local/nginx \
> --conf-path=/etc/nginx/nginx.conf \
> --error-log-path=/var/log/nginx/error.log \
> --http-log-path=/var/log/nginx/access.log \
> --pid-path=/var/run/nginx.pid \
> --lock-path=/var/run/nginx.lock \
> --user=nginx \
> --group=nginx \
> --with-http_ssl_module \
> --with-http_v2_module \
> --with-http_dav_module \
> --with-http_stub_status_module \
> --with-threads \
> --with-file-aio

[root@centos7 nginx-1.14.0]# make && make install
[root@centos7 ~]# echo 'PATH=/usr/local/nginx/sbin/:$PATH' > /etc/profile.d/nginx.sh
[root@centos7 ~]# . /etc/profile.d/nginx.sh
[root@centos7 ~]# nginx
[root@centos7 ~]# curl -I 127.0.0.1
Server: honginx/6.6.6
[root@centos7 ~]# vim /etc/nginx/nginx.conf
http {
    server_tokens off;
}
[root@centos7 ~]# nginx -s reload
[root@centos7 ~]# curl -I 127.0.0.1
Server: honginx

nginx编译安装选项说明

--prefix=/etc/nginx 安装路径
--sbin-path=/usr/sbin/nginx 指明nginx程序文件安装路径
--conf-path=/etc/nginx/nginx.conf 主配置文件安装位置
--error-log-path=/var/log/nginx/error.log 错误日志文件安装位置
--http-log-path=/var/log/nginx/access.log 访问日志文件安装位置
--pid-path=/var/run/nginx.pid 指明pid文件安装位置
--lock-path=/var/run/nginx.lock 锁文件安装位置
--http-client-body-temp-path=/var/cache/nginx/client_temp \
#客户端body部分的临时文件存放路径,服务器允许客户端使用put方法提交大数据时,临时存放的磁盘路径
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
#作为代理服务器,服务器响应报文的临时文件存放路径
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
#作为fastcgi代理服务器,服务器响应报文的临时文件存放路径
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
#作为uwsgi代理服务器,服务器响应报文的临时文件存放路径
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
#作为scgi反代服务器,服务器响应报文的临时文件存放路径
--user=nginx 指明以那个身份运行worker进程,主控master进程一般由root运行
--group=nginx
--with-http_ssl_module 表示把指定模块编译进来

nginx主配置段

帮助文档:http://nginx.org/en/docs/ngx_core_module.html

正常运行必备的配置

  • user:指定worker进程的运行身份,如组不指定,默认和用户名同名

  • pid /PATH/TO/PID_FILE:指定存储nginx主进程PID的文件路径

  • include file|mask:指明包含进来的其它配置文件片断

  • load_module file:

    模块加载配置文件:/usr/share/nginx/modules/*.conf

    指明要装载的动态模块路径:/usr/lib64/nginx/modules/*.so

优化性能相关的配置

  • worker_processes number | auto:worker进程的数量;通常应该为当前主机的cpu的物理核心数

  • worker_cpu_affinity cpumask …:将worker进程绑定到指定CPU上,提高缓存命中率

  cpumask:
  		00000001:0号CPU
  		00000010:1号CPU
  		10000000:8号CPU
  worker_cpu_affinity 0001 0010 0100 1000; 分别将worker进程绑定到1,2,3,4号CPU上
  • worker_priority number:指定worker进程的nice值,设定worker进程优先级:[-20-19]

  • worker_rlimit_nofile number:worker进程所能够打开的文件数量上限

用于调试及定位问题相关的配置

  • daemon on|off:是否以守护进程方式运行nignx,默认是守护进程方式
  • master_process on|off:是否以master/worker模型运行nginx;默认为on;off 将不启动worker
  • error_log file [level] :错误日志文件及其级别;出于调试需要,可设定为debug;但debug仅在编译时使用了“–with-debug”选项时才有效:level:debug|info|notice|warn|error|crit|alter|emerg

事件驱动相关的配置

events {
    worker_connections 1024;
}
  • worker_connections number:每个worker进程所能够打开的最大并发连接数数量;总最大并发数:worker_processes * worker_connections
  • use method:指明并发连接请求的处理方法,默认自动选择最优方法:use epoll;
  • accept_mutex on|off:处理新的连接请求的方法;on指由各个worker轮流处理新请求,Off指每个新请求的到达都会通知(唤醒)所有的worker进程,但只有一个进程可获得连接,会造成“惊群”,影响服务器性能,建议开启

nginx的模块

nginx高度模块化,但其模块早期不支持DSO机制;1.9.11版本支持动态装载和卸载

核心模块:core module

标准模块:

  • HTTP 模块:ngx_http_*
  • Mail 模块 ngx_mail_*
  • Stream 模块 ngx_stream_*

第三方模块:

ngx_http_core_module 核心模块

1)server { … }:配置虚拟主机

$ vim /etc/nginx/nginx.conf
http  { 
   server {
       listen 80;
       server_name www.fenghong.tech;
       root /data/www/;
   }
   server {
       listen 80;
       server_name news.fenghong.tech;
       root /data/news/;
   }
}
$ nginx  启动服务
$ echo news site > /data/news/index.html
$ echo www site > /data/www/index.html

客户端测试:

$ curl www.fenghong.tech
www site
$ curl news.fenghong.tech
news site

2)listen port|address[:port]|unix:/PATH/TO/SOCKET_FILE

listen address[:port] [default_server] [ssl] [http2 | spdy]  [backlog=number] [rcvbuf=size] [sndbuf=size]
  • default_server:设定为默认虚拟主机
  • ssl:限制仅能够通过ssl连接提供服务
  • backlog=number:超过并发连接数后,新请求进入后援队列的长
  • rcvbuf=size:接收缓冲区大小
  • sndbuf=size:发送缓冲区大小

listen PORT; 指令监听在不同的端口,可实现基于端口的虚拟主机

listen IP:PORT; 监听 IP 地址不同,实现基于IP的虚拟主机

3)server_name name …

虚拟主机的主机名称后可跟多个由空白字符分隔的字符串

支持*通配任意长度的任意字符

    server {
        listen 80;
        server_name *.fenghong.tech;
        root /data/default/;
    }
$ echo default > /data/default/index.html
$ nginx -s reload
$ curl xxx.fenghong.tech
default

支持 ~ 起始的字符做正则表达式模式匹配,性能原因慎用

server_name		~^www\d+\.fenghong\.tech$  #说明:\d 表示 [0-9]

匹配优先级机制从高到低: (1) 首先是字符串精确匹配 如:www.fenghong.com (2) 左侧*通配符 如:*.fenghong.tech (3) 右侧*通配符 如:www.fenghong.* (4) 正则表达式 如: ~^.*\.fenghong\.tech$ (5) default_server

4)tcp_nodelay on|off

在keepalived模式下的连接是否启用TCP_NODELAY选项

当为off时,延迟发送,合并多个请求后再发送

默认on时,不延迟发送

可用于:http, server, location

如果为了节约服务器性能可以打开,如果为了用户体验更好选择关闭

5)sendfile on|off

是否启用sendfile功能,在内核中封装报文直接发送,默认关闭

6)server_tokens on|off|build|string

是否在响应报文的Server首部显示nginx版本,建议关闭

7)root

设置web资源的路径映射;用于指明请求的URL所对应的文档的目录路径,可用于http, server, location, if in location

8)location [ = | ~ | ~* | ^~ ] uri { … }

在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,并找出一个最佳匹配,而后应用其配置

# mkdir /data/www/blog/
# echo blog > /data/www/blog/index.html
# vim /etc/nginx/nginx.conf
    server {
        listen 80;
        server_name www.fenghong.tech;
        root /data/www/;
        location /blog {
            root /data/www/;
        }
    }
# curl http://www.fenghong.tech/blog/  #测试
blog

=:对URI做精确匹配

^~: 对URI的最左边部分做匹配检查,不区分字符大小写

~: 对URI做正则表达式模式匹配,区分字符大小写

~*: 对URI做正则表达式模式匹配,不区分字符大小写

不带符号:匹配起始于此uri的所有的uri

匹配优先级从高到低:=, ^~, ~/~*, 不带符号

例如:

location = / {
    [ configuration A ]
}
location / {
    [ configuration B ]
}
location /documents/ {
    [ configuration C ]
}
location ^~ /images/ {
    [ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

The “/” request will match configuration A, 
the “/index.html” request will match configuration B, 
the “/documents/document.html” request will match configuration C, 
the “/images/1.gif” request will match configuration D, 
and the “/documents/1.jpg” request will match configuration E.

9)alias

路径别名,文档映射的另一种机制;仅能用于location上下文

    server {
        listen 80;
        server_name www.fenghong.tech;
        root /data/www/;
        location /blog {
            alias /data/www/blog;  #和root /data/www/;作用相同
        }
    }
# curl http://www.fenghong.tech/blog/
blog

注意:location中使用root指令和alias指令的意义不同 (a) root,给定的路径对应于location中的/uri/左侧的/ (b) alias,给定的路径对应于location中的/uri/右侧的/

10)index file …

指定默认网页文件,注意需要装载 ngx_http_index_module 模块

11)error_page code … [=[response]] uri

定义错误页,以指定的响应状态码进行响应;可用位置:http, server, location, if in location

# echo "404 not found page" > /data/www/404.html
    server {
        listen 80;
        server_name www.fenghong.tech;
        root /data/www/;
        error_page 404 /404.html;
    }
# curl http://www.fenghong.tech/notfound.html
404 not found page
    server {
        listen 80;
        server_name www.fenghong.tech;
        root /data/www/;
        error_page 404 =200 /404.html;  #将404返回码重定向成200访问码,防止浏览器劫持
    }
# curl -I http://www.fenghong.tech/notfound.html
HTTP/1.1 200 OK  #测试为200正确访问码

12)try_files file … uri | =code

​ 按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有的文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误

# echo default page > /data/news/default.html
    server {
        listen 80;
        server_name news.fenghong.tech;
        root /data/news/;
        location / {
            try_files $uri /default.html;  #如果用户访问的URI不存在则放回默认页面
        }
    }
# curl http://news.fenghong.tech/index.html   
news site
# curl http://news.fenghong.tech/noindex.html
default page
    server {
        listen 80;
        server_name news.fenghong.tech;
        root /data/news/;
        location / {
            try_files $uri $uri/index.html $uri.html =404;
        }
    }
# curl http://news.fenghong.tech/index.html  
news site
# curl http://news.fenghong.tech/noindex.html
404 Not Found

13)keepalive_timeout timeout [header_timeout]

设定保持连接超时时长,0表示禁止长连接,默认为75s,可用于http, server, location

14)keepalive_requests number

在一次长连接上所允许请求的资源的最大数量,默认为100

15)keepalive_disable none | browser …

对哪类型的浏览器禁用长连接

16)send_timeout time

向客户端发送响应报文的超时时长,此处是指两次写操作之间的间隔时长,而非整个响应过程的传输时长

17)client_body_buffer_size size

用于接收每个客户端请求报文的body部分的缓冲区大小;默认为16k;

超出此大小时,其将被暂存到磁盘上的由下面 client_body_temp_path 指令所定义的位置

18)client_body_temp_path path [level1 [level2 [level3]]]

设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量

19)limit_rate rate

限制响应给客户端的传输速率,单位是bytes/second;默认值0表示无限制

20)limit_except method … { … }

限制客户端使用除了指定的请求方法之外的其它方法,仅用于location

method:GET(包括HEAD), HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH

location /upload {
    root /date/www/;
    limit_except GAT {
        allow 192.168.0.9/24;
        deny all;
    }
}
# 除了 GET和HEAD 之外其它方法仅允许192.168.0.9/24主机使用

21)aio on | off | threads[=pool]

是否启用aio功能

22)directio size | off

当文件大于等于给定大小时,例如directio 4m,同步到磁盘,而非写缓存,以防数据丢失

23)open_file_cache off | max=N [inactive=time]

  • max=N:可缓存的缓存项上限;达到上限后会使用LRU算法实现管理
  • inactive=time:缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于open_file_cache_min_uses指令所指定的次数的缓存项即为非活动项将被删除

24)open_file_cache_errors on | off

是否缓存查找时发生错误的文件一类的信息,默认值为off

25)open_file_cache_min_uses number

open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项,默认值为1

26)open_file_cache_valid time

缓存项有效性的检查频率,默认值为60s

ngx_http_access_module 访问控制模块

基于ip的访问控制功能

    server {
        listen 80 default_server;
        server_name www.fenghong.tech;
        root /data/www/;
        location / {
            allow 192.168.0.0/24;
            deny all;
        }
    }

自上而下检查,一旦匹配,将生效,条件严格的置前

ngx_http_auth_basic_module 用户认证模块

实现基于用户的访问控制,使用basic机制进行用户认证

# mkdir /data/www/admin/
# echo admin area > /data/www/admin/index.html
    server {
        listen 80 default_server;
        server_name www.fenghong.tech;
        root /data/www/;
        location /admin {
            auth_basic "Admin Area";
            auth_basic_user_file /etc/nginx/.ngxpasswd;
        }
    }
# yum install httpd-tools -y
# htpasswd -cm /etc/nginx/.ngxpasswd user1
# htpasswd -m /etc/nginx/.ngxpasswd user2
# nginx -s reload
浏览器访问:http://192.168.0.8/admin/  测试

ngx_http_stub_status_module 服务器状态信息模块

用于输出nginx的基本状态信息

    server {
        listen 80 default_server;
        server_name www.fenghong.tech;
        root /data/www/;
        location /admin {
            auth_basic "Admin Area";
            auth_basic_user_file /etc/nginx/.ngxpasswd;
        }
        location /status {
            stub_status;
            allow 192.168.0.0/24;
            deny all;
        }
    }
$ curl http://192.168.0.8/status/
Active connections: 3 
server accepts handled requests
       35      35      34
Reading: 0 Writing: 1 Waiting: 2 

Active connections:当前状态,活动状态的连接数 accepts:统计总值,已经接受的客户端请求的总数 handled:统计总值,已经处理完成的客户端请求的总数 requests:统计总值,客户端发来的总的请求数 Reading:当前状态,正在读取客户端请求报文首部的连接的连接数 Writing:当前状态,正在向客户端发送响应报文过程中的连接数 Waiting:当前状态,正在等待客户端发出请求的空闲连接数

ngx_http_log_module 日志模块

指定日志格式记录请求

1)log_format name string …

string可以使用nginx核心模块及其它模块内嵌的变量

2)access_log path [format [buffer=size][gzip[=level]][flush=time][if=condition]] 或 access_log off

http {
   log_format  customlog  '$remote_addr - $remote_user [$time_iso8601] "$request" '
                 '$status $body_bytes_sent "$http_referer" '
                 '"$http_user_agent" "$http_x_forwarded_for"';
   server {
        listen 80 default_server;
        server_name www.fenghong.tech;
        root /data/www/;
        access_log /var/log/nginx/www.fenghong.tech-access.log customlog buffer=32k;
    }
}

3)open_log_file_cache max=N [inactive=time][min_uses=N][valid=time]; 和 open_log_file_cache off;

缓存各日志文件相关的元数据信息

max:缓存的最大文件描述符数量 min_uses:在inactive指定的时长内访问大于等于此值方可被当作活动项 inactive:非活动时长 valid:验证缓存中各缓存项是否为活动项的时间间隔

ngx_http_gzip_module 压缩传输模块

用gzip方法压缩响应数据,节约带宽

1)gzip on | off; 启用或禁用gzip压缩

2)gzip_comp_level level; 压缩比由低到高:1 到 9 ,默认:1

3)gzip_disable regex …; 匹配到客户端浏览器不执行压缩

4)gzip_min_length length; 启用压缩功能的响应报文大小阈值

5)gzip_http_version 1.0 | 1.1; 设定启用压缩功能时,协议的最小版本,默认:1.1

6)gzip_buffers number size; 支持实现压缩功能时缓冲区数量及每个缓存区的大小,默认:32 4k 或 16 8k

7)gzip_types mime-type …; 指明仅对哪些类型的资源执行压缩操作;即压缩过滤器,默认包含有text/html,不用显示指定,否则出错

8)gzip_vary on | off; 如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”

9)gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any …;

nginx充当代理服务器时,对于后端服务器的响应报文,在何种条件下启用压缩功能

  • off:不启用压缩
  • expired,no-cache, no-store,private:对后端服务器的响应报文首部Cache-Control值任何一个,启用压缩功能
server {
    listen 80 default_server;
    server_name www.fenghong.tech;
    root /data/www/;
    gzip on;
    gzip_comp_level 6;
    gzip_min_length 64;
    gzip_proxied any;
    gzip_types text/xml text/css text/plain application/javascript;
}

ngx_http_ssl_module 加密传输模块

1)ssl on|off; 为指定虚拟机启用HTTPS protocol, 建议用listen指令代替

2)ssl_certificate file; 当前虚拟主机使用PEM格式的证书文件

3)ssl_certificate_key file; 当前虚拟主机上与其证书匹配的私钥文件

4)ssl_protocols [SSLv2][SSLv3][TLSv1][TLSv1.1][TLSv1.2]; 支持ssl协议版本,默认为后三个

5)ssl_session_cache off | none | [builtin[:size]][shared:name:size];

  • none: 通知客户端支持ssl session cache,但实际不支持
  • builtin[:size]:使用OpenSSL内建缓存,为每worker进程私有
  • [shared:name:size]:在各worker之间使用一个共享的缓存

6)ssl_session_timeout time; 客户端连接可以复用ssl session cache中缓存的ssl参数的有效时长,默认5m

服务器配置示例:

[root@nginx ~]# cd /etc/pki/tls/certs/
[root@nginx certs]# vim Makefile
%.key:
    umask 77 ; \
    /usr/bin/openssl genrsa $(KEYLEN) > $@
[root@nginx certs]# make aa.crt
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:bj
Locality Name (eg, city) [Default City]:bj
Organization Name (eg, company) [Default Company Ltd]:aa.com
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server's hostname) []:www.aa.com
[root@nginx certs]# make bb.crt
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:bj
Locality Name (eg, city) [Default City]:bj
Organization Name (eg, company) [Default Company Ltd]:bb.com
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server's hostname) []:www.bb.com
[root@nginx certs]# mkdir /etc/nginx/conf.d/ssl/
[root@nginx certs]# mv aa.crt aa.key bb.crt bb.key /etc/nginx/conf.d/ssl/
[root@nginx ~]# vim /etc/nginx/conf.d/vhosts.conf
server {
    listen 443 ssl;
    server_name www.aa.com;
    root /data/www/aa/;
    ssl_certificate /etc/nginx/conf.d/ssl/aa.crt;
    ssl_certificate_key /etc/nginx/conf.d/ssl/aa.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;
}
server {
    listen 443 ssl;
    server_name www.bb.com;
    root /data/www/bb/;
    ssl_certificate /etc/nginx/conf.d/ssl/bb.crt;
    ssl_certificate_key /etc/nginx/conf.d/ssl/bb.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;
}
[root@nginx ~]# mkdir -pv /data/www/{aa,bb}
[root@nginx ~]# echo "aa test page" > /data/www/aa/index.html
[root@nginx ~]# echo "bb test page" > /data/www/bb/index.html
[root@nginx ~]# nginx

客户端测试:

[root@client ~]# vim /etc/hosts
192.168.0.8 www.aa.com www.bb.com
[root@client ~]# curl -k https://www.aa.com/
aa test page
[root@client ~]# curl -k https://www.bb.com/
bb test page

ngx_http_rewrite_module URI重写模块

将用户请求的URI基于PCRE regex所描述的模式进行检查,而后完成重定向替换

1)rewrite regex replacement [flag]

将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI

如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查

隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制

如果replacement是以http://或https://开头,则替换结果会直接以重向返回给客户端, 即永久重定向301

[flag]:

  • last:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环,不建议在location中使用
  • break:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用
  • redirect:临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
  • permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,状态码:301

2)return

return code [text];

return code URL;

return URL;

停止处理,并返回给客户端指定的响应码

3)rewrite_log on | off;

是否开启重写日志, 发送至error_log(notice level)

4)set $variable value;

用户自定义变量;注意:变量定义和调用都要以$开头

5)if (condition) { … }

条件满足时,执行配置块中的配置指令;server, location

condition:

  • = 相同 != 不同
  • ~:模式匹配,区分字符大小写
  • ~*:模式匹配,不区分字符大小写
  • !~:模式不匹配,区分字符大小写
  • !~*:模式不匹配,不区分字符大小写
  • -e, !-e 存在(包括文件,目录,软链接)
  • -f, !-f 文件 -d, !-d 目录 -x, !-x 执行

实现http重定向到https

server {
    listen 80 default_server;
    listen 443 ssl;
    server_name www.aa.com;
    root /data/www/aa;
    ssl_certificate /etc/nginx/conf.d/ssl/aa.crt;
    ssl_certificate_key /etc/nginx/conf.d/ssl/aa.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;
    location / {
        if ( $scheme = http ) {
            rewrite / https://www.aa.com/ redirect;
        }
    }
}

ngx_http_referer_module 模块

用来阻止Referer首部无有效值的请求访问,可防止盗链

valid_referers none|blocked|server_names|string …; 定义referer首部的合法可用值,不能匹配的将是非法值

  • none:请求报文首部没有referer首部
  • blocked:请求报文有referer首部,但无有效值
  • server_names:参数,其可以有值作为主机名或主机名模式
  • arbitrary_string:任意字符串,但可使用*作通配符
  • regular expression:被指定的正则表达式模式匹配到的字符串,要使用~开头,例如: ~.*\.fenghong\.com
[root@nginx ~]# cp /usr/share/backgrounds/night.jpg /data/www/aa/
[root@nginx ~]# vim /data/www/bb/index.html
bb test page
<img src=http://www.aa.com/night.jpg>  #bb.com网站盗链aa.com网站图片
[root@nginx ~]# vim /etc/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.aa.com;
    root /data/www/aa;
    valid_referers none block server_names *.aa.com ~\.aa\.;  #只有从aa.com访问的才可以浏览
    if  ($invalid_referer)  {
        return 403  http://www.aa.com;
    }
}
server {
    listen 80;
    server_name www.bb.com;
    root /data/www/bb/;
}
现在访问www.bb.com无法获取aa.com的图片了

ngx_http_proxy_module 反向代理模块

反向代理:转发请求至另一台主机

1)proxy_pass URL; proxy_pass后面路径不带uri时,会将location的uri传递(附加)给后端主机

server {
    listen 80;
    server_name www.aa.com;
    location /admin {
        proxy_pass http://192.168.0.9/;  #带" / "
    }
}
访问http://www.aa.com时相当于访问 http://192.168.0.9/
server {
    listen 80;
    server_name www.aa.com;
    location /admin {
        proxy_pass http://192.168.0.9;  #不带" / "
    }
}
访问http://www.aa.com时相当于访问 http://192.168.0.9/admin

如果location定义其uri时使用了正则表达式的模式,则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加至后端服务器之后

2)proxy_set_header field value; 设定发往后端主机的请求报文的请求首部的值

proxy_set_header X-Real-IP  $remote_addr;  #$remote_addr客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  #$proxy_add_x_forwarded_for代理IP

配合日志记录实现后端web服务器记录真正的客户端地址:

[root@nginx ~]# vim /etc/nginx/conf.d/vhosts.conf
server {
    listen 80 default_server;
    server_name www.aa.com;
    location / {
        proxy_pass http://192.168.0.9/;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
[root@nginx-1 ~]# vim /etc/nginx/nginx.conf
listen       80;
listen       [::]:80;
log_format  mylogformat  '$http_x_forwarded_for - $remote_user [$time_iso8601] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
[root@nginx-1 ~]# vim /etc/nginx/conf.d/vhosts.conf
server {
    listen 80 default_server;
    server_name www.aa.com;
    root /data/www/aa/;
    access_log /var/log/nginx/www.aa.com-access.log mylogformat;
}
root@nginx-1 ~]# mkdir -pv /data/www/aa/
[root@nginx-1 ~]# echo www.aa.com test page on nginx-1 > /data/www/aa/index.html
[root@nginx-2 ~]# curl www.aa.com
www.aa.com test page on nginx-1
[root@nginx-1 ~]# tail -f /var/log/nginx/www.aa.com-access.log
192.168.0.10 - - [2018-07-07T14:34:07+08:00] "GET / HTTP/1.0" 200 32 "-" "curl/7.29.0" "192.168.0.10"  #显示的是真正的客户端的IP地址

3)proxy_cache_path; 定义可用于proxy功能的缓存,在http中定义

proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

配置代理缓存示例:在http配置定义缓存信息

[root@nginx ~]# vim /etc/nginx/nginx.conf
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
[root@nginx ~]# mkdir /var/cache/nginx/

proxycache:20m 指内存中缓存的大小,主要用于存放key和metadata

max_size=1g 指磁盘存入文件内容的缓存空间最大值

[root@nginx ~]# vim /etc/nginx/conf.d/vhosts.conf
server {
    listen 80 default_server;
    server_name www.aa.com;
    location / {
        proxy_pass http://192.168.0.9/;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_cache proxycache;
        proxy_cache_key $request_uri;
        proxy_cache_valid 200 302 301 1h;
        proxy_cache_valid any 1m;
    }
}
[root@nginx ~]# tree /var/cache/nginx/proxy_cache/
/var/cache/nginx/proxy_cache/
└── 9
    └── d
        └── 7
            └── 6666cd76f96956469e7be39d750cc7d9

4)proxy_cache zone|off; 默认off ,指明调用的缓存,或关闭缓存机制

5)proxy_cache_key string; 缓存中用于“键”的内容

默认值:proxy_cache_key $scheme$proxy_host$request_uri;

6)proxy_cache_valid [code …] time; 定义对特定响应码的响应内容的缓存时长,定义在http{…}中

7)proxy_cache_use_stale; 在被代理的后端服务器出现哪种情况下,可以真接使用过期的缓存响应客户端

proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ...

8)proxy_cache_methods GET | HEAD | POST …; 对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存

9)proxy_hide_header field; 默认nginx在响应报文不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel-等,用于隐藏后端服务器特定的响应首部

10)proxy_connect_timeout time; 定义与后端服务器建立连接的超时时长,如超时会出现502错误,默认为60s,一般不建议超出75s

11)proxy_send_timeout time; 将请求发送给后端服务器的超时时长;默认为60s

12)proxy_read_timeout time; 等待后端服务器发送响应报文的超时时长,默认为60s

ngx_http_headers_module 模块

向由代理服务器响应给客户端的响应报文添加自定义首部,或修改指定首部的值

1)add_header name value [always]; 添加自定义首部

add_header X-Via  $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;

2)add_trailer name value [always]; 添加自定义响应信息的尾部

ngx_http_fastcgi_module 模块

转发请求到FastCGI服务器,不支持php模块方式

1)fastcgi_pass address; address为后端的fastcgi server的地址;可用位置:location, if in location

2)fastcgi_index name; fastcgi默认的主页资源;fastcgi_index index.php;

3)fastcgi_param parameter value [if_not_empty]; 设置传递给 FastCGI服务器的参数值,可以是文本,变量或组合

4)fastcgi_cache_path path … 定义fastcgi的缓存:

fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time][purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

path:缓存位置为磁盘上的文件系统 max_size=size:磁盘path路径中用于缓存数据的缓存空间上限 levels=levels:缓存目录的层级数量,以及每一级的目录数量 levels=ONE:TWO:THREE:示例:leves=1:2:2 keys_zone=name:size:k/v映射的内存空间的名称及大小 inactive=time:非活动时长

5)fastcgi_cache zone|off; 调用指定的缓存空间来缓存数据,可用位置:http, server, location

6)fastcgi_cache_key string; 定义用作缓存项的key的字符串,示例:fastcgi_cache_key $request_rui;

7)fastcgi_cache_methods GET | HEAD | POST …; 为哪些请求方法使用缓存

8)fastcgi_cache_min_uses number; 缓存空间中的缓存项在inactive定义的非活动时间内至少要被访问到此处所指定的次数方可被认作活动项

9)fastcgi_keep_conn on | off; 收到后端服务器响应后,fastcgi服务器是否关闭连接,建议启用长连接

10)fastcgi_cache_valid [code …] time; 不同的响应码各自的缓存时长

示例:配置 lnmp

[root@lnmp ~]# yum install nginx php-fpm php-mysql mariadb -y
[root@lnmp ~]# cp /etc/nginx/nginx.conf{,.bak}
[root@lnmp ~]# vim /etc/nginx/nginx.conf
http {
    fastcgi_cache_path /var/cache/nginx/fcgi_cache levels=1:2:1 keys_zone=fcgicache:20m inactive=120s;
    server {
        listen       80 default_server;
        server_name  www.fenghong.tech;
        root         /data/www;
        location / {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME /data/www/$fastcgi_script_name;
                include fastcgi_params;
                fastcgi_cache fcgicache; 
                fastcgi_cache_key $request_uri;
                fastcgi_cache_valid 200 302 10m;
                fastcgi_cache_valid 301 1h;
                fastcgi_cache_valid any 1m;
        }
        location ~* ^/(status|ping)$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_param  SCRIPT_FILENAME  $fastcgi_script_name;
                include fastcgi_params;
        }
    }
}
[root@lnmp ~]# vim /etc/php-fpm.d/www.conf
pm.status_path = /status
ping.response = pong
ping.path = /ping
[root@lnmp ~]# systemctl enable nginx.service php-fpm.service
[root@lnmp ~]# systemctl start nginx.service php-fpm.service
[root@lnmp ~]# mkdir /var/cache/nginx/
[root@lnmp ~]# mkdir -pv /data/www/
[root@lnmp ~]# vim /data/www/index.php
<?php
phpinfo();
?>
测试:
# curl 192.168.0.8/status  #查看PHP的工作状态
pool:                 www
process manager:      dynamic
start time:           07/Jul/2018:16:27:07 +0800
start since:          1463
accepted conn:        9
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       4
active processes:     1
total processes:      5
max active processes: 1
max children reached: 0
slow requests:        0
# curl 192.168.0.8/ping  #测试PHP进程是否工作
pong
访问 http://192.168.0.8/

ngx_http_upstream_module 反向代理调度模块

用于将多个服务器定义成服务器组,而由proxy_pass, fastcgi_pass等指令进行引用,实现健康检查,负载均衡的功能

1)upstream name { … } 定义后端服务器组,会引入一个新的上下文,默认调度算法是wrr,在http中定义

2)server address [parameters]; 在upstream上下文中server成员,以及相关的参数

address:

  • unix: /PATH/TO/SOME_SOCK_FILE socket文件
  • IP[:PORT] IP加端口
  • HOSTNAME[:PORT] 主机名加端口

parameters:

  • weight=number 权重,默认为1
  • max_conns 连接后端报务器最大并发活动连接数,1.11.5版本后支持
  • max_fails=number 失败尝试最大次数;超出此处指定的次数时,server将被标记为不可用,默认为1
  • fail_timeout=time 后端服务器标记为不可用状态的连接超时时长,默认10s
  • backup 将服务器标记为“备用”,即所有服务器均不可用时才启用
  • down 标记为“不可用”,配合ip_hash使用,实现灰度发布

3)ip_hash 源地址hash调度方法

4)least_conn 最少连接调度算法,当server拥有不同的权重时其为wlc,当所有后端主机连接数相同时,则使用wrr,适用于长连接

5)hash key [consistent]

基于指定的key的hash表来实现对请求的调度,此处的key可以直接文本、变量或二者组合

将请求分类,同一类请求将发往同一个upstream server,使用consistent参数,将使用ketama一致性hash算法,适用于后端是Cache服务器(如varnish)时使用

hash $request_uri consistent;
hash $remote_addr;

6)keepalive 连接数N:为每个worker进程保留的空闲的长连接数量,可节约nginx端口,并减少连接管理的消耗

7)health_check [parameters]; 健康状态检测机制;只能用于location上下文,仅对nginx plus有效

  • interval=time检测的频率,默认为5秒
  • fails=number:判定服务器不可用的失败检测次数;默认为1次
  • passes=number:判定服务器可用的失败检测次数;默认为1次
  • uri=uri:做健康状态检测测试的目标uri;默认为/
  • match=NAME:健康状态检测的结果评估调用此处指定的match配置块

8)match name { … } 对backend server做健康状态检测时,定义其结果判断机制;只能用于http上下文,仅对nginx plus有效

  • status code[ code …]: 期望的响应状态码
  • header HEADER[operator value]:期望存在响应首部,也可对期望的响应首部的值基于比较操作符和值进行比较
  • body:期望响应报文的主体部分应该有的内容

实现proxy反向代理的动静分离缓存负载均衡。

1530955794774

静态服务器的配置

ip为192.168.1.13

$ yum install -y httpd
$ vim /etc/httpd/conf/httpd.conf
LogFormat \"%{X-Real-IP}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
$ echo static html > /var/www/html/index.html
$ cp /var/log/messages-20180610 /var/www/html/m.txt  #生成大文件
$ for i in {1..10} ;do echo page$i on 8 > test$i.html;done    #在192.168.1.13运行
$ service httpd restart

动态服务器配置

ip为192.168.1.8

$ yum install -y httpd php php-mysql mysql-server
$ service httpd restart
$ service mysqld start
$ mysql -e "grant all on *.* to test@'192.168.1.%' identified by 'centos';"
$ cat /var/www/html/index.php #测试php联通mysql页面
<?php
$dsn='mysql:host=192.168.1.8;dbname=mysql';
$username='test';
$passwd='centos';
$dbh=new PDO($dsn,$username,$passwd);
var_dump($dbh);
?>
$ for i in {1..10} ;do echo page$i on 13 > test$i.html;done	#生成调度文件

nginx代理服务器

ip为192.168.1.18

  • 反代功能:
$ vim /etc/nginx/conf.d/a.com.conf
location ~ \.php$ {
    proxy_pass http://192.168.1.8;
}
location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://192.168.1.13;
}
lcotion /bbs {
    proxy_pass httpd://192.168.1.8/; #有url,将会把/bbs置换成/。
    proxy_pass httpd://192.168.1.8; #无url,将会把/bbs补加在其后。
}
  • 缓存功能:

proxy_cache_path 必须放在http{}语句块中,而后续的server语句块也要加入相应的代码

$ mkdir -pv /var/cache/nginx/
mkdir: created directory ‘/var/cache/nginx’
$ vim /etc/nginx/nginx.conf
···
http {
···
	#开启缓存功能,与下面的缓存功能一起启用方可生效
	proxy_cache_path /var/cache/nginx/nginx_cache levels=1:1:1
                        keys_zone=proxycache:20m
                        inactive=120s max_size=1g;
···
$ vim /etc/nginx/conf.d/a.com.conf
···
    location / {
    	##代理功能
        proxy_pass http://192.168.1.13/;
        proxy_set_header X-Real-IP $remote_addr;
        ##缓存功能
        proxy_cache proxycache;
        proxy_cache_key $request_uri;
        proxy_cache_valid 200 302 301 1h;
        proxy_cache_valid any 1m;
        #响应头部自定义添加,来自ngx_http_headers_module提供
        add_header X-Via $server_addr;
        add_header X-Cache $upstream_cache_status;
        add_header X-Accel $server_name;
        }
···
$ nginx -s reload
  • 调度功能
$ vim /etc/nginx/nginx.conf
···
http {
···
	upstream www {
		least_conn;	#最少连接算法,类似lvs中的wlc算法。
		#ip_hash;	#源地址hash算法。
		#hash $request_uri [consistent];	#对请求的uri进行hash后,对server的权重和取余
		#hash $remote_addr;  
         server 192.168.1.8:80;
         server 192.168.1.9:80 weight=3;
         server 192.168.1.13:80 backup|down; #down的适合灰度发布中使用
    }
···
$ vim /etc/nginx/conf.d/a.com.conf
    location / {
        proxy_pass http://www;                                                          
    }

client端访问测试

$ curl 172.20.5.24				#出现下面页面说明反代成功
static html
$ curl 172.20.5.24/index.php    #出现下面页面说明反代成功
object(PDO)#1 (0) {
}

$ curl 172.20.5.24/bbs
webbs

$ ab -c 100 -n 1000 http://172.20.5.24/m.txt
···
Requests per second:    40.07 [#/sec] (mean)  	#缓存前
···
Requests per second:    68.24 [#/sec] (mean)	#缓存后
···
$ curl -I 172.20.5.24/m.txt	#后端的服务器相关内容都被隐藏了
HTTP/1.1 200 OK
Server: honginx/6.6.6
Date: Sat, 07 Jul 2018 12:43:20 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 1288618
Connection: keep-alive
Last-Modified: Sat, 07 Jul 2018 00:14:11 GMT
ETag: "28063c-13a9aa-5705da8e165e8"
X-Via: 172.20.5.24
X-Cache: MISS
X-Accel: www.a.com
Accept-Ranges: bytes
Accept-Ranges: bytes

##测试调度功能
$ for i in {1..10};do curl 172.20.5.24/test$i.html;done
page1 on 13
page2 on 13
page3 on 13
page4 on 8
page5 on 8
page6 on 8
page7 on 8
page8 on 8
page9 on 8
page10 on 13

在客户端测试时不会看到调度的效果,想要看到调度的效果需要把缓存关闭

感谢阅读!

上一篇
I/O