Nginx 新手起步
Nginx优点
- 处理响应请求很快
- 高并发连接
-
低的内存消耗
10000 个非活跃的 HTTP Keep-Alive 连接在 Nginx 中仅消耗 2.5MB 的内存
- 具有很高的可靠性
-
高扩展性
完全是由多个不同功能、不同层次、不同类型且耦合度极低的模块组成。这种设计造就了 Nginx 庞大的第三方模块
-
热部署
master 管理进程与 worker 工作进程的分离设计,使得 Nginx 具有热部署的功能 可以在 7 × 24 小时不间断服务的前提下,升级 Nginx 的可执行文件。 也可以在不停止服务的情况下修改配置文件,更换日志文件等功能。
-
自由的 BSD 许可协议
BSD 许可协议不只是允许用户免费使用 Nginx,也允许用户修改 Nginx 源码,还允许用户用于商业用途
使用 Nginx
安装
1 获取 Nginx
2 解压缩 nginx-xx.tar.gz 包
3 进入解压缩目录,执行 ./configure
4 make & make install
若安装时找不到上述依赖模块,使用 --with-openssl=<openssl_dir>、
--with-pcre=<pcre_dir>、--with-zlib=<zlib_dir> 指定依赖的模块目录
配置
配置目录 conf 下有以下配置文件
.
├── fastcgi.conf
├── fastcgi_params
├── koi-utf
├── koi-win
├── mime.types
├── nginx.conf
├── scgi_params
├── uwsgi_params
└── win-utf
除了 nginx.conf
,其余配置文件,一般只需要使用默认提供即可
nginx.conf
worker_process # 表示工作进程的数量,一般设置为cpu的核数
worker_connections # 表示每个工作进程的最大连接数
server{} # 块定义了虚拟主机
listen # 监听端口
server_name # 监听域名
location {} # 是用来为匹配的 URI 进行配置,URI 即语法中的“/uri/”
location /{} # 匹配任何查询,因为所有请求都以 / 开头
root # 指定对应uri的资源查找路径,这里html为相对路径,完整路径为
# /opt/nginx-1.7.7/html/
index # 指定首页index文件的名称,可以配置多个,以空格分开。如有多
# 个,按配置顺序查找。
location 匹配规则
语法规则
location [=|~|~*|^~] /uri/ { … }
模式 | 含义 |
---|---|
location = /uri |
= 表示精确匹配,只有完全匹配上才能生效 |
location ^~ /uri |
^ ^~ 开头对URL路径进行前缀匹配,并且在正则之前。 |
location ~ pattern |
开头表示区分大小写的正则匹配 |
location ~* pattern |
开头表示不区分大小写的正则匹配 |
location / |
通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default |
location /uri |
不带任何修饰符,也表示前缀匹配,但是在正则匹配之后 |
多个 location 配置的情况下匹配顺序
:
首先精确匹配 =
其次前缀匹配 ^~
其次是按文件中顺序的正则匹配
然后匹配不带任何修饰的前缀匹配。
最后是交给 / 通用匹配
当有匹配成功时候,停止匹配,按当前匹配规则处理请求
匹配实例
location = / {
echo "规则A";
}
location = /login {
echo "规则B";
}
location ^~ /static/ {
echo "规则C";
}
location ^~ /static/files {
echo "规则X";
}
location ~ \.(gif|jpg|png|js|css)$ {
echo "规则D";
}
location ~* \.png$ {
echo "规则E";
}
location /img {
echo "规则Y";
}
location / {
echo "规则F";
}
访问根目录 /,比如 http://localhost/ 将匹配 规则A
访问 http://localhost/login 将匹配 规则B,http://localhost/register 则匹配 规则F
访问 http://localhost/static/a.html 将匹配 规则C
访问 http://localhost/static/files/a.exe 将匹配 规则X,虽然 规则C 也能匹配到,但因为最大匹配原则,最终选中了 规则X。你可以测试下,去掉规则 X ,则当前 URL 会匹配上 规则C。
访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配 规则D 和 规则 E ,但是 规则 D 顺序优先,规则 E 不起作用,而 http://localhost/static/c.png 则优先匹配到 规则 C
访问 http://localhost/a.PNG 则匹配 规则 E ,而不会匹配 规则 D ,因为 规则 E 不区分大小写。
访问 http://localhost/img/a.gif 会匹配上 规则D,虽然 规则Y 也可以匹配上,但是因为正则匹配优先,而忽略了 规则Y。
访问 http://localhost/img/a.tiff 会匹配上 规则Y。
访问 http://localhost/category/id/1111 则最终匹配到规则 F
因为以上规则都不匹配,这个时候应该是 Nginx 转发请求给后端应用服务器,比如 FastCGI(php),tomcat(jsp)
Nginx 作为反向代理服务器存在。
前缀匹配,如果有包含关系时,按最大匹配原则进行匹配。
location /dir01 与 location /dir01/dir02,如有请求 http://localhost/dir01/dir02/file 将最终匹配到 location /dir01/dir02
location实际应用
# 直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
# 这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是 nginx 作为 http 服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
# 第三个规则就是通用规则,用来转发动态请求到后端应用服务器
# 非静态文件请求就默认是动态请求,自己根据实际把握
# 毕竟目前的一些框架的流行,带.php、.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/
}
rewrite
语法
last – 基本上都用这个 flag
break – 中止 rewrite,不再继续匹配
redirect – 返回临时重定向的 HTTP 状态 302
permanent – 返回永久重定向的 HTTP 状态 301
可以用来判断的表达式
-f 和 !-f 用来判断是否存在文件
-d 和 !-d 用来判断是否存在目录
-e 和 !-e 用来判断是否存在文件或目录
-x 和 !-x 用来判断文件是否可执行
可以用作判断的全局变量
例:http://localhost:88/test1/test2/test.php?k=v
$host:localhost
$server_port:88
$request_uri:/test1/test2/test.php?k=v
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php
redirect
语法
server {
listen 80;
server_name start.igrow.cn;
index index.html index.php;
root html;
if ($http_host !~ "^star\.igrow\.cn$") {
rewrite ^(.*) http://star.igrow.cn$1 redirect;
}
}
防盗链
location ~* \.(gif|jpg|swf)$ {
valid_referers none blocked start.igrow.cn sta.igrow.cn;
if ($invalid_referer) {
rewrite ^/ http://$host/logo.png;
}
}
根据文件类型设置过期时间
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
expires 1h;
break;
}
}
禁止访问
禁止访问某个目录
location ~* \.(txt|doc)${
root /data/www/wwwroot/linuxtone/test;
deny all;
}
Nginx 静态文件
服务
http {
# 这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,
# 建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。
open_file_cache max=204800 inactive=20s;
# open_file_cache 指令中的inactive 参数时间内文件的最少使用次数,
# 如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个
# 文件在inactive 时间内一次没被使用,它将被移除。
open_file_cache_min_uses 1;
# 这个是指多长时间检查一次缓存的有效信息
open_file_cache_valid 30s;
# 默认情况下,Nginx的gzip压缩是关闭的, gzip压缩功能就是可以让你节省不
# 少带宽,但是会增加服务器CPU的开销哦,Nginx默认只对text/html进行压缩 ,
# 如果要对html之外的内容进行压缩传输,我们需要手动来设置。
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
server {
listen 80;
server_name www.test.com;
charset utf-8;
root /data/www.test.com;
index index.html index.htm;
}
}
实现和调整应用栈(application stack)的缓存
提高终端用户的体验
-
文件缓存
一个 web 缓存坐落于客户端和原始服务器(origin server)中间,它保留了所有可见内容的拷贝。 如果一个客户端请求的内容在缓存中存储,则可以直接在缓存中获得该内容而不需要与服务器通信。 这样一来,由于 web 缓存距离客户端“更近”,就可以提高响应性能,并更有效率的使用应用服务器, 因为服务器不用每次请求都进行页面生成工作。
在浏览器和应用服务器之间,存在多种潜在缓存,如:客户端浏览器缓存、中间缓存、内容分发网络(CDN)和服务器上的负载平衡和反向代理。
缓存,仅在反向代理和负载均衡的层面,就对性能提高有很大的帮助
安装和配置基础缓存
proxy_cache_path
用来设置缓存的路径和配置
proxy_cache
用来启用缓存
proxy_cache_path/path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m
use_temp_path=off;
server {
...
location / {
proxy_cache my_cache;
proxy_pass http://my_upstream;
}
}
proxy_cache_path
用于缓存的本地磁盘目录是 /path/to/cache/
levels 在 /path/to/cache/ 设置了一个两级层次结构的目录。将大量的文件放置在单个目录中会导致文件访问缓慢,
所以针对大多数部署,我们推荐使用两级目录层次结构。如果 levels 参数没有配置,则 Nginx 会将所有的文件放到同一个目录中。
keys_zone 设置一个共享内存区,该内存区用于存储缓存键和元数据,有些类似计时器的用途。
将键的拷贝放入内存可以使 Nginx 在不检索磁盘的情况下快速决定一个请求是 HIT 还是 MISS,
这样大大提高了检索速度。一个 1MB 的内存空间可以存储大约 8000 个 key,
那么上面配置的 10MB 内存空间可以存储差不多 80000 个 key。
max_size 设置了缓存的上限(在上面的例子中是 10G)。这是一个可选项;如果不指定具体值,
那就是允许缓存不断增长,占用所有可用的磁盘空间。当缓存达到这个上限,
处理器便调用 cache manager 来移除最近最少被使用的文件,这样把缓存的空间降低至这个限制之下。
inactive 指定了项目在不被访问的情况下能够在内存中保持的时间。在上面的例子中,
如果一个文件在 60 分钟之内没有被请求,则缓存管理将会自动将其在内存中删除,不管该文件是否过期。
该参数默认值为 10 分钟(10m)。注意,非活动内容有别于过期内容。
Nginx 不会自动删除由缓存控制头部指定的过期内容(本例中 Cache-Control:max-age=120)。
过期内容只有在 inactive 指定时间内没有被访问的情况下才会被删除。如果过期内容被访问了,
那么 Nginx 就会将其从原服务器上刷新,并更新对应的 inactive 计时器。
Nginx 最初会将注定写入缓存的文件先放入一个临时存储区域,use_temp_path=off 命令指示 Nginx 将在缓存这些文件时将它们写入同一个目录下。
我们强烈建议你将参数设置为 off 来避免在文件系统中不必要的数据拷贝。
缓存微调
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m
use_temp_path=off;
server {
...
location / {
proxy_cache my_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 3;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
proxy_pass http://my_upstream;
}
}
proxy_cache_revalidate 指示 Nginx 在刷新来自服务器的内容时使用 GET 请求。如果客户端的请求项已经被缓存过了,但是在缓存控制头部中定义为过期,
那么 Nginx 就会在 GET 请求中包含 If-Modified-Since 字段,发送至服务器端。这项配置可以节约带宽,
因为对于 Nginx 已经缓存过的文件,服务器只会在该文件请求头中 Last-Modified 记录的时间内被修改时才将全部文件一起发送。
proxy_cache_min_uses 该指令设置同一链接请求达到几次即被缓存,默认值为 1 。当缓存不断被填满时,这项设置便十分有用,
因为这确保了只有那些被经常访问的内容会被缓存。
proxy_cache_use_stale 中的 updating 参数告知 Nginx 在客户端请求的项目的更新正在原服务器中下载时发送旧内容,
而不是向服务器转发重复的请求。第一个请求陈旧文件的用户不得不等待文件在原服务器中更新完毕。
陈旧的文件会返回给随后的请求直到更新后的文件被全部下载。
当 proxy_cache_lock 被启用时,当多个客户端请求一个缓存中不存在的文件(或称之为一个 MISS),
只有这些请求中的第一个被允许发送至服务器。
其他请求在第一个请求得到满意结果之后在缓存中得到文件。
如果不启用 proxy_cache_lock,则所有在缓存中找不到文件的请求都会直接与服务器通信
日志
Nginx 日志主要有两种:access_log(访问日志)
和 error_log(错误日志)
access_log 访问日志
通过 access_log
你可以得到用户地域来源、跳转来源、使用终端、某个 URL 访问量等相关信息
log_format myformat '$remote_addr $status $time_local';
access_log logs/access.log myformat;
log_format name string
name 表示格式名称,
string 表示定义的格式字符串
access_log path [format_name [buffer=size | off]]
path 表示访问日志存放路径
format_name 表示访问日志格式名称
buffer 表示缓存大小
off 表示关闭访问日志
字段 | 作用 |
---|---|
$remote_addr与$http_x_forwarded_for |
记录客户端IP地址 |
$remote_user |
记录客户端用户名称 |
$request |
记录请求的URI和HTTP协议 |
$status |
记录请求状态 |
$body_bytes_sent |
发送给客户端的字节数,不包括响应头的大小 |
$bytes_sent |
发送给客户端的总字节数 |
$connection |
连接的序列号 |
$connection_requests |
当前通过一个连接获得的请求数量 |
$msec |
日志写入时间。单位为秒,精度是毫秒 |
$pipe |
如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.” |
$http_referer |
记录从哪个页面链接访问过来的 |
$http_user_agent |
记录客户端浏览器相关信息 |
$request_length |
请求的长度(包括请求行,请求头和请求正文) |
$request_time |
请求处理时间,单位为秒,精度毫秒 |
$time_iso8601 |
ISO8601标准格式下的本地时间 |
$time_local |
记录访问时间与时区 |
注意:
log_format 配置必须放在 http 内 否则会出现警告
Nginx 进程设置的用户和组必须对日志路径有创建文件的权限,否则会报错
error_log 错误日志
error_log
主要记录客户端访问 Nginx 出错时的日志,格式不支持自定义
error_log path [level]
path 表示错误日志存放路径
level 表示错误日志等级
日志等级包括 debug、info、notice、warn、error、crit、alert、emerg
从左至右,日志详细程度逐级递减,即 debug 最详细,emerg 最少,默认为 error
注意:error_log off 并不能关闭错误日志记录,此时日志信息会被写入到文件名为 off |
的文件 |
Linux 系统把存储位置设置为空设备
error_log /dev/null;
http {
# ...
}
反向代理
反向代理(Reverse Proxy)
是指用代理服务器来接受 internet 上的连接请求, 然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端, 此时代理服务器对外就表现为一个反向代理服务器
nginx.conf 配置示例:
worker_processes 1;
pid logs/nginx.pid;
error_log logs/error.log warn;
events {
worker_connections 3000;
}
http {
include mime.types;
server_tokens off;
## 下面配置反向代理的参数
server {
listen 8866;
## 1. 用户访问 http://ip:port,则反向代理到 https://github.com
location / {
proxy_pass https://github.com;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
## 2.用户访问 http://ip:port/README.md,则反向代理到
## https://github.com/.../README.md
location /README.md {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://github.com/moonbingbing/openresty-best-practices/blob/master/README.md;
}
}
}
正向代理
正向代理
就像一个跳板,例如一个用户访问不了某网站(例如 www.google.com),
但是他能访问一个代理服务器,这个代理服务器能访问 www.google.com,于是用户可以先连上代理服务器,
告诉它需要访问的内容,代理服务器去取回来返回给用户。
例如一些常见的翻墙工具
、游戏代理
就是利用正向代理的原理工作的,我们需要在这些正向代理工具上配置服务器的 IP 地址等信息。
负载均衡
负载均衡(Load balancing)
是一种计算机网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,
以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。
upstream
负载均衡概要
upstream test.net{
ip_hash;
server 192.168.10.13:80;
server 192.168.10.14:80 down;
server 192.168.10.15:8009 max_fails=3 fail_timeout=20s;
server 192.168.10.16:8080;
}
server {
location / {
proxy_pass http://test.net;
}
}
upstream
是 Nginx 的 HTTP Upstream
模块,这个模块通过一个简单的调度算法来实现客户端 IP
到后端服务器的负载均衡
。
在上面的设定中,通过 upstream 指令指定了一个负载均衡器
的名称 test.net
。这个名称可以任意指定,在后面需要用到的地方直接调用即可
upstream 支持的状态参数
down:
表示当前的 server 暂时不参与负载均衡。
backup:
预留的备份机器。
当其他所有的非 backup 机器出现故障或者忙的时候,才会请求 backup 机器,因此这台机器的压力最轻。
max_fails:
允许请求失败的次数,默认为 1 。
当超过最大次数时,返回 proxy_next_upstream 模块定义的错误。
fail_timeout:
在经历了 max_fails 次失败后,暂停服务的时间。
max_fails 可以和 fail_timeout 一起使用。
注意:
当负载调度算法为 ip_hash
时,后端服务器在负载均衡调度中的状态不能是 backup
upstream 支持的负载均衡算法
1 轮询(默认):
每个请求按时间顺序逐一分配到不同的后端服务器
如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。
Weight 指定轮询权, 值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。
2 ip_hash:
每个请求按访问 IP 的 hash 结果分配,这样来自同一个 IP 的访客固定访问一个后端服务器,
有效解决了动态网页存在的 session 共享问题。
3 fair:
这是比上面两个更加智能的负载均衡算法。
此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,
也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。
Nginx 本身是不支持 fair 的,如果需要使用这种调度算法,必须下载 Nginx 的 upstream_fair 模块。
4 url_hash:
此方法按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,
可以进一步提高后端缓存服务器的效率。
Nginx 本身是不支持 url_hash 的,如果需要使用这种调度算法,必须安装 Nginx 的 hash 软件包。
5 least_conn:
最少连接负载均衡算法,简单来说就是每次选择的后端都是当前最少连接的一个 server(这个最少连接不是共享的,是每个 worker 都有自己的一个数组进行记录后端 server 的连接数)。
6 hash:
这个 hash 模块又支持两种模式 hash, 一种是普通的 hash, 另一种是一致性 hash(consistent)。
配置负载均衡
upstream
是定义在 server{ } 之外
的,不能定义在 server{ }
内部。
定义好 upstream
之后,用 proxy_pass
引用一下即可
upstream webservers {
server 192.168.18.201 weight=1;
server 192.168.18.202 weight=1;
server 192.168.18.202 backup;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://webservers;
proxy_set_header X-Real-IP $remote_addr;
}
}