目录
一、安装Nginx:
1 : wget下载: http://nginx.org/download/nginx-1.4.2.tar.gz
2 : 进行安装: tar -zxvf nginx-1.6.2.tar.gz
3 : 下载锁需要的依赖库文件:
yum install pcre
yum install pcre-devel
yum install zlib
yum install zlib-devel
4 : 进行configure配置:cd nginx-1.6.2 && ./configure --prefix=/usr/local/nginx 查看是否报错
5 : 编译安装 make && make install
6 : 启动Nginx:
cd /usr/local/nginx目录下: 看到如下4个目录
....conf 配置文件
... html 网页文件
...logs 日志文件
...sbin 主要二进制程序
启动命令:/usr/local/nginx/sbin/nginx -s start 关闭(stop)重启(reload)
成功:查看是否启动(netstat -ano | grep 80)
失败:可能为80端口被占用等。
最终:浏览器访问地址:http://192.168.1.172:80 (看到欢迎页面即可
二、使用Nginx:简单与单台Tomcat整合
首先找到nginx.conf文件:vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost:80;
location / {
proxy_pass http://localhost:8080;
}
//...others
}
三、详细使用(nginx就是去配置其文件而已),如下所示:
1、常用命令
# 开机配置
systemctl enable nginx # 开机自动启动
systemctl disable nginx # 关闭开机自动启动
# 启动Nginx
systemctl start nginx # 启动Nginx成功后,可以直接访问主机IP,此时会展示Nginx默认页面
# 停止Nginx
systemctl stop nginx
# 重启Nginx
systemctl restart nginx
# 重新加载Nginx
systemctl reload nginx
# 查看 Nginx 运行状态
systemctl status nginx
# 查看Nginx进程
ps -ef | grep nginx
# 杀死Nginx进程
kill -9 pid # 根据上面查看到的Nginx进程号,杀死Nginx进程,-9 表示强制结束进程
# nginx命令
nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启
nginx -s reopen # 重启 Nginx
nginx -s stop # 快速关闭
nginx -s quit # 等待工作进程处理完成后关闭
nginx -T # 查看当前 Nginx 最终的配置
nginx -t # 检查配置是否有问题
2、分段配置详解
-
main
全局配置,对全局生效; -
events
配置影响Nginx
服务器与用户的网络连接; -
http
配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置; -
server
配置虚拟主机的相关参数,一个http
块中可以有多个server
块; -
location
用于配置匹配的uri
; -
upstream
配置后端服务器具体地址,负载均衡配置不可或缺的部分;
# main段配置信息
user nginx; # 运行用户,默认即是nginx,可以不进行设置user USERNAME [GROUP]
worker_processes auto; # Nginx 子进程数,一般设置为和 CPU 核数一样
error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录
pid /var/run/nginx.pid; # Nginx 服务启动时 Nginx master 主进程的 pid 存放位置
worker_rlimit_nofile 20480; # 可以理解成每个worker子进程的最大连接数量。
worker_rlimit_core 50M; # 存放大小限制 指定 worker 子进程异常终止后的 core 文件,用于记录分析问题。
working_directory /opt/nginx/tmp; # 存放目录
worker_cpu_affinity 0001 0010 0100 1000; # 4个物理核心,4个worker子进程 将每个 worker 子进程与我们的 cpu 物理核心绑定。
# Linux 默认进程的优先级值是120,值越小越优先; nice 定范围为 -20 到 +19 。
worker_priority -10; # 120-10=110,110就是最终的优先级
worker_shutdown_timeout 5s; # 指定 worker 子进程优雅退出时的超时时间。
timer_resolution 100ms; # worker 子进程内部使用的计时器精度,调整时间间隔越大,系统调用越少,有利于性能提升;反之,系统调用越多,性能下降。
daemon off; # 默认是on,后台运行模式 指定 Nginx 的运行方式,前台还是后台,前台用于调试,后台用于生产。
# events段配置信息
events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)method 可选值为:select、poll、kqueue、epoll、/dev/poll、eventport
worker_connections 1024; # 每个子进程允许最大并发数
accept_mutex on # 是否打开负载均衡互斥锁。默认是off关闭的,这里推荐打开
}
# http段配置信息
# 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
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; # Nginx访问日志存放位置
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段配置信息
server {
listen 80; # 配置监听的端口
server_name localhost; # 配置的域名 # 支持正则
# location段配置信息
# = 精确匹配;~ 正则匹配,区分大小写;~* 正则匹配,不区分大小写;^~ 匹配到即停止搜索;匹配优先级: = > ^~ > ~ > ~* > 不带任何字符。
location / {
root /usr/share/nginx/html; # 指定静态资源目录位置,它可以写在 http 、 server 、 location 等配置中。
alias /opt/nginx/static/image/; # 也是指定静态资源目录位置,使用 alias 末尾一定要添加 / ,并且它只能位于 location 中。
index index.html index.htm; # 默认首页文件
deny 172.168.22.11; # 禁止访问的ip地址,可以为all
allow 172.168.33.44;# 允许访问的ip地址,可以为all
}
error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面
error_page 400 404 error.html; # 同上
}
}
3、server_name
指定虚拟主机域名。
server_name name1 name2 name3
# 示例:
server_name www.nginx.com;域名匹配的四种写法:
精确匹配:
server_name www.nginx.com
;左侧通配:
server_name *.nginx.com
;右侧统配:
server_name www.nginx.*
;正则匹配:
server_name ~^www\.nginx\.*$
;匹配优先级:精确匹配 > 左侧通配符匹配 > 右侧通配符匹配 > 正则表达式匹配
4、location
配置路径。
匹配规则:
-
=
精确匹配; -
~
正则匹配,区分大小写; -
~*
正则匹配,不区分大小写; -
^~
匹配到即停止搜索;
匹配优先级: =
> ^~
> ~
> ~*
> 不带任何字符。
实例:
server {
listen 80;
server_name www.nginx-test.com;
# 只有当访问 www.nginx-test.com/match_all/ 时才会匹配到/usr/share/nginx/html/match_all/index.html
location = /match_all/ {
root /usr/share/nginx/html
index index.html
}
# 当访问 www.nginx-test.com/1.jpg 等路径时会去 /usr/share/nginx/images/1.jpg 找对应的资源
location ~ \.(jpeg|jpg|png|svg)$ {
root /usr/share/nginx/images;
}
# 当访问 www.nginx-test.com/bbs/ 时会匹配上 /usr/share/nginx/html/bbs/index.html
location ^~ /bbs/ {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
#不带 / 当访问 www.nginx-test.com/test 时, Nginx 先找是否有 test 目录,如果有则找 test 目录下的 index.html ;如果没有 test 目录, nginx 则会找是否有 test 文件。
#带 / 当访问 www.nginx-test.com/test 时, Nginx 先找是否有 test 目录,如果有则找 test 目录下的 index.html ,如果没有它也不会去找是否存在 test 文件。
location /test {
...
}
location /test/ {
...
}
5、return机制
停止处理请求,直接返回响应码或重定向到其他 URL
;执行 return
指令后, location
中后续指令将不会被执行。
return code [text];
return code URL;
return URL;
例如:
location / {
return 404; # 直接返回状态码
}
location / {
return 404 "pages not found"; # 返回状态码 + 一段文本
}
location / {
return 302 /bbs ; # 返回状态码 + 重定向地址
}
location / {
return https://www.baidu.com ; # 返回重定向地址
}
6、rewrite机制
根据指定正则表达式匹配规则,重写 URL
。
语法:rewrite 正则表达式 要替换的内容 [flag];
上下文:server、location、if
示例:rewirte /images/(.*\.jpg)$ /pic/$1; # $1是前面括号(.*\.jpg)的反向引用
flag
可选值的含义:
-
last
重写后的URL
发起新请求,再次进入server
段,重试location
的中的匹配; -
break
直接使用重写后的URL
,不再匹配其它location
中语句; -
redirect
返回302临时重定向; -
permanent
返回301永久重定向;
按照这个配置我们来分析:
当访问 fe.lion.club/search 时,会自动帮我们重定向到 https://www.baidu.com。
当访问 fe.lion.club/images/1.jpg 时,第一步重写 URL 为 fe.lion.club/pics/1.jpg ,找到 pics 的 location ,继续重写 URL 为 fe.lion.club/photos/1.jpg ,找到 /photos 的 location 后,去 html/photos 目录下寻找 1.jpg 静态资源。
server{
listen 80;
server_name fe.lion.club; # 要在本地hosts文件进行配置
root html;
location /search {
rewrite ^/(.*) https://www.baidu.com redirect;
}
location /images {
rewrite /images/(.*) /pics/$1;
}
location /pics {
rewrite /pics/(.*) /photos/$1;
}
location /photos {
}
}
7、if 指令
语法:if (condition) {...}
上下文:server、location
示例:
if($http_user_agent ~ Chrome){
rewrite /(.*)/browser/$1 break;
}
# 当访问 localhost:8080/images/ 时,会进入 if 判断里面执行 rewrite 命令。
server {
listen 8080;
server_name localhost;
root html;
location / {
if ( $uri = "/images/" ){
rewrite (.*) /pics/ break;
}
}
}
condition
判断条件:
-
$variable
仅为变量时,值为空或以0开头字符串都会被当做false
处理; -
=
或!=
相等或不等; -
~
正则匹配; -
! ~
非正则匹配; -
~*
正则匹配,不区分大小写; -
-f
或! -f
检测文件存在或不存在; -
-d
或! -d
检测目录存在或不存在; -
-e
或! -e
检测文件、目录、符号链接等存在或不存在; -
-x
或! -x
检测文件可以执行或不可执行;
8、autoindex
用户请求以 /
结尾时,列出目录结构,可以用于快速搭建静态资源下载网站。
autoindex.conf
配置信息:
server {
listen 80;
server_name fe.lion-test.club;
location /download/ {
root /opt/source;
autoindex on; # 打开 autoindex,,可选参数有 on | off
autoindex_exact_size on; # 修改为off,以KB、MB、GB显示文件大小,默认为on,以bytes显示出⽂件的确切⼤⼩
autoindex_format html; # 以html的方式进行格式化,可选参数有 html | json | xml
autoindex_localtime off; # 显示的⽂件时间为⽂件的服务器时间。默认为off,显示的⽂件时间为GMT时间
}
}
当访问 fe.lion.com/download/
时,会把服务器 /opt/source/download/
路径下的文件展示出来。
9、变量
Nginx
提供给使用者的变量非常多,但是终究是一个完整的请求过程所产生数据, Nginx
将这些数据以变量的形式提供给使用者。
下面列举些项目中常用的变量:
实例演示 var.conf
:
server{
listen 8081;
server_name var.lion-test.club;
root /usr/share/nginx/html;
location / {
return 200 "
remote_addr: $remote_addr
remote_port: $remote_port
server_addr: $server_addr
server_port: $server_port
server_protocol: $server_protocol
binary_remote_addr: $binary_remote_addr
connection: $connection
uri: $uri
request_uri: $request_uri
scheme: $scheme
request_method: $request_method
request_length: $request_length
args: $args
arg_pid: $arg_pid
is_args: $is_args
query_string: $query_string
host: $host
http_user_agent: $http_user_agent
http_referer: $http_referer
http_via: $http_via
request_time: $request_time
https: $https
request_filename: $request_filename
document_root: $document_root
";
}
}
当我们访问 http://var.lion-test.club:8081/test?pid=121414&cid=sadasd
时,由于 Nginx
中写了 return
方法,因此 chrome
浏览器会默认为我们下载一个文件,下面展示的就是下载的文件内容:
remote_addr: 27.16.220.84
remote_port: 56838
server_addr: 172.17.0.2
server_port: 8081
server_protocol: HTTP/1.1
binary_remote_addr: 茉
connection: 126
uri: /test/
request_uri: /test/?pid=121414&cid=sadasd
scheme: http
request_method: GET
request_length: 518
args: pid=121414&cid=sadasd
arg_pid: 121414
is_args: ?
query_string: pid=121414&cid=sadasd
host: var.lion-test.club
http_user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
http_referer:
http_via:
request_time: 0.000
https:
request_filename: /usr/share/nginx/html/test/
document_root: /usr/share/nginx/html
Nginx
的配置还有非常多,以上只是罗列了一些常用的配置,在实际项目中还是要学会查阅文档。
10、upstream
用于定义上游服务器(指的就是后台提供的应用服务器)的相关信息。
语法:upstream name {
...
}
上下文:http
示例:
upstream back_end_server{
server 192.168.100.33:8081
}
在 upstream
内可使用的指令:
-
server
定义上游服务器地址; -
zone
定义共享内存,用于跨worker
子进程; -
keepalive
对上游服务启用长连接; -
keepalive_requests
一个长连接最多请求HTTP
的个数; -
keepalive_timeout
空闲情形下,一个长连接的超时时长; -
hash
哈希负载均衡算法; -
ip_hash
依据IP
进行哈希计算的负载均衡算法; -
least_conn
最少连接数负载均衡算法; -
least_time
最短响应时间负载均衡算法; -
random
随机负载均衡算法;
server定义上游服务器地址。
语法:server address [parameters]
上下文:upstream
parameters
可选值:
-
weight=number
权重值,默认为1; -
max_conns=number
上游服务器的最大并发连接数; -
fail_timeout=time
服务器不可用的判定时间; -
max_fails=numer
服务器不可用的检查次数; -
backup
备份服务器,仅当其他服务器都不可用时才会启用; -
down
标记服务器长期不可用,离线维护;
11、proxy_pass代理
用于配置代理服务器。
语法:proxy_pass URL;
上下文:location、if、limit_except
示例:
proxy_pass http://127.0.0.1:8081
proxy_pass http://127.0.0.1:8081/proxy
URL
参数原则
-
URL
必须以http
或https
开头; -
URL
中可以携带变量; -
URL
中是否带URI
,会直接影响发往上游请求的URL
;
接下来让我们来看看两种常见的 URL
用法:
-
proxy_pass http://192.168.100.33:8081
-
proxy_pass http://192.168.100.33:8081/
这两种用法的区别就是带 /
和不带 /
,在配置代理时它们的区别可大了:
-
不带
/
意味着Nginx
不会修改用户URL
,而是直接透传给上游的应用服务器; -
带
/
意味着Nginx
会修改用户URL
,修改方法是将location
后的URL
从用户URL
中删除;
不带 /
的用法:
location /bbs/{
proxy_pass http://127.0.0.1:8080;
}
分析:
-
用户请求
URL
:/bbs/abc/test.html
-
请求到达
Nginx
的URL
:/bbs/abc/test.html
-
请求到达上游应用服务器的
URL
:/bbs/abc/test.html
带 /
的用法:
location /bbs/{
proxy_pass http://127.0.0.1:8080/;
}
分析:
-
用户请求
URL
:/bbs/abc/test.html
-
请求到达
Nginx
的URL
:/bbs/abc/test.html
-
请求到达上游应用服务器的
URL
:/abc/test.html
并没有拼接上 /bbs
,这点和 root
与 alias
之间的区别是保持一致的。
12、配置反向代理
# /etc/nginx/conf.d/proxy.conf
upstream back_end {
server 121.42.11.34:8080 weight=2 max_conns=1000 fail_timeout=10s max_fails=3;
keepalive 32;
keepalive_requests 80;
keepalive_timeout 20s;
}
server {
listen 80;
server_name proxy.lion.club;
location /proxy {
proxy_pass http://back_end/proxy;
}
}
分析:
-
当访问
proxy.lion.club/proxy
时通过upstream
的配置找到121.42.11.34:8080
; -
因此访问地址变为
http://121.42.11.34:8080/proxy
; -
连接到
121.42.11.34
服务器,找到8080
端口提供的server
; -
通过
server
找到/usr/share/nginx/html/proxy/index.html
资源,最终展示出来。
13、配置负载均衡
配置负载均衡主要是要使用 upstream
指令。
我们把 121.42.11.34
服务器作为上游服务器,做如下配置( /etc/nginx/conf.d/balance.conf
):
server{
listen 8020;
location / {
return 200 'return 8020 \n';
}
}
server{
listen 8030;
location / {
return 200 'return 8030 \n';
}
}
server{
listen 8040;
location / {
return 200 'return 8040 \n';
}
}
配置完成后:
-
nginx -t
检测配置是否正确; -
nginx -s reload
重启Nginx
服务器; -
执行
ss -nlt
命令查看端口是否被占用,从而判断Nginx
服务是否正确启动。
把 121.5.180.193
服务器作为代理服务器,做如下配置( /etc/nginx/conf.d/balance.conf
):
upstream demo_server {
server 121.42.11.34:8020;
server 121.42.11.34:8030;
server 121.42.11.34:8040;
}
server {
listen 80;
server_name balance.lion.club;
location /balance/ {
proxy_pass http://demo_server;
}
}
配置完成后重启 Nginx
服务器。并且在需要访问的客户端配置好 ip
和域名的映射关系。
在客户端机器执行 curl http://balance.lion.club/balance/
命令:
不难看出,负载均衡的配置已经生效了,每次给我们分发的上游服务器都不一样。就是通过简单的轮询策略进行上游服务器分发。
14、负载均衡策略
#通过制定关键字作为 hash key ,基于 hash 算法映射到特定的上游服务器中。关键字可以包含有变量、字符串。
#hash $request_uri 表示使用 request_uri 变量作为 hash 的 key 值,只要访问的 URI 保持不变,就会一直分发给同一台服务器。
upstream demo_server {
hash $request_uri;
server 121.42.11.34:8020;
server 121.42.11.34:8030;
server 121.42.11.34:8040;
}
# 根据客户端的请求 ip 进行判断,只要 ip 地址不变就永远分配到同一台主机。它可以有效解决后台服务器 session 保持的问题。
upstream demo_server {
ip_hash;
server 121.42.11.34:8020;
server 121.42.11.34:8030;
server 121.42.11.34:8040;
}
# 各个 worker 子进程通过读取共享内存的数据,来获取后端服务器的信息。来挑选一台当前已建立连接数最少的服务器进行分配请求。
upstream demo_server {
zone test 10M; # zone可以设置共享内存空间的名字和大小
least_conn; # 最小连接数
server 121.42.11.34:8020;
server 121.42.11.34:8030;
server 121.42.11.34:8040;
}
15、配置缓存
proxy_cache
存储一些之前被访问过、而且可能将要被再次访问的资源,使用户可以直接从代理服务器获得,从而减少上游服务器的压力,加快整个访问速度。
语法:proxy_cache zone | off ; # zone 是共享内存的名称
默认值:proxy_cache off;
上下文:http、server、location
proxy_cache_path
设置缓存文件的存放路径。
语法:proxy_cache_path path [level=levels] ...可选参数省略,下面会详细列举
默认值:proxy_cache_path off
上下文:http
参数含义:
path 缓存文件的存放路径;
level path 的目录层级;
keys_zone 设置共享内存;
inactive 在指定时间内没有被访问,缓存会被清理,默认10分钟;
proxy_cache_key
设置缓存文件的 key 。
语法:proxy_cache_key
默认值:proxy_cache_key $scheme$proxy_host$request_uri;
上下文:http、server、location
proxy_cache_valid
配置什么状态码可以被缓存,以及缓存时长。
语法:proxy_cache_valid [code...] time;
上下文:http、server、location
配置示例:proxy_cache_valid 200 304 2m;; # 说明对于状态为200和304的缓存文件的缓存时间是2分钟
proxy_no_cache
定义相应保存到缓存的条件,如果字符串参数的至少一个值不为空且不等于“ 0”,则将不保存该响应到缓存。
语法:proxy_no_cache string;
上下文:http、server、location
示例:proxy_no_cache $http_pragma $http_authorization;
proxy_cache_bypass
定义条件,在该条件下将不会从缓存中获取响应。
语法:proxy_cache_bypass string;
上下文:http、server、location
示例:proxy_cache_bypass $http_pragma $http_authorization;
upstream_cache_status 变量
它存储了缓存是否命中的信息,会设置在响应头信息中,在调试中非常有用。
MISS: 未命中缓存
HIT: 命中缓存
EXPIRED: 缓存过期
STALE: 命中了陈旧缓存
REVALIDDATED: Nginx验证陈旧缓存依然有效
UPDATING: 内容陈旧,但正在更新
BYPASS: X响应从原始服务器获取
配置示例:
proxy_cache_path /etc/nginx/cache_temp levels=2:2 keys_zone=cache_zone:30m max_size=2g inactive=60m use_temp_path=off;
upstream cache_server{
server 121.42.11.34:1010;
server 121.42.11.34:1020;
}
server {
listen 80;
server_name cache.lion.club;
location / {
proxy_cache cache_zone; # 设置缓存内存,上面配置中已经定义好的
proxy_cache_valid 200 5m; # 缓存状态为200的请求,缓存时长为5分钟
proxy_cache_key $request_uri; # 缓存文件的key为请求的URI
add_header Nginx-Cache-Status $upstream_cache_status # 把缓存状态设置为头部信息,响应给客户端
proxy_pass http://cache_server; # 代理转发
}
}
缓存就是这样配置,我们可以在 /etc/nginx/cache_temp 路径下找到相应的缓存文件。
「对于一些实时性要求非常高的页面或数据来说,就不应该去设置缓存,下面来看看如何配置不缓存的内容。」
...
server {
listen 80;
server_name cache.lion.club;
# URI 中后缀为 .txt 或 .text 的设置变量值为 "no cache"
if ($request_uri ~ \.(txt|text)$) {
set $cache_name "no cache"
}
location / {
proxy_no_cache $cache_name; # 判断该变量是否有值,如果有值则不进行缓存,如果没有值则进行缓存
proxy_cache cache_zone; # 设置缓存内存
proxy_cache_valid 200 5m; # 缓存状态为200的请求,缓存时长为5分钟
proxy_cache_key $request_uri; # 缓存文件的key为请求的URI
add_header Nginx-Cache-Status $upstream_cache_status # 把缓存状态设置为头部信息,响应给客户端
proxy_pass http://cache_server; # 代理转发
}
}
16、配置https
下载证书的压缩文件,里面有个 Nginx
文件夹,把 xxx.crt
和 xxx.key
文件拷贝到服务器目录,再进行如下配置:
server {
listen 443 ssl http2 default_server; # SSL 访问端口号为 443
server_name lion.club; # 填写绑定证书的域名(我这里是随便写的)
ssl_certificate /etc/nginx/https/lion.club_bundle.crt; # 证书地址
ssl_certificate_key /etc/nginx/https/lion.club.key; # 私钥地址
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 支持ssl协议版本,默认为后三个,主流版本是[TLSv1.2]
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
17、解决跨域
-
前端
server
的域名为:fe.server.com
-
后端服务的域名为:
dev.server.com
server {
listen 80;
server_name fe.server.com;
location / {
proxy_pass dev.server.com;
}
}
18、配置开启 gzip 压缩
在 /etc/nginx/conf.d/
文件夹中新建配置文件 gzip.conf
:
# # 默认off,是否开启gzip
gzip on;
# 要采用 gzip 压缩的 MIME 文件类型,其中 text/html 被系统强制启用;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# ---- 以上两个参数开启就可以支持Gzip压缩了 ---- #
# 默认 off,该模块启用后,Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件,如果有则直接返回该 .gz 文件内容;
gzip_static on;
# 默认 off,nginx做为反向代理时启用,用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩;
gzip_proxied any;
# 用于在响应消息头中添加 Vary:Accept-Encoding,使代理服务器根据请求头中的 Accept-Encoding 识别是否启用 gzip 压缩;
gzip_vary on;
# gzip 压缩比,压缩级别是 1-9,1 压缩级别最低,9 最高,级别越高压缩率越大,压缩时间越长,建议 4-6;
gzip_comp_level 6;
# 获取多少内存用于缓存压缩结果,16 8k 表示以 8k*16 为单位获得;
gzip_buffers 16 8k;
# 允许压缩的页面最小字节数,页面字节数从header头中的 Content-Length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大;
# gzip_min_length 1k;
# 默认 1.1,启用 gzip 所需的 HTTP 最低版本;
gzip_http_version 1.1;
其实也可以通过前端构建工具例如 webpack
、rollup
等在打生产包时就做好 Gzip
压缩,然后放到 Nginx
服务器中,这样可以减少服务器的开销,加快访问速度。
19、配置限流
nginx 中有两个主要的指令可以用来配置限流:limit_req_zone 和 limit_req。
下面是一个最简单的限流的例子:
limit_req_zone $binary_remote_addr zone=test:10m rate=2r/s;
server {
location / {
limit_req zone=test;
}
}
imit_req_zone 用于设置限流和共享内存区域的参数,格式为:limit_req_zone key zone rate。
key: 定义限流对象,$binary_remote_addr 是 nginx 中的变量,表示基于 remote_addr(客户端IP) 来做限流,binary_ 是二进制存储。使用 $binary_remote_addr 而不是 $remote_addr 是因为二进制存储可以压缩内存占用量。$remote_addr 变量的大小从7到15个字节不等,而 $binary_remote_addr变量的大小对于 IPv4 始终为4个字节,对于 IPv6 地址则为16个字节。
zone: 定义共享内存区来存储访问信息,访问信息包括每个 IP 地址状态和访问受限请求 URL 的频率等。zone 的定义又分为两个部分:由 zone= 关键字标识的区域名称,以及冒号后面的区域大小。test:10m 表示一个大小为10M,名字为 test 的内存区域。1M 能存储16000个 IP 地址的访问信息,test 大概可以存储约160000个地址。nginx 创建新记录的时候,会移除前60秒内没有被使用的记录,如果释放的空间还是存储不了新的记录,会返回503的状态码。
rate: 设置最大的访问速率。rate=2r/s(为了好模拟,rate 设置的值比较小),表示每秒最多处理 2个请求。事实上 nginx 是以毫秒为粒度追踪请求的,rate=2r/s 实际上是每500毫秒1个请求,也就是说,上一个请求完成后,如果500毫秒内还有请求到达,这些请求会被拒绝(默认返回503,如果想修改返回值,可以设置limit_req_status)。
limit_req_zone 只是设置限流参数,如果要生效的话,必须和 limit_req 配合使用。limit_req 的格式为:limit_req zone=name [burst=number] [nodelay]。
上面的例子只简单指定了 zone=test,表示使用 test 这个区域的配置,在请求 html 文件时进行限流。我们可以理解为这个桶目前没有任何储存水滴的能力,到达的所有不能立即漏出的请求都会被拒绝。如果我1秒内发送了10次请求,其中前500毫秒1次,后500毫秒9次,那么只有前500毫秒的请求和后500毫秒的第一次请求会响应,其余请求都会被拒绝。
处理突发流量
上面的配置保证了 nginx 以固定的速度提供服务(2r/s),但是这种情况不适用于有突发流量的情况,我们希望可以尽可能的缓存请求并处理它们,此时需要在 limit_req 上增加 burst 参数:
limit_req_zone $binary_remote_addr zone=test:10m rate=2r/s;
server {
location / {
limit_req zone=test burst=5;
}
}
burst 表示在超过设定的访问速率后能额外处理的请求数。当 rate=2r/s 时,表示每500ms 可以处理一个请求。burst=5时,如果同时有10个请求到达,nginx 会处理第1个请求,剩余9个请求中,会有5个被放入队列,剩余的4个请求会直接被拒绝。然后每隔500ms从队列中获取一个请求进行处理,此时如果后面继续有请求进来,如果队列中的请求数目超过了5,会被拒绝,不足5的时候会添加到队列中进行等待。
配置 burst 之后,虽然同时到达的请求不会全部被拒绝,但是仍需要等待500ms 一次的处理时间,放入桶中的第5个请求需要等待500ms * 4的时间才能被处理,更长的等待时间意味着用户的流失,在许多场景下,这个等待时间是不可接受的。此时我们需要增加 nodelay 参数,和 burst 配合使用。
limit_req_zone $binary_remote_addr zone=test:10m rate=2r/s;
server {
location / {
limit_req zone=test burst=5 nodelay;
}
}
设置白名单
如果遇到不需要限流的情况,比如测试要压测,可以通过配置白名单,取消限流的设置。白名单要用到 nginx 的 ngx_http_geo_module 和 ngx_http_map_module 模块。
geo $limit {
default 1;
10.0.0.0/8 0;
192.168.0.0/24 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=mylimit:10m rate=2r/s;
geo 指令可以根据 IP 创建变量 $limit。$limit 的默认值是1,如果匹配到了下面的 IP,则返回对应的值(这里返回的是0)。
之后通过 map 指令,将 $limit 的值映射为$limit_key:在白名单内的,$limit_key 为空字符串,不在白名单内的,则为 $binary_remote_addr。当limit_req_zone指令的第一个参数是一个空字符串,限制不起作用,因此白名单的 IP 地址(在10.0.0.0/8和192.168.0.0/24子网中)没有被限制,其它 IP 地址都被限制为 2r/s
limit_req重复
如果同一个 location 下配置了多条 limit_req 的指令,这些指令所定义的限制都会被使用。
geo $limit {
default 1;
10.0.0.0/8 0;
192.168.0.0/24 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=mylimit:10m rate=2r/s;
limit_req_zone $binary_remote_addr zone=myLimit2:10m rate=10r/s;
server {
location ~* \.(html)$ {
limit_req zone=mylimit burst=5 nodelay;
limit_req zone=myLimit2 burst=5 nodelay;
}
}
上面的例子配置了两条规则,myLimit 和 myLimit2。白名单用户虽然没有匹配到mylimit的规则,但是根据规则 mylimit2,被限制为10r/s。对于不在白名单的用户,则需要同时匹配mylimit 和 mylimit2,两者中最严格的条件 2r/s 会起作用。
3限制连接数
nginx 的 ngx_http_limit_conn_module 模块提供限制连接数的能力,包含两个指令limit_conn_zone 和 limit_conn,格式为limit_conn_zone key zone。
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
location ~* \.(html)$ {
limit_conn perip 10;
limit_conn perserver 100;
}
}
limit_conn perip 10: key 是$binary_remote_addr,表示限制单个IP同时最多能持有10个连接。
limit_conn perserver 100: key 是 $server_name,表示虚拟主机(server) 同时能处理并发连接的总数为100。
需要注意的是:只有当 request header 被后端server处理后,这个连接才进行计数。
4上传/下载速率限制
limit_rate主要用于限制用户和服务器之间传输的字节数,最常用的场景可能就是下载/上传限速。limit_rate并没有单独的一个模块,而是在ngx_http_core_module中,同时它的相关指令也比较少,只有limit_rate和limit_rate_after这两个指令。
4.1、limit_rate
server {
location / {
limit_rate 4k;
}
}
limit_rate的用法非常简单,后面跟随的rate就是具体限速的阈值
注意默认的单位是bytes/s,也就是每秒传输的字节数Bytes而不是比特数bits
rate可以设置为变量,从而可以实现动态限速
限速指令的生效范围是根据每个连接确定的,例如上面限定每个连接的速率为4k,也就是当客户端发起两个连接的时候,速率就可以变为8k
4.2、limit_rate_after
server {
location / {
limit_rate_after 500k;
limit_rate 4k;
}
}
limit_rate_after允许在传输了一部分数据之后再进行限速,例如上面的配置中就是传输的前500k数据不限速,500k之后再进行限速。比较常见的应用场景如分段下载限速,超过指定大小的部分再进行限速;又或者是流媒体视频网站一般为了保证用户体验而不会对第一个画面进行限速,确保其能够尽快加载出来,等用户开始观看视频之后,再把带宽限制在合理的范围内,从而降低因客户端网速过快导致提前加载过多内容带来的额外成本。
4.3、proxy_limit_rate
proxy_limit_rate的基本原理和用法与limit_rate几乎一样,唯一不同的是proxy_limit_rate是限制nginx和后端upstream服务器之间的连接速率而limit_rate限制的是nginx和客户端之间的连接速率。需要注意的是proxy_limit_rate需要开启了proxy_buffering这个指令才会生效。
#语法:
Syntax: proxy_limit_rate rate;
Default: proxy_limit_rate 0;
Context: http, server, location
This directive appeared in version 1.7.7.
4.4、动态限速
limit_rate的一大特点就是能够使用变量,这就意味着和map指令之类的进行组合就可以实现动态限速功能,这里只列几个简单的示范
4.4.1、基于时间动态限速
这里引入了nginx内置的一个ssi模块,这个模块有两个比较有意思的时间变量:$date_local和$date_gmt,分别对应当前时间和GMT时间
这里使用变量和map指令组合的方式,利用正则表达式匹配不同的时间段,再结合map变量将不同时间段和不同的限速对应起来。
map $date_local $limit_rate_time {
default 4K;
~(00:|01:|02:|03:|04:|05:|06:|07:).*:.* 16K;
~(08:|12:|13:|18:).*:.* 8K;
~(19:|20:|21:|22:|23:).*:.* 16K;
}
limit_rate $limit_rate_time
4.2、基于变量动态限速
有些服务可能会对不用的用户进行不同的限速,例如VIP用户的速度要更快一些等,例如下面可以针对不同的cookie进行限速
map $cookie_User $limit_rate_cookie {
gold 64K;
silver 32K;
copper 16K;
iron 8K;
}
limit_rate $limit_rate_cookie
四、配置示例
1、示例大全
#开启进程数 <=CPU数
worker_processes 1;
#错误日志保存位置
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#进程号保存文件
#pid logs/nginx.pid;
#等待事件
events {
#每个进程最大连接数(最大连接=连接数x进程数)
#每个worker允许同时产生多少个链接,默认1024
worker_connections 1024;
}
http {
#文件扩展名与文件类型映射表
include mime.types;
#默认文件类型
default_type application/octet-stream;
#日志文件输出格式 这个位置相于全局设置
#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 logs/access.log main;
#打开发送文件
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
#打开gzip压缩
#gzip on;
#设定请求缓冲
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
#设定负载均衡的服务器列表
upstream myproject {
#weigth参数表示权值,权值越高被分配到的几率越大
#max_fails 当有#max_fails个请求失败,就表示后端的服务器不可用,默认为1,将其设置为0可以关闭检查
#fail_timeout 在以后的#fail_timeout时间内nginx不会再把请求发往已检查出标记为不可用的服务器
#这里指定多个源服务器,ip:端口,80端口的话可写可不写
server 192.168.1.78:8080 weight=5 max_fails=2 fail_timeout=600s;
#server 192.168.1.222:8080 weight=3 max_fails=2 fail_timeout=600s;
}
#第一个虚拟主机
server {
#监听IP端口
listen 80;
#主机名
server_name localhost;
#设置字符集
#charset koi8-r;
#本虚拟server的访问日志 相当于局部变量
#access_log logs/host.access.log main;
#对本server"/"启用负载均衡
location / {
#root /root; #定义服务器的默认网站根目录位置
#index index.php index.html index.htm; #定义首页索引文件的名称
proxy_pass http://myproject; #请求转向myproject定义的服务器列表
#以下是一些反向代理的配置可删除.
# 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;
# client_max_body_size 10m; #允许客户端请求的最大单文件字节数
# client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
# proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
# proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
# proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
# proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
# proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
# proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
# proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
}
location /upload {
alias e:/upload;
}
#设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log off;
#allow 192.168.0.3;
#deny all;
#auth_basic "NginxStatus";
#auth_basic_user_file conf/htpasswd;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
# 定义错误提示页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
#多监听
# listen 8000;
#主机名
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
#WEB文件路径
# root html;
#默认首页
# index index.html index.htm;
# }
#}
# HTTPS server HTTPS SSL加密服务器
#
#server {
# listen 443;
# server_name localhost;
# ssl on;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_timeout 5m;
# ssl_protocols SSLv2 SSLv3 TLSv1;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
2、后端反向代理示例
location / {
root /data/front;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location / {
proxy_pass http://192.168.1.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
}