nginx使用
Nginx概述
Nginx 功能介绍
-
静态的web资源服务器html,图片,js,css,txt等静态资源
-
http/https协议的反向代理 ,7层 url
-
结合FastCGI /uWSGI/SCGI等协议反向代理动态资源请求
-
tcp/udp协议的请求转发(反向代理) 4层
基础特性
- 模块化设计,较好的扩展性
- 高可靠性
- 支持热部署:不停机更新配置文件,升级版本,更换日志文件
- 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
- event-driven, aio, mmap,sendfile
Web 服务相关的功能
- 虚拟主机(server)
- 支持 keep-alive 和管道连接(利用一个连接做多次请求)
- 访问日志(支持基于日志缓冲提高其性能)
- url rewirte
- 路径别名
- 基于IP及用户的访问控制
- 支持速率限制及并发数限制
- 重新配置和在线升级而无须中断客户的工作进程
Nginx 架构
Nginx 进程结构
web请求处理机制
-
多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求。
-
多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程来个客户方进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
主进程(master process)的功能:
对外接口:接收外部的操作(信号)
对内转发:根据外部的操作的不同,通过信号管理 Worker
监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
读取Nginx 配置文件并验证其有效性和正确性
建立、绑定和关闭socket连接
按照配置生成、管理和结束工作进程
接受外界指令,比如重启、升级及退出服务器等指令
不中断服务,实现平滑升级,重启服务并应用新的配置
开启日志文件,获取文件描述符
不中断服务,实现平滑升级,升级失败进行回滚处理
编译和处理perl脚本
工作进程(worker process)的功能:
所有 Worker 进程都是平等的
实际处理:网络请求,由 Worker 进程处理
Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争CPU资源,
增加上下文切换的损耗
接受处理客户的请求
将请求依次送入各个功能模块进行处理
I/O调用,获取响应数据
与后端服务器通信,接收后端服务器的处理结果
缓存数据,访问缓存索引,查询和调用缓存数据
发送请求结果,响应客户的请求
接收主程序指令,比如重启、升级和退出等
Nginx 模块
- 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能
- 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等
- 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如:Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
- 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
- Stream服务模块: 实现反向代理功能,包括TCP协议代理 四层
- 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等
nginx高度模块化,但其模块早期不支持DSO机制;1.9.11 版本支持动态装载和卸载
常用模块
ngx_http_core_module 核心模块
ngx_http_access_module 访问控制 deny allow
ngx_http_auth_basic_module 身份验证
ngx_http_gzip_module 压缩模块
ngx_http_log_module 日志模块
ngx_http_proxy_module 代理模块
ngx_http_rewrite_module 重写模块
ngx_http_stub_status_module 状态页模块
ngx_http_upstream_module 反向代理
ngx_http_stream_module 四层代理
核心模块:core module
标准模块:
HTTP 模块: ngx_http_*
HTTP Core modules #默认功能
HTTP Optional modules #需编译时指定
Mail 模块: ngx_mail_*
Stream 模块 ngx_stream
第三方模块
安装nginx
编译安装
源码包内的文件:
- contrib:vim 格式文件,修改nginx配置文件的格式,高亮 cp -r /opt/nginx-1.18.0/contrib/vim/* /usr/share/vim/vimfiles/
- conf:配置文件
- man:man帮助 man man/nginx.8 不加路径看不了 nginx.8 文件
- src:源码包 点c 点h 结尾的文件 find src -type f |xargs cat |wc -l 193678
https://nginx.org/en/download.html
#官网
yum -y install gcc pcre-devel openssl-devel zlib-devel openssl openssl-devel
#安装依赖包
useradd -M -s /sbin/nologin nginx
#新建nginx用户便于管理
cd /opt/
wget http://nginx.org/download/nginx-1.18.0.tar.gz
#官网下载安装包
tar xf nginx-1.18.0.tar.gz
cd nginx-1.18.0/
#解压软件包
mkdir /apps/nginx -p
./configure --help
#查看帮助模块
./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
make -j2 && make install
chown -R nginx.nginx /apps/nginx
#修改权限
ll /apps/nginx/
total 0
drwxr-xr-x 2 root root 333 Sep 22 12:49 conf
drwxr-xr-x 2 root root 40 Sep 22 12:49 html
drwxr-xr-x 2 root root 6 Sep 22 12:49 logs
drwxr-xr-x 2 root root 19 Sep 22 12:49 sbin
######安装好后生成四个文件功能如下
- conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params两个文件,配置文件一般都有个样板配置文件,是文件名.default结尾,使用的使用将其复制为并将default去掉即可。
- html目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面。
- logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比如/var/logs/nginx里面。
- sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。
find src/ -name "*.c" |xargs cat |wc -l
启动停止nginx
##########启动##############
/apps/nginx/sbin/nginx
#绝对路径启动
ln -s /apps/nginx/sbin/nginx /usr/sbin/
#创建软连接后直接 nginx启动
##########停止###############
killall nginx
创建Nginx 自启动文件
#复制同一版本的nginx的yum安装生成的service文件
vim /usr/lib/systemd/system/nginx.service
#建立文件
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/apps/nginx/logs/nginx.pid
#注意文件位置,如果不对 启动不了
ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
#注意启动文件位置
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
####复制使用
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/apps/nginx/logs/nginx.pid
ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=/bin/kill -s TERM \$MAINPID
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
###如果需要修改pid文件可以执行以下操作#################
mkdir /apps/nginx/run/
#创建目录
vim /apps/nginx/conf/nginx.conf
#修改配置文件
pid /apps/nginx/run/nginx.pid;
#找到 pid的位置修改
#######################################################
systemctl daemon-reload
#重新加载配置
systemctl enable --now nginx
#开机自启并立即启动 如果卡主是应为logs下有 nginx.pid 文件 删除即可
chown -R nginx.nginx /apps/nginx
#修改权限
Yum安装
centos7 需要安装epel源
yum install -y epel-release
#安装epel源 额外 rpeo
yum install nginx -y
yum nginx
去使用官方源按装较新的版本
http://nginx.org/en/linux_packages.html#RHEL
信号
nginx 命令支持向其发送信号,实现不同功能
nginx 当做单独命令使用有以下选项
[root@node2 ~]#nginx -h
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen , reload
-p prefix : set prefix path (default: /etc/nginx/)
-e filename : set error log file (default: /var/log/nginx/error.log)
-c filename : set configuration file (default: /etc/nginx/nginx.conf)
-g directives : set global directives out of configuration file
nginx -t 检查语法
nginx -T 检查语法 并打印所有配置
nginx -v 显示版本
nginx -V 显示详细信息, 包括 编译的信息
nginx -c 指定配置文件启动
nginx -s = kill 发送信号
nginx -s relaod 重新加载配置文件
nginx -s stop 停止nginx 立即停止
nginx -s quit 优雅的退出 , 如果有人在访问我的服务, 那么不会立即关闭, 等客户断开连接再 退出
nginx -s reopen 重新生成日志文件 USR1 日志 有关
nginx -s USR2 飞行中升级
nginx命令 | kill命令 | 含义 |
---|---|---|
nginx -s relaod | kill -s HUP | 重新加载配置文件 |
nginx -s stop | kill -9(KILL) | 立即停止 |
nginx -s quit | kill -3(QUITt) | 优雅的退出 |
nginx -s reopen | kill -s USR1 | 重新生成日志文件 |
nginx | kill -s USR2 | 飞行中升级 |
Nginx基本配置
nginx 官方帮助文档:http://nginx.org/en/docs/
tengine 帮助文档:http://tengine.taobao.org/nginx_docs/cn/docs/
Nginx的配置文件的组成部分:
主配置文件:nginx.conf
子配置文件: include conf.d/*.conf
配置文件由指令和指令块构成
每条指令以;分号结尾,指令与值之间以空格符号分隔
pid /apps/run/nginx.pid
指令已{}达括号将多条指令组织在一起且可以嵌套指令块
include语句允许组合多个配置文件以提升可维护性
#号注释
$使用变量
部分支持正则
自定义变量:由用户使用set命令定义,格式: set variable_name value
全局配置
events{ 控制事件驱动 }
http { web网页配置有关 server { location } }
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置 同步
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {负载均衡
...
}
全局块配置
nginx 有多种模块
- 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能
- 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等
- 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如:Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
- 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
- Stream服务模块: 实现反向代理功能,包括TCP协议代理
- 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等
event块配置
io模型调优
events {
worker_connections 65535; #设置单个工作进程的最大并发连接数 worker_rlimit_nofile 总数量
use epoll;
#使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中设置。
accept_mutex on;
#on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也称为"惊群",因此nginx刚安装完以后要进行适当的优化。建议设置为on
multi_accept on;
#ON时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个。建议设置为on
}
http块设置
http 是一个大的语句块,包含若干个小的语句块(比如server语句块)
http {
...
... #各server的公共配置
server { #每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器 对主机的设置 端口号 ip地址 域名 主站点 日志
...
}
server {
...
server_name #虚拟主机名
root #主目录
alias #路径别名
location [OPERATOR] URL { #指定URL的特性 匹配 url
...
if CONDITION {
...
}
}
}
}
http 协议配置说明
http {
expires 1d;
include mime.types; #导入支持的文件类型,是相对于/apps/nginx/conf的目录
default_type application/octet-stream; #除mime.types中文件类型外,设置其它文件默认类型,访问其它类型时会提示下载不匹配的类型文件
#日志配置部分
#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; #在开启了sendfile的情况下,合并请求后统一发送给客户端。
#tcp_nodelay off; #在开启了keepalived模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟0.2s发送,默认On时,不延迟发送,立即发送用户响应报文。
#keepalive_timeout 0;
keepalive_timeout 65 65; #设置会话保持时间,第二个值为响应首部:keepAlived:timeout=65,可以和第一个值不同
#gzip on; #开启文件压缩
server {
listen 80; #设置监听地址和端口
server_name localhost ; #设置server name,可以以空格隔开写多个并支持正则表达式,如:*.kgc.com www.kgc.* ~^www\d+\.kgc\.com$ default_server
#charset koi8-r; #设置编码格式,默认是俄语格式,建议改为utf-8
#access_log logs/host.access.log main;
location /fxj { www.ky31.com/fsj /apps/nginx/html
root /data;
index index.html index.htm;
}
#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$ { #以http的方式转发php请求到指定web服务器
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ { #以fastcgi的方式转发php请求到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 { #拒绝web形式访问指定文件,如很多的网站都是通过.htaccess文件
来改变自己的重定向等功能。
# deny all;
#}
location ~ /passwd.html {
deny all;
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server { #自定义虚拟server
3.3.1 MIME
范例: 识别php文件为text/html
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm; #指定默认网页文件,此指令由
ngx_http_index_module模块提供
# }
#}
# HTTPS server
#
#server { #https服务器配置
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
Nginx高级配置
日志分割
----------------日志切割-------------------
vim /opt/fenge.sh
#!/bin/bash
# Filename: fenge.sh
day=$(date -d "-1 day" "+%Y%m%d") #显示前一天的时间
logs_path="/var/log/nginx"
pid_path="/usr/local/nginx/logs/nginx.pid"
[ -d $logs_path ] || mkdir -p $logs_path #创建日志文件目录
mv /usr/local/nginx/logs/access.log ${logs_path}/kgc.com-access.log-$day #移动并重命名日志文件
kill -USR1 $(cat $pid_path) #重建新日志文件
find $logs_path -mtime +30 -exec rm -rf {} \; #删除30天之前的日志文件
#find $logs_path -mtime +30 | xargs rm -rf
chmod +x /opt/fenge.sh
/opt/fenge.sh
ls /var/log/nginx
ls /usr/local/nginx/logs/access.log
crontab -e
0 1 * * * /opt/fenge.sh
一键安装及脚本
日志分割
系统调优
自动检测系统性能
Nginx压缩功能
支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源。Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module
官方文档: https://nginx.org/en/docs/http/ngx_http_gzip_module.html
配置指令如下:
#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1
gzip_comp_level level;
#禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...; a.txt
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on | off;
#预压缩,先压缩好,不用临时压缩,消耗cpu
gzip_static on | off;
#重启nginx并进行访问测试压缩功能
[root@centos8 ~]# cp /apps/nginx/logs/access.log /data/nginx/html/pc/m.txt
[root@centos8 ~]# echo "test" > /data/nginx/html/pc/test.html #小于1k的文件测试是否会压缩
[root@centos8 ~]# vim /apps/nginx/conf/nginx.conf
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/gif image/png;
gzip_vary on;
#重启Nginx并访问测试:
[root@centos8 ~]# curl --head --compressed 192.168.91.100/test.html
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 22 Feb 2019 01:52:23 GMT
Content-Type: text/html
Last-Modified: Thu, 21 Feb 2019 10:31:18 GMT
Connection: keep-alive
Keep-Alive: timeout=65
Vary: Accept-Encoding
ETag: W/"5c6e7df6-171109"
Content-Encoding: gzip #压缩传输
#验证不压缩访问的文件大小:
https
ssl on | off;
#为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代
listen 443 ssl;
ssl_certificate /path/to/file;
#指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件
ssl_certificate_key /path/to/file;
#当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
#支持ssl协议版本,早期为ssl现在是TLS,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
#配置ssl缓存
off: #关闭缓存
none: #通知客户端支持ssl session cache,但实际不支持
builtin[:size]:#使用OpenSSL内建缓存,为每worker进程私有
[shared:name:size]:#在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称
ssl_session_timeout time;
#客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
升级 openssl
./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/data/echo-nginx-module-master --with-openssl=/data/openssl-1.1.1k
重写功能rewrite
Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之
一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为自动访问,另外还可以在一定程度上提高网站的安全性。
ngx_http_rewrite_module模块指令
官方文档: https://nginx.org/en/docs/http/ngx_http_rewrite_module.html
if 指令
官方文档:
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:
if (条件匹配) {
action
}
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
#示例:
http://www.baidu.com
3字打头重定向
301 永久重定向 将缓存记录在浏览器中
302 临时重定向 没有缓存 每次都要重定向
304
location /main {
index index.html;
default_type text/html;
if ( $scheme = http ){
echo "if-----> $scheme";
}
if ( $scheme = https ){
echo "if ----> $scheme";
}
#if (-f $request_filename) {
# echo "$request_filename is exist";
#}
if (!-e $request_filename) {
echo "$request_filename is not exist";
#return ;
}
}
http://192.168.91.100/test/a.jpg
/data/test/a.jpg
【用户访问的文件不存在 直接返回主页】
server {
listen 80;
server_name www.kgc.com;
root /data/nginx/pc/;
location / {
root /data/nginx/pc/;
}
location /test {
default_type text/plain;
return 301 http://www.baidu.com;
}
location /main {
index index.html;
default_type text/html;
if ( $scheme = http ){
return 666 "if-----> $scheme";
}
if (!-e $request_filename){
return 302 /index.html; #如果用户不存在直接跳转到主页面
}
}
}
www.kgc.com/main/xxxxx
#注意访问的main下的不存在 目录
#注意前面的if语句执行后会 停止匹配
【想控制所有网站可以 放到前面】
server {
listen 80;
server_name www.kgc.com;
root /data/nginx/pc/;
if (!-e $request_filename){
return 302 /index.html; #如果用户不存在直接跳转到主页面
}
location / {
root /data/nginx/pc/;
}
location /test {
default_type text/plain;
return 301 http://www.baidu.com;
}
location /main {
index index.html;
default_type text/html;
if ( $scheme = http ){
return 666 "if-----> $scheme";
}
}
}
return
return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置
语法格式:
www.kgc.com/test/
404
return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code url; #返回给客户端的URL地址
return code [text]
范例:
location / {
root /data/nginx/html/pc;
default_type text/html;
index index.html;
if ( $scheme = http ){
#return 666;
#return 666 "not allow http";
#return 301 http://www.baidu.com;
return 500 "service error";
echo "if-----> $scheme"; #return后面的将不再执行
}
if ( $scheme = https ){
echo "if ----> $scheme";
}
}
##############################################################
例子1:
server {
listen 80;
server_name www.kgc.com;
root /data/nginx/pc/;
location /{
root /data/nginx/pc/;
}
location /test { #访问test 直接返回403
return 403; #可以改成666
}
}
例子2:
location /test { #访问test 直接返回403
return 666 "hello"; #可以改成666自定义,hello是描述 文字可以 图形浏览器不可以
}
例子3:
location /test {
default_type text/plain; #定义文本格式后图形浏览器可以看见
return 666 "hello";
}
例子4:
location /test {
default_type text/plain;
return 302 http://www.baidu.com;
}
location /test {
default_type text/plain;
return 301 /index.html;
}
301 缓存在磁盘上 我们即使关闭nginx 服务器 客户也可以正常跳转
302 没有缓存 , 服务器断开无法重定向
301永久重定向
302临时重定向
永久重定向
set 指令
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key value,value可以是text, variables和两者的组合。
set $变量名 变量值
location /main {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $name kgc;
echo $name;
set $my_port $server_port(nginx 自带的变量 服务端口 一般80);
echo $my_port;
}
break 指令
用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和locationif块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令(set rewrit return if),其它指令还会执行
使用语法如下:
if ($slow) {
limit_rate 10k;
break;
}
location /main {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $name kgc;
echo $name;
break; #location块中break后面指令还会执行
set $my_port $server_port;
echo $my_port;
}
location /test {
set naem
}
if
return
rewrite
set
break 如果同属于 rewrite 模块那么 break之后的命令就不执行了
rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理
官方文档:
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite
rewrite可以配置在 server、location、if
语法格式 :
rewrite可以配置在 server、location、if
语法格式 :
rewrite regex replacement(www.baidu.com) [flag];
正则匹配原始访问url 替代的url链接 标志 ()premanent301 redirect302 break last 死循环
死
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自上而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301
正则表达式格式
. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字 [0-9]
\b #匹配单词的开始或结束
^ #匹配字符串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
{n} #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^kgc] #匹配除了kgc 这几个字母以外的任意字符
rewrite flag 使用介绍
利用nginx的rewrite的指令,可以实现url的重新跳转,rewrtie有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型
- 跳转型指由客户端浏览器重新对新地址进行请求
- 代理型是在WEB服务器内部实现跳转
rewrite 格式
Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据包。
Default: —
Context: server, location, if
flag 说明
redirect;302
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;301 www.bj.com www.beijing.com
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
break; www.bj.com
#重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户301
例子:
bj ------ > beijing
bj 宝鸡----> baoji
www.bj.com -----> www.beijing.com
#访问 bj 跳转到 beijing
location /bj {
root /data/nginx/pc;
rewrite ^/bj/(.*) /beijing/$1 permanent;
}
此处的$1代表后项引用
192.168.91.100/bj/(.*) /beijing/$1
location / {
root /data/nginx/html/pc;
index index.html;
rewrite / http://www.kgc.com permanent;
#rewrite / http://www.kgc.com redirect;
}
#重启Nginx并访问域名 http://www.kgc.org 进行测试
【rewrite】
rewrite regex replacement [flag];
指令 正则 替换 标志
【访问bj 等于 访问beijing】
location /bj {
rewrite ^/bj/(.*) /beijing/$1 permanent;
}
mkdir beijing
echo beijing > beijing/index.html
整个网页跳转 老域名跳转到新域名
location / {
root /data/nginx/pc/;
rewrite / http://www.accp.com permanent;
}
server {
listen 80;
server_name www.accp.com;
root /data/nginx/pc/accp/;
}
~
cd /data/nginx/pc/
mkdir accp
echo accp > accp/index.html
问,直接给你结果
break 用户在浏览器中的连接不会改变
【break】
server {
location /bj {
rewrite ^/bj/(.*) /beijing/$1 break;
}
}
mkdir beijing
echo beijing > beijing/index.html
mkdir bj
echo bj > bj/index.html
301 302 请求后 告诉你重定向的域名, 让你重新发起请求 两次请求
break 服务器缓存好网页直接让你访 一次请求
last 与 break
location /break {
rewrite .* /test break;
}
location /last {
rewrite .* /test last;
}
location /test {
return 403;
}
location
500
例子:要有页面访问
break 是立即终止匹配 使用该url 进行访问
last 停止本location中的 匹配, 开启新一轮的 location 匹配
location /break {
root /data/;
rewrite ^/break/(.*) /test1/$1 break;
rewrite ^/test1/(.*) /break/$1 break;
}
location /last {
root /data/;
rewrite ^/last/(.*) /test1/$1 last;
rewrite ^/test1/(.*) /test2/$1 last;
}
location /test1 {
echo "new test1";
}
location /test2 {
echo "new test2";
}
mkdir /data/test1
mkdir /data/test2
echo /data/test1 > /data/test1/index.html
echo /data/test2 > /data/test2/index.html
curl 192.168.91.100/break/index.html
curl 192.168.91.100/last/index.html
实战案例 http 转https
server {
listen 443 ssl;
listen 80;
ssl_certificate /apps/nginx/certs/www.kgc.org.crt;
ssl_certificate_key /apps/nginx/certs/www.kgc.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.kgc.org;
location / { #针对全站跳转
root /data/nginx/html/pc;
index index.html;
if ($scheme = http ){ #如果没有加条件判断,会导致死循环
rewrite /(.*) https://$host/$1 redirect;
}
}
location /login { #针对特定的URL进行跳转https
if ($scheme = http ){ #如果没有加条件判断,会导致死循环
rewrite / https://$host/login redirect;
}
}
}
其他例子:
#案例1: 更换目录访问方式,目录转换为对象存储形式
#要求:
#/20200106/static ->/static?id=20200106
#/20200123/image ->/image?id=20200123
rewrite ^/(\d+)/(.+)/ /$2?id=$l last;
#案例2:多目录转换访问方式
#要求: www.lucky.com/images/20200106/1.jpg => www.lucky.com/index.do?name=images&dir=20200106=&file=1.jpg
#规则配置:
if ($host ~* (.*)\.lucky\.com) {
rewrite ^/(.*)/(\d+)/(.*)$ /index.do?name=$1&dir=$2&file=$3 last;
}
防盗链
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
none:#请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息
blocked:#请求报文有referer首部,但无有效值,比如为空
server_names:#referer首部中包含本主机名及即nginx 监听的server_name。
www.lucky.com/test
www.kucky.com/a.jpg
www.cloud.com/index.html
www.lucky.com/a.jpg
arbitrary_string:#自定义指定字符串,但可使用*作通配符。示例: *.kgc.org www.kgc.* www.baidu.com
blog.lucky.com/index.html
www.lucky.com/a.jpg
blog.sina.com
news.sina.com
sports.sina.com
regular expression:#被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:~.*\.kgc\.com
实现盗链
在二机器上:
systemctl stop firewalld
setenforce 0
yum install epel-release.noarch -y
yum install nginx
cd /usr/share/nginx/html
yum install httpd -y
cd /var/www/html
vim index.html
<html>
<body>
<h1>this is yunjisuan </h1>
<img src="http://www.lucky.com/a.jpg"/>
</body>
</html>
systemctl start nginx
vim /etc/nginx/nginx.conf
41 server_name www.lucky.com;
修改41行如上
真机上 添加dns 解析
C:\Windows\System32\drivers\etc
打开 hosts 文件
第二台机器的IP地址 www.lucky.com
真机上测试
www.lucky.com 是否可以打开图片
第一胎服务器
vim /apps/nginx/conf.d/pc.conf
server{
listen 80;
server_name www.pc.com;
root /data/nginx/pc;
location / {
root /data/nginx/pc;
}
location ~* \.(jpg|gif|swf|jpeg|bmp)$ {
root /data/nginx/pc;
valid_referers none blocked *.lucky.com lucky.com;
if ( $invalid_referer ) {
#rewrite ^/ http://www.lucky.com/error.jpg;
return 403;
}
}
}
}
cd /data/nginx/pc/
拖入两张图片 a.jpg error.png
再次测试www.accp.com 是否可以打开图片
www.kgc.com
www.accp.com
80
/data/nginx/kgc
/data/nginx/accp
server {
listen 80;
server_name www.kgc.com;
root /data/nginx/kgc;
}
server {
listen 80;
server_name www.accp.com;
root /data/nginx/accp;
}
实现防盗链
location ~* \.(jpg|gif|swf|png)$ {
root /data/nginx/pc;
valid_referers none blocked *.pc.com pc.com;
if ( $invalid_referer ) {
rewrite ^/ http://www.pc.com/error.png;
#return 403
}
}
~* \.(jpg|gif|swf)$:这段正则表达式表示匹配不区分大小写,以.jpg 或.gif 或.swf 结尾的文件
Valid_referers:设置信任的网站,可以正常使用图片。
None :浏览器中 referer 为空的情况,就是直接在浏览器访问图片。
Blocked :referer 不为空的情况 ,但是值被代理或防火墙删除了,这些值不以 http://或https://开头。后面的网址或者域名:referer 中包含相关字符串的网址。
If 语句:如果链接的来源域名不在 valid_referers 所列出的列表中,$invalid_referer 为1,则执行后面的操作,即进行重写或返回 403 页面。
例子:
server {
index index.html;
valid_referers none blocked server_names *.magedu.com *.magedu.org
~\.google\. ~\.baidu\. ~\.bing\. ~\.so\. ~\.dogedoge\. ; #定义有效的
referer
if ($invalid_referer) { #假如是使用其他的无效的referer访问
return 403 "Forbidden Access"; #返回状态码403
}
......
}
#重启Nginx并访问测试
反向代理
正向代理 : 代理的是客户端 去访问 服务器 加快访问速度 squid
反向代理: 代理的是服务端 负载均衡
nginx : 4+7
haproxy: 4+7
lvs : 只支持4层代理 性能强
3 种 自动生成
keepalive
反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能
ngx_http_proxy_module: #将客户端的请求以http协议转发至指定服务器进行处理 7层代理
ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组 负载均衡
ngx_stream_proxy_module:#将客户端的请求以tcp协议转发至指定服务器处理 4层代理
ngx_http_fastcgi_module:#将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module: #将客户端对Python的请求以uwsgi协议转发至指定服务器处理
http 协议反向代理
反向代理配置参数
#官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
指令语法:
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
proxy_pass;
#用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP地址:端口的方式
#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
例子:
location / {
proxy_pass http://192.168.10101;
}
# http://192.168.10101 目前加不加/ 无所谓 访问本机的主站点 那么跳转到 101 的 主站点
location /test {
proxy_pass http://192.168.10101;
}
加不加/
#示例:
10.0.0.8/web
location /web {
index index.html;
proxy_pass http://10.0.0.18:8080; #8080后面无uri,即无 / 符号,需要将location后面url 附加到proxy_pass指定的url后面,此行为类似于root
#proxy_pass指定的uri不带斜线将访问的/web,等于访问后端服务器
http://10.0.0.18:8080/web/index.html,即后端服务器配置的站点根目录要有web目录才可以被访问
# http://nginx/web/index.html ==> http://10.0.0.18:8080/web/index.html
proxy_pass http://10.0.0.18:8080/; #8080后面有uri,即有 / 符号,相当于置换,即访问/web时实际返回proxy_pass后面uri内容.此行为类似于alias
#proxy_pass指定的uri带斜线,等于访问后端服务器的http://10.0.0.18:8080/index.html 内容返回给客户端
} # http://nginx/web/index.html ==> http://10.0.0.18:8080
#重启Nginx测试访问效果:
#curl -L http://www.cs.org/web
#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能使用uri; 即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后
server {
...
server_name HOSTNAME;
location ~|~* /uri/ {
proxy_pass http://host:port; #proxy_pass后面的url 不能加/
}
...
}
http://HOSTNAME/uri/ --> http://host/uri/
proxy_hide_header field;
#用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置在http,server或location块
#示例: 隐藏后端服务器ETag首部字段
location /web {
index index.html;
proxy_pass http://10.0.0.18:8080/;
proxy_hide_header ETag;
}
proxy_pass_header field;
#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端
#field 首部字段大小不敏感
#示例:透传后端服务器的Server和Date首部给客户端,同时不再响应报中显示前端服务器的Server字段
proxy_pass_header Server;
proxy_pass_header Date;
proxy_pass_request_body on | off;
#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启
proxy_pass_request_headers on | off;
#是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启
**实战案例: **反向代理单台web 服务器
实现单台反向代理
7-1 代理服务器
vim /apps/nginx/conf.d/pc.conf
server{
listen 80;
server_name www.pc.com;
root /data/nginx/pc;
location / {
proxy_pass http://192.168.10101;
}
}
7-2 真实服务器
yum install httpd -y
cd /var/www/html
echo "real server 101" > index.html
systemctl stop nginx
systemctl start httpd
7-3 客户机
vim /etc/hosts
192.168.10100 www.pc.com
代理服务器
server{
listen 80;
server_name www.pc.com;
root /data/nginx/pc;
location / {
root /data/nginx/pc;
proxy_pass http://192.168.10101;
}
}
真实服务器
yum install httpd -y
cd /var/www/html/
echo "real server httpd" >index.html
建立大文件查看连接情况
dd if=/dev/zero of=test.img count=1 bs=1G
找台服务器访问
curl www.pc.com
wget --limit-rate=1024 http://192.168.10101/test.img
修改端口号
真实服务器
httpd 服务器修改端口号
server{
listen 80;
server_name www.pc.com;
root /data/nginx/pc;
location / {
root /data/nginx/pc;
proxy_pass http://192.168.10101:8080;
}
}
502
504
在真实服务器上 做防火墙规则
iptables -A INPUT -s 192.168.10100 -j DROP
客户端再次访问 会出现504网关超时(有可能只是处理时间久,服务器不一定挂了),时间较长1分钟,没有定义代理超时时间
iptables -A INPUT -s 192.168.10100 -j REJECT
客户端再次访问 会出现502,一般出现502 代表后端真实服务器挂了
针对某个uri 进行访问
要求:将用户对域 www.cs.com的请求转发给后端服务器处理
[root@centos8 ~]# cat /apps/nginx/conf/conf.d/pc.conf
server {
listen 80;
server_name www.cs.com;
location /api {
proxy_pass http://192.168.10101;
}
}
追加
192.168.10100/api/ -----------------> 192.168.10101/api/
server {
listen 80;
server_name www.cs.com;
location /api {
proxy_pass http://192.168.10101/;
}
}
替换
192.168.10100/api/ -----------------> 192.168.10101/
server {
listen 80;
server_name www.cs.com;
location ~* /api {
proxy_pass http://192.168.10101;
}
}
只要包含api都替换成 192.168.10101/
不太实际情况
指定location 实现反向代理 动静分离
server {
listen 80;
server_name www.cs.org;
location / {
index index.html index.php;
root /data/nginx/html/pc;
}
location /api {
#proxy_pass http://10.0.0.18:80/; #注意有后面的/, 表示置换
proxy_pass http://192.168.10101; #后面没有 / , 表示追加
}
}
http 共享文件
ftp
192.168.10100/a.jpg
index.html
server {
......
location ~* \.(jpe?g|png|bmp|gif|html)$ {
proxy_pass http://192.168.10103; #如果加/ 语法出错
}
}
#如果 http://10.0.0.18/ 有 / 语法出错
server{
listen 80;
server_name www.pc.com;
root /data/nginx/pc;
location / {
root /data/nginx/pc;
}
location /api {
root /data/nginx/pc;
proxy_pass http://192.168.10101:8080;
}
location ~* \.(jpg|jpeg|png|gif|bmp)$ {
root /data/nginx/pc;
proxy_pass http://192.168.10102;
}
}
http {
server {
listen 80;
server_name ;
root ;
}
}
proxy_pass
反向代理示例:缓存功能
关闭后端服务器后,图片无法访问
缓存功能默认关闭,需要开启
proxy_cache zone_name | off; 默认off
#指明调用的缓存,或关闭缓存机制;Context:http, server, location
#zone_name 表示缓存空间的名称.需要由proxy_cache_path事先定义
proxy_cache_key string;
#缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
#定义对特定响应码的响应内容的缓存时长,定义在http{...}中
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_path;
#定义可用于proxy功能的缓存;Context:http 必须放在http语句中
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=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配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建
levels=1:2:3 #定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=2^20=1048576个目录
keys_zone=proxycache:20m #指内存中缓存的大小,主要用于存放key和metadata(如:使用次数),一般1M可存放8000个左右的key
inactive=120s #缓存有效时间
max_size=10g; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
#在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
#示例
proxy_cache_use_stale error http_502 http_503;
proxy_cache_methods GET | HEAD | POST ...;
#对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
清理缓存
方法1: rm -rf 缓存目录
方法2: 第三方扩展模块ngx_cache_purge
例子:
http 语句块中
proxy_cache_path /data/nginx/proyxcache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
http 语句
1:1:1 16个二进制 2^16/2^16/2^16 2^48
server {
listen 80;
proxy_cache proxycache;
proxy_cache_key $request_uri;
#proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 5m;
server_name www.cs.com;
root /data/nginx/pc;
location / {
root /data/nginx/pc;
}
location /api {
proxy_pass http://192.168.10101:9527;
}
location ~* \.(jpg|png|gif|html)$ {
proxy_pass http://192.168.10102;
}
}
实现缓存实际操作
在未开启缓存前可以测试下载速度
ab -c100 -n1000 http://192.168.10100/12.png
去代理服务器上 添加操作
先去 主配置文件 的 http模块 中加入下方配置
proxy_cache_path /data/nginx/proyxcache/ levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
再去 子配置文件中添加
server{
listen 80;
server_name www.pc.com;
proxy_cache proxycache;
proxy_cache_key $request_uri; www.kg.com/a.jpg
#proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 5m;
root /data/nginx/pc;
location / {
root /data/nginx/pc;
}
location /api {
root /data/nginx/pc;
proxy_pass http://192.168.10101:8080;
}
location ~* \.(jpg|jpeg|png|gif|bmp)$ {
root /data/nginx/pc;
proxy_pass http://192.168.10102;
}
}
添加首部字段
nginx基于模块ngx_http_headers_module可以实现对后端服务器响应给客户端的报文中添加指定的响应首部字段
参考链接: https://nginx.org/en/docs/http/ngx_http_headers_module.html
Syntax: add_header name value [always];
Default: —
Context: http, server, location, if in location
#添加响应报文的自定义首部:
add_header name value [always];
#示例:
add_header X-Via $server_addr; #当前nginx主机的IP
add_header X-Cache $upstream_cache_status; #是否缓存命中
add_header X-Accel $server_name; #客户访问的FQDN
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;
实现反向代理客户端 IP 透传
官方文档:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#var_proxy_add_x_forwarded_for
[root@centos8 ~]# cat /apps/nginx/conf/conf.d/pc.conf
server {
listen 80;
server_name www.cs.org;
location / {
index index.html index.php;
root /data/nginx/html/pc;
proxy_pass http://10.0.0.18;
#proxy_set_header X-Real-IP $remote_addr; #只添加客户端IP到请求报文头部,转发至后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #添加客户端IP和反向代理服务器IP到请求报文头部
}
}
#重启nginx
[root@7-1 ~]#systemctl restart nginx
#后端Apache配置:
[root@7-1 ~]#vim /etc/httpd/conf/httpd.conf
LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
#重启apache访问web界面并验证apache日志
[root@centos8 ~]#cat /var/log/httpd/access_log
10.0.0.1 10.0.0.8 - - [05/Mar/2019:00:40:46 +0800] "GET / HTTP/1.0" 200 19 "-"
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/72.0.3626.119 Safari/537.36"
#Nginx配置:
[root@centos8 conf.d]# cat /apps/nginx/conf/nginx.conf
"$http_x_forwarded_for"' #默认日志格式就有此配置
#重启nginx访问web界面并验证日志格式:
10.0.0.8 - - [04/Mar/2019:16:40:51 +0800] "GET / HTTP/1.0" 200 24 "-"
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/72.0.3626.119 Safari/537.36" "10.0.0.1"
http反向代理负载均衡
官方文档: https://nginx.org/en/docs/http/ngx_http_up
#自定义一组服务器,配置在http块内
upstream web {
server 192.168.10100
server 192.168.10101
server 192.168.10102
}
location / {
pass_proxy http://web/
}
#示例
upstream backend {
server backend1.example.com weight=4; 权重
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
语法:
server address [parameters];
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
#server支持的parameters如下:
weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒
backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器 sorry server 自己不能转自己
down #标记为down状态
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx
hash KEY [consistent];
#基于指定请求报文中首部字段或者URI等key做hash计算,使consistent参数,将使用ketama一致性
www.cs.com/test1
hash test1 103
hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一
致性hash基于取模运算
hash $request_uri consistent; #基于用户请求的uri做hash
hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑定
ip_hash;
#源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持
least_conn;
#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
fair
#此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。
实际操作
http {
upstream web {
#hash $request_uri consistent;
#hash $cookie_sessionid
#ip_hash;
#least_conn;
server 192.168.10101:80;
server 192.168.10102:80;
}
........
}
[root@localhost nginx]#vim conf.d/test.conf
server {
listen 80;
server_name www.cs.com;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
root /data/nginx/pc;
location / {
root /data/nginx/pc;
proxy_pass http://web;
}
}
调度算法
基于hash的调度算法
hash KEY [consistent];
#基于指定请求报文中首部字段或者URI等key做hash计算,使consistent参数,将使用ketama一致性
添加节点后会导致很多的调度的缓存信息失效
一致性md5算法取模假设是对url md5算法 再对后端服务器地址 取模 2^32次方再对后端服务器的ip地址 取模
实际操作
调度算法:
http {
upstream web {
server 192.168.10101:80 weight=3; #权重 3比1
server 192.168.10103:80; #默认 1
}
http {
upstream web {
server 192.168.10101:80 weight=3;
server 192.168.10103:80 max_conns=10; #最多连接10个
}
准备大文件 压测
ab -c100 -n 10000 http://www.cs.com/a.jpg
http {
upstream web {
server 192.168.10101:80 ;
server 192.168.10103:80 down; #实际没死,认为是死了
}
http {
upstream web {
server 192.168.10101:80 ;
server 192.168.10103:80 down; #实际没死,认为是死了
server 127.0.0.1:80 backup;
}
【hash】
d5sum anaconda-ks.cfg 对文件进行hash运算
b381bf20b4ea5927a73a8cb48710fb46 anaconda-ks.cfg
www.cs.com/test1 把/test1 做hash运算
得到hash 结果后 每台机器的 权重除以总权重
http {
upstream web {
hash $remote_addr;
server 192.168.10101:80;
server 192.168.10103:80;
}
http {
upstream web {
hash $request_uri;#发请求的地址,一旦定下不会轻易改变
server 192.168.10101:80;
server 192.168.10103:80;
}
多生成文件
for i in {1..10};do echo 192.168.10101 test$i > test$i.html;done
curl www.cs.com/test4.html
http {
upstream web {
hash $cookie_hello;
server 192.168.10101:80;
server 192.168.10103:80;
}
#curl -b hello=zhou 192.168.10100
实现 Nginx tcp 负载均衡 四层
官方文档:
https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html
http://nginx.org/en/docs/stream/ngx_stream_upstream_module.html
http 同级别的
stream { #定义stream相关的服务;Context:main
upstream backend { #定义后端服务器
hash $remote_addr consistent; #定义调度算法
server backend1.example.com:12345 weight=5; #定义具体server
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns { #定义后端服务器
server 10.0.0.1:53535; #定义具体server
server dns.example.com:53;
}
server { #定义server
listen 12345; #监听IP:PORT
proxy_connect_timeout 1s; #连接超时时间
proxy_timeout 3s; #转发超时时间
proxy_pass backend; #转发到具体服务器组
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}
负载均衡实例 : Redis
后端服务器
#安装两台redis服务器
[root@centos8 ~]# yum -y install redis
[root@centos8 ~]# sed -i '/^bind /c bind 0.0.0.0' /etc/redis.conf
[root@centos8 ~]# systemctl enable --now redis
[root@centos8 ~]# ss -tnl | grep 6379
LISTEN 0 128 *:6379 *:*
nginx 配置
[root@7-1 ~]# vim /apps/nginx/conf/nginx.conf
include /apps/nginx/conf/tcp/tcp.conf; #注意此处的include与http模块平级
[root@7-1 ~]# mkdir /apps/nginx/conf/tcp
[root@7-1 ~]# cat /apps/nginx/conf/tcp/tcp.conf
stream {
upstream redis_server {
#hash $remote_addr consistent;
server 10.0.0.18:6379 max_fails=3 fail_timeout=30s;
server 10.0.0.28:6379 max_fails=3 fail_timeout=30s;
}
server {
listen 10.0.0.8:6379;
proxy_connect_timeout 3s;
proxy_timeout 3s;
proxy_pass redis_server;
}
}
#重启nginx并访问测试
[root@7-1 ~]# systemctl restart nginx
[root@7-1 ~]# ss -tnl | grep 6379
LISTEN 0 128 10.0.0.8:6379 *:*
#测试通过nginx 负载连接redis:
[root@centos8 ~]#redis-cli -h 10.0.0.8 set name wang