1、 Nginx 介绍
- I/O:
网络IO:本质是socket读取
磁盘IO:每次IO,都要经由两个阶段:
第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长
第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短 - 特性:
模块化设计,较好的扩展性
高可靠性
支持热部署:不停机更新配置文件,升级版本,更换日志文件
低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需要2.5M内存
event-driven,aio:异步非阻塞,mmap,sendfile:加速访问速度,数据不需要进入用户空间,直接从内核空间封装http头部后发送出去 - nginx的功用:
静态的web资源服务器
html,图片,js,css,txt等静态资源
结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
http/https协议的反向代理
imap4/pop3协议的反向代理
tcp/udp协议的请求转发(反向代理) - web服务相关的功能:
虚拟主机(server)
支持keep-alive 和管道连接
访问日志(支持基于日志缓冲提高其性能)
urlrewirte
路径别名
基于IP及用户的访问控制
支持速率限制及并发数限制
重新配置和在线升级而无须中断客户的工作进程
Memcached的GET 接口 - nginx的程序架构:
master/worker结构
一个master进程:负责加载和分析配置文件、管理worker进程、平滑升级
一个或多个worker进程:处理并响应用户请求
2、 Nginx 安装、目录结构和命令
- 安装
官方:http://nginx.org/packages/centos/7/x86_64/RPMS
Fedora-EPEL:https://mirrors.aliyun.com/epel/7/x86_64/
安装 yum install nginx
- nginx目录结构和命令
网站默认主目录/usr/share/nginx/html
主配置文件:/etc/nginx/nginx.conf
子配置文件/etc/nginx/conf.d/*.conf
Nginx:默认为启动nginx
-h 查看帮助选项
-t 测试nginx语法错误
-c filename 指定配置文件(default: /etc/nginx/nginx.conf)
-s signal 发送信号给master进程,signal可为:stop, quit, reopen, reload
示例:
nginx -s stop 停止
nginx-s reload 加载配置文件
3、Nginx的配置
Nginx的相关配置可以参考官方文档
http://nginx.org/en/docs/
根据如下图的索引进行查找
主配置文件结构:四部
main block:主配置段,即全局配置段,对http,mail都有效
event {
...
} 事件驱动相关的配置
http {
...
}http/https 协议相关配置段
mail {
...
} mail 协议相关配置段
stream {
...
} stream 服务器相关配置段
- 隐藏版本号
vim /etc/nginx/nginx.conf
server_tokens off; ---注意不能放到放到全局配置里,并且以分号结尾
nginx -t
nginx -s reload
curl -I 172.18.21.107
一、Main 全局配置段常见的配置指令分类
- 正常运行必备的配置:
1、user
指定worker进程的运行身份,默认是nginx,如组不指定,默认和用户名同名
2、pid /PATH/TO/PID_FILE
指定存储nginx主进程PID的文件路径
3、include file | mask
指明包含进来的其它配置文件片断
4、load_modulefile
模块加载配置文件:/usr/share/nginx/modules/*.conf ---这个文件规定了模块加载的路径
指明要装载的动态模块路径: /usr/lib64/nginx/modules
- 性能优化相关的配置:
1、worker_processes number | auto
worker进程的数量;通常应该为当前主机的cpu的物理核心数
2、worker_cpu_affinity cpumask...
worker_cpu_affinity auto [cpumask] 使进程和cpu绑定,提高缓存命中率,也就是进程工作在固定的cpu上,这样客户端访问的时候就可以利用缓存,不必再跑到磁盘上去读数据,如果cpu不固定,进程工作在一个新的cpu上就需要建立新的缓存
CPU MASK:00000001:0号CPU
00000010:1号CPU
10000000:8号CPU
worker_cpu_affinity 0001 0010 0100 1000;表示工作在0、1、2、3cpu上
3、worker_priority number
指定worker进程的nice值,设定worker进程优先级:[-20,19]
4、worker_rlimit_nofile number
worker进程所能够打开的文件数量上限,如65535
- 事件驱动相关的配置:
events {
...
}
1、worker_connections number
每个worker进程所能够打开的最大并发连接数数量,如10240,此项在生产中要根据实际情况进行增加
2、use method
指明并发连接请求的处理方法,默认自动选择最优方法
use epoll;
3、accept_mutex on | off 互斥
处理新的连接请求的方法;on指由各个worker轮流处理新请求,off指每个新请求的到达都会通知(唤醒)所有的worker进程,但只有一个进程可获得连接,造成“惊群”,影响性能,默认on
- 调试和定位问题:
1、daemon on|off
是否以守护进程方式运行nignx,默认是守护进程方式,否则是以前端运行了
2、master_processon|off
是否以master/worker模型运行nginx;默认为on,off 将不启动worker
3、error_log file [level]
错误日志文件及其级别;出于调试需要,可设定为debug;但debug仅在编译时使用了“--with-debug”选项时才有效
level:debug|info|notice|warn|error|crit|alter|emerg
二、http协议的相关配置
基于ngx_http_core_module模块
- 配置虚拟主机
vim /etc/nginx/conf.d/vhost.conf
server{
listen 80; ---表示监控在本地的所有ip
server_name www.a.com;
root /app/website1; ---根目录的路径
}
server{
listen 192.168.74.132:80;
server_name www.b.com;
root /app/website2;
}
listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size]
在监听的端口后面还可以加上下面的一些选项
default_server设定为默认虚拟主机
ssl限制仅能够通过ssl连接提供服务
backlog=number 超过并发连接数后,新请求进入后援队列的长度
rcvbuf=size接收缓冲区大小
sndbuf=size 发送缓冲区大小
注意:
(1) 基于port;
listen PORT; 指令监听在不同的端口
(2) 基于ip的虚拟主机
listen IP:PORT; IP 地址不同
(3) 基于hostname
server_name fqdn; 指令指向不同的主机名
- server_name name ...
虚拟主机的主机名称后可跟多个由空白字符分隔的字符串
支持*通配任意长度的任意字符
server_name *.magedu.com www.magedu.*
支持~起始的字符做正则表达式模式匹配,性能原因慎用
server_name ~^www\d+\.magedu\.com$
\d 表示[0-9]
匹配优先级机制从高到低:
(1) 首先是字符串精确匹配如:www.magedu.com
(2) 左侧*通配符如:*.magedu.com
(3) 右侧*通配符如:www.magedu.*
(4) 正则表达式如:~^.*\.magedu\.com$
(5) default_server
- tcp_nodelay on | off
在keepalived模式下的连接是否启用TCP_NODELAY选项
当为off时,延迟发送,合并多个请求后再发送
默认on时,不延迟发送
可用于:http, server, location - sendfile on | off
是否启用sendfile功能,在内核中封装报文直接发送,默认on - server_tokens on | off | build | string
是否在响应报文的Server首部显示nginx版本 - location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,并找出一个最佳匹配,而后应用其配置
示例:
[root@centos7 images]#vim /etc/nginx/conf.d/vhost.conf
server{
listen 80;
server_name www.a.com;
location /images {
root /app/website2/;
}
}
curl www.a.com/images时访问你的是/app/website2/images目录
=:对URI做精确匹配;
location = / {
...
}
http://www.magedu.com/匹配
http://www.magedu.com/index.html 不匹配
^~:对URI的最左边部分做匹配检查,不区分字符大小写
~:对URI做正则表达式模式匹配,区分字符大小写
~*:对URI做正则表达式模式匹配,不区分字符大小写
不带符号:匹配起始于此uri的所有的uri
匹配优先级从高到低:
=, ^~, ~/~*, 不带符号,等号优先级最高,不带符号优先级最低
- alias path
路径别名,文档映射的另一种机制;仅能用于location上下文
示例:
location /bbs/ {
alias /app/website2/;
} -->http://www.a.com/bbs/映射的是访问磁盘这个目录 /app/website2/
location /bbs/ {
root /app/website1/;
} -->http://www.a.com/bbs/ 映射的是访问磁盘这个录下的文件/app/website1/bbs/
注意:location中使用root指令和alias指令的意义不同
vim /etc/nginx/conf.d/vhost.conf
server{
listen 80;
server_name www.a.com;
location /images {
alias /app/website2/;
}
}
curl www.a.com/images 时实际上访问的/app/website2目录下文件
- index file ...
指定默认网页资源,默认是index.html,注意:ngx_http_index_module模块
- error_page code ... [=[response]] uri
模块:ngx_http_core_module
定义错误页面,以指定的响应状态码进行响应
可用位置:http, server, location, if in location
error_page 404 /404.html
error_page 404 =200 /404.html
示例1
[root@centos7 website1]#vim /etc/nginx/conf.d/vhost.conf
server{
listen 80;
server_name www.a.com;
root /app/website1;
error_page 404 /404.html; --- 表示当你访问一个不存在的页面的时候,实际上访问的是404.html文件
location /images {
root /app/website2/;
}
location /404.html { 规定了404.html文件在哪,表示在/app/website1/errror目录下,如果没有规定这个location,就表示访问的是根下的404.html文件,而此时的根是/app/website1
root /app/website1/error/;
}
}
[root@centos7 images]#nginx -s reload
测试
[root@centos6 ~]#curl www.a.com/no.html
sorry,你访问的页面不存在
[root@centos6 ~]#curl -I www.a.com/no.html
HTTP/1.1 404 Not Found --当不加200的时候状态码返回的是404
Server: nginx
Date: Wed, 25 Oct 2017 02:58:22 GMT
Content-Type: text/html
Content-Length: 34
Connection: keep-alive
ETag: "59efe716-22"
示例2
vim /etc/nginx/conf.d/vhost.conf
server{
listen 80;
server_name www.a.com;
root /app/website1;
error_page 404 =200 /404.html;
location /images {
root /app/website2/;
}
location /404.html {
root /app/website1/error/;
}
}
[root@centos7 images]#nginx -s reload
为了防止错误页面被浏览器劫持,访问一个不存在的页面时不是自己定义的目录下的错误页面,而是浏览器的一个广告,可以定义一个=200,即使访问不存在的页面也返回正确的状态码,但访问的是自己定义的那个错误的页面
测试
[root@centos6 ~]#curl www.a.com/no.html
sorry,你访问的页面不存在
[root@centos6 ~]#curl -I www.a.com/no.html
HTTP/1.1 200 OK ---加上=200后状态码返回的是200,这样就不会被浏览器劫持,而是自己定义的错误页面
Server: nginx
Date: Wed, 25 Oct 2017 02:51:56 GMT
Content-Type: text/html
Content-Length: 34
Last-Modified: Wed, 25 Oct 2017 01:21:26 GMT
Connection: keep-alive
ETag: "59efe716-22"
Accept-Ranges: bytes
总结:location可以定义访问不同的目录有不同的根目录,用root和alias,定义错误页面时最好加上=200,不然很容易被浏览器劫持,尤其是360浏览器。
- try_files file ... uri
try_files file ... =code;
按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有的文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误
示例
[root@centos7 images]#vim /etc/nginx/conf.d/vhost.conf
server{
listen 80;
server_name www.a.com;
root /app/website1;
location /images {
root /app/website2/;
try_files $uri /images/default.jpg; --- $uri表示当前的uri路径,按顺序查找,如果都找不到,返回的是最后一个文件中的内容
}
[root@centos7 images]#nginx -s reload
[root@centos7 images]#cp /usr/share/pixmaps/faces/sky.jpg /app/website2/images/a.jpg
[root@centos7 images]#cp
/usr/share/pixmaps/faces/flower.jpg /app/website2/images/b.jpg
[root@centos7 images]#cp /usr/share/pixmaps/faces/sunset.jpg /app/website2/images/default.jpg
在浏览器测试
http://172.18.21.107/images/a.jpg
http://172.18.21.107/images/b.jpg
http://172.18.21.107/images/c.jpg ---访问前两个,因为目录下有这两个文件,就返回原文件,但访问c.jpg时因为目录下没有这个文件,返回的就是最后一个default.jpg文件中的内容,前提是最后一个文件要有
try_files $uri /images/default.jpg =404; ---可以在上面的内容增加一个=404,表示按照顺序查找要访问你的文件,如果都找不到,并且最后一个文件也没有,就返回404错误代码
[root@centos6 ~]#curl -I www.a.com/images/c.jpg
HTTP/1.1 404 Not Found ---返回的是404,如果不加上面=404会返回200
Server: nginx
Date: Wed, 25 Oct 2017 03:38:59 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
- 定义客户端请求的相关配置
1、keepalive_timeout timeout [header_timeout];
设定保持连接超时时长,0表示禁止长连接,默认为75s,可以在http、server、location设置都可以
2、keepalive_requests number;
在一次长连接上所允许请求的资源的最大数量,默认为100
3、keepalive_disable none | browser ...
对哪种浏览器禁用长连接
4、send_timeout time;
向客户端发送响应报文的超时时长,此处是指两次写操作之间的间隔时长,而非整个响应过程的传输时长
5 、client_body_buffer_size size;
用于接收每个客户端请求报文的body部分的缓冲区大小;默认为16k;超出此大小时,其将被暂存到磁盘上的由client_body_temp_path指令所定义的位置
6、client_body_temp_pathpath [level1 [level2 [level3]]];
设定用于存储客户端请求报文的body部分的临时存储路径及子目录结构和数量
目录名为16进制的数字;
client_body_temp_path/var/tmp/client_body1 2 2
1 1级目录占1位16进制,即2^4=16个目录0-f
2 2级目录占2位16进制,即2^8=256个目录00-ff
2 3级目录占2位16进制,即2^8=256个目录00-ff
- 对客户端进行限制的相关配置
1、limit_rate rate;
限制响应给客户端的传输速率,单位是bytes/second
默认值0表示无限制
2、limit_except method ... { ... },仅用于location
限制客户端使用除了指定的请求方法之外的其它方法
method:GET, HEAD, POST, PUT, DELETE
MKCOL, COPY, MOVE, OPTIONS, PROPFIND,
PROPPATCH, LOCK, UNLOCK, PATCH
limit_except GET {
allow 192.168.1.0/24;
deny all;
} 除了GET和HEAD之外其它方法仅允许192.168.1.0/24网段主机使用,GET包含HEAD,一个下载整个网页,一个是下载头部
- 文件操作优化的配置
1、aio on | off | threads[=pool];
是否启用aio功能
2、directio size | off;
是否同步(直接)写磁盘,而非写缓存,在Linux主机启用O_DIRECT标记,则文件大于等于给定大小时使用,例如directio4m
3、open_file_cache off;
open_file_cache max=N [inactive=time];
nginx可以缓存以下三种信息:
(1) 文件元数据:文件的描述符、文件大小和最近一次的修改时间
(2) 打开的目录结构
(3) 没有找到的或者没有权限访问的文件的相关信息
max=N:可缓存的缓存项上限;达到上限后会使用LRU算法实现管理
inactive=time:缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于open_file_cache_min_uses指令所指定的次数的缓存项即为非活动项,将被删除
4、open_file_cache_errors on | off;
是否缓存查找时发生错误的文件一类的信息,默认值为off
5、open_file_cache_min_uses number;
open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项
默认值为1
6、open_file_cache_valid time;
缓存项有效性的检查频率,默认值为60s
4、实现基于ip的访问控制
ngx_http_access_module模块
1、allow address | CIDR | unix: | all;
2、deny address | CIDR | unix: | all;
http, server, location, limit_except
自上而下检查,一旦匹配,将生效,条件严格的置前
示例
[root@centos7 images]#vim /etc/nginx/conf.d/vhost.conf
server{
listen 80;
server_name www.a.com;
root /app/website1;
location /images {
root /app/website2/;
deny 172.18.21.106;
allow 172.18.254.200;
}
}
nginx -s reload
表示允许172.18.254.200访问/app/website2/images,不允许172.18.21.106访问,但访问/app/website1/根目录是不受限制的
5、实现基于用户的访问控制
使用basic机制进行用户认证
ngx_http_auth_basic_module模块
示例
vim /etc/nginx/conf.d/vhost.conf
server{
listen 80;
server_name www.a.com;
root /app/website1;
location /images {
root /app/website2/;
auth_basic "admin area"; ---提示信息
auth_basic_user_file /etc/nginx/.ngxpasswd; ---指明存放用户名和密码的文件
}
}
nginx -s reload
cd /etc/nginx/
htpasswd -c -m .ngxpasswd http1 ---创建文件并指定用户
测试
在浏览器上访问http://172.18.21.107/images/,需要输入用户名密码才可以访问
6、显示nginx的基本状态信息
ngx_http_stub_status_module模块
示例
vim /etc/nginx/conf.d/vhost.conf
server{
listen 80;
server_name www.a.com;
root /app/website1;
location /status {
root /app/website2/;
stub_status;
allow 172.18.254.200;
deny all;
}
}
nginx -s reload
测试
Active connections:当前状态,活动状态的连接数
accepts:统计总值,已经接受的客户端请求的总数
handled:统计总值,已经处理完成的客户端请求的总数
requests:统计总值,客户端发来的总的请求数
Reading:当前状态,正在读取客户端请求报文首部的连接的连接数
Writing:当前状态,正在向客户端发送响应报文过程中的连接数
Waiting:当前状态,正在等待客户端发出请求的空闲连接数
7、指定日志格式
gx_http_log_module模块
示例
vim /etc/nginx/nginx.conf
log_format compression '$remote_addr-$remote_user[$time_local] '
'"$request" $status $bytes_sent'
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
注意:log_format只能放到主配置文件的http里
vim /etc/nginx/conf.d/vhost.conf
server{
listen 80 default_server;
server_name www.a.com;
root /app/website1;
access_log /var/log/nginx/nginx-com.log compression buffer=32k ; ---注意这里如果加上buffer=32k,访问的时候不会马上记录日志,会先缓存,等缓存达到32k时才会记录日志,练习时为了测试方便将这条去掉了,不然总是看不到日志里面有内容
}
nginx -t ---检查一下语法
nginx -s reload
测试
在客户端访问
发现在这个文件中/var/log/nginx/nginx-com.log已经开始记录日志了
总结:URL和URI
http://172.18.21.107/images/a.jpg整体叫URL
URI是/images/a.jpg
ctrl+f5是强制刷新,是刷新本地浏览器上的缓存