文章目录
Nginx
一、Nginx概述
1、Nginx 功能介绍
-
静态的web资源服务器html,图片,js,css,txt等静态资源
-
http/https协议的反向代理 ,7层url
-
结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
-
tcp/udp协议的请求转发(反向代理) 4层
2、基础特性
- 模块化设计,较好的扩展性
- 高可靠性
- 支持热部署:不停机更新配置文件,升级版本,更换日志文件
- 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
- event-driven, aio, mmap,sendfile
3、Web 服务相关的功能
-
虚拟主机(server)
-
支持 keep-alive 和管道连接(利用一个连接做多次请求)
-
访问日志(支持基于日志缓冲提高其性能)
-
url rewirte
-
路径别名
-
基于IP及用户的访问控制
-
支持速率限制及并发数限制
-
重新配置和在线升级而无须中断客户的工作进程
4、Nginx 进程结构
web请求处理机制
-
多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求。
-
多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程来个客户方进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
4.1 主进程(master process)的功能
- 对外接口:接收外部的操作(信号)
- 对内转发:根据外部的操作的不同,通过信号管理 Worker
- 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
- 读取Nginx 配置文件并验证其有效性和正确性
- 建立、绑定和关闭socket连接
- 按照配置生成、管理和结束工作进程
- 接受外界指令,比如重启、升级及退出服务器等指令
- 不中断服务,实现平滑升级,重启服务并应用新的配置
- 开启日志文件,获取文件描述符
- 不中断服务,实现平滑升级,升级失败进行回滚处理
- 编译和处理perl脚本
4.2 工作进程(worker process)的功能
- 所有 Worker 进程都是平等的
- 实际处理:网络请求,由 Worker 进程处理
- Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争CPU资源,
- 增加上下文切换的损耗
- 接受处理客户的请求
- 将请求依次送入各个功能模块进行处理
- I/O调用,获取响应数据
- 与后端服务器通信,接收后端服务器的处理结果
- 缓存数据,访问缓存索引,查询和调用缓存数据
- 发送请求结果,响应客户的请求
- 接收主程序指令,比如重启、升级和退出等
5、nginx 模块
- 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能
- 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等
- 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如:Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
- 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
- Stream服务模块: 实现反向代理功能,包括TCP协议代理 反向
- 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等
模块 | 说明 |
---|---|
ngx_http_core_module | 核心模块 |
ngx_http_access_module | 访问控制 |
ngx_http_auth_basic_module | 身份验证模块 |
ngx_http_gzip_static_module | 压缩模块 |
ngx_http_log_module | 日志模块 |
ngx_http_proxy_modul | 代理模块 |
ngx_http_rewrite_module | 重写模块 |
ngx_http_stub_status_module | 状态页 |
ngx_http_upstream_module | 反向代理模块 |
二、安装及使用nginx
1、编译安装nginx
##安装之前需要先关闭防火墙
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/
#切换目录
./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
#编译及安装
ln -s /apps/nginx/sbin/* /usr/bin
#做软链接
chown -R nginx.nginx /apps/nginx
#修改权限
vim /usr/lib/systemd/system/nginx.service
#创建nginx自启动文件
[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
systemctl daemon-reload
#重新加载配置文件
systemctl start nginx.service
#启动nginx
systemctl status nginx.service
#查看nginx状态
systemctl stop nginx.service
#停止nginx
源码包里的相关文件
-
contrib:vim 格式文件,修改nginx配置文件的格式,高亮 cp -r /opt/nginx-1.18.0/contrib/vim/* /usr/share/vim/vimfiles/
-
conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params两个文件,配置文件一般都有个样板配置文件,是文件名.default结尾,使用的使用将其复制为并将default去掉即可
-
man:man帮助 man man/nginx.8 不加路径看不了 nginx.8 文件
-
src:源码包
-
html:目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面。
- logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比如/var/logs/nginx里面
- sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能
2、nginx命令
nginx -v #显示版本号
nginx -V #显示编译安装详细模块等信息
nginx -s #发信号
nginx -s stop #立即关闭nginx
nginx -s quit #优雅退出,不影响业务的状态下退出
nginx -s reload #重新加载配置文件
nginx -g #指定配置,不以配置文件中的为准(使用时要将配置文件中的相关配置第3行注释掉)
nginx -t #检查语法格式
nginx -T #检测配置文件是否有语法错误,转储
nginx -p prefix #设置前缀路径(默认是:/etc/nginx/)
nginx -e filename #错误日志文件(默认是:/var/log/nginx/error.log)
nginx -c filename #设置配置文件(默认是:/etc/nginx/nginx.conf)
nginx -q #在检测配置文件期间屏蔽非错误信息
3、分割日志
##方法一:
mv access.log access.log.bak
#改名
touch access.log
#新建一个默认日志文件
[root@liuyanfen12 apps]#curl 192.168.10.11
#使用另一台设备访问,日志存放在access.log.bak中
nginx -s reopen
#重新打开日志文件,将后续的日志写入新的默认日志文件
[root@liuyanfen12 apps]#curl 192.168.10.11
#使用另一台设备访问,日志存放在新建的默认日志文件access.log中
##方法二:
mv access.log access.log.bak
#改名
touch access.log
#新建一个默认日志文件
[root@liuyanfen12 apps]#curl 192.168.10.11
#使用另一台设备访问,日志存放在access.log.bak中
pstree -p |grep nginx
#查看nginx进程
kill -USR1 主进程号
#分割日志,将后续的日志写入新的默认日志文件(注意:进程号应该填写主进程号)
[root@liuyanfen12 apps]#curl 192.168.10.11
#使用另一台设备访问,日志存放在新建的默认日志文件access.log中
- 方法一
- 方法二
4、升级nginx1.18 nginx1.20
- 将旧Nginx文件换成新Nginx文件(注意备份)
- 向master进程发送USR2信号
- master进程修改pid文件名,加后缀.oldbin
- master进程用新Nginx文件启动新master进程,系统中将有新旧两个Nginx主进程共同提供Web服务
- 向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止,并删除Nginx.pid.oldbin文件
- 向旧master进程发送QUIT信号,关闭老master
- 如果发现升级有问题,可以回滚向老master发送HUP,向新master发送QUIT
wget https://nginx.org/download/nginx-1.20.2.tar.gz
#下载安装包
tar xf nginx-1.20.2.tar.gz
#解压软件包
cd nginx-1.20.2/
#切换路径
./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
#编译(注意不要安装执行)
cd objs
#切换目录(此文件夹中有新版本的nginx)
nginx -v
#查看版本(安装好的nginx)
./nginx -v
#查看版本(当前文件夹中升级版本的nginx)
mv /apps/nginx/sbin/nginx /apps/nginx/sbin/nginx.bak
#将低版本的nginx主程序改名
cp ./nginx /apps/nginx/sbin
#将新版本拷入进去
cd /apps/nginx/sbin
#切换目录
nginx -v
#查看版本(是升级的版本)
[root@liuyanfen12 ~]#curl -I 192.168.10.11
#使用另一台设备查看nginx现在的版本(还是旧版本1.18.0)
ps aux|grep -v grep|grep nginx
#查看进程(一个master进程,一个worker进程)
pstree -p|grep nginx
#查看进程树
kill -USR2 主进程号
#升级
ps aux|grep -v grep|grep nginx
#查看进程(两个个master进程,两个个worker进程)
cd /apps/nginx/html
#切换目录
dd if=/dev/zero of=/apps/nginx/html/m.img bs=1G count=10
记录了10+0 的读入
记录了10+0 的写出
10737418240字节(11 GB)已复制,15.4173 秒,696 MB/秒
#生成一个大文件,测试
[root@liuyanfen12 ~]#wget --limit-rate=1M http://192.168.10.11/m.img
#使用新设备下载
kill -WINCH `cat /apps/nginx/logs/nginx.pid.oldbin`
#优雅关闭老进程的worker进程(并不会影响下载)
[root@liuyanfen12 ~]#curl -I 192.168.10.11
#使用另一台设备查看nginx现在的版本(已经更新为新版本1.20.2)
测试一段时间,无问题就可以了
5、配置详细解释
5.1 nginx的配置文件的组成部分
- 主配置文件:nginx.conf
- 子配置文件:include conf.d/*.conf
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置 同步
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {负载均衡
...
}
5.2 全局配置
nginx 有多种模块
- 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能
- 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等
- 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如:Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
- 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
- Stream服务模块: 实现反向代理功能,包括TCP协议代理
- 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等
5.2.1 关闭版本或修改版本
关闭版本
[root@liuyanfen12 ~]#curl -I 192.168.10.11
#使用新设备查看nginx(显示版本号)
vim /apps/nginx/conf/nginx.conf
20 server_tokens off;
#修改配置文件,在20行加入
nginx -t
#检查语法错误
nginx -s reload
#重新加载,不影响使用
[root@liuyanfen12 ~]#curl -I 192.168.10.11
#使用新设备查看nginx(修改完配置文件后,不显示版本号)
修改版本
##此时修改时,nginx是开启的状态
cd /opt/nginx-1.18.0/src/core
#切换目录,在源代码里的核心代码里面修改
vim nginx.h
13 #define NGINX_VERSION "1128"
14 #define NGINX_VER "xxxx/" NGINX_VERSION
#修改配置文件(修改第13"1128"、14"xxxx/"行,#号不要去掉)
cd /opt/nginx-1.18.0/src/http/
#切换目录
vim ngx_http_header_filter_module.c
49 static u_char ngx_http_server_string[] = "Server: xxxx" CRLF;
#修改配置文件(修改第49行"Server: xxxx")
##此时修改时,关闭服务
systemctl stop nginx
#关闭服务
cd /opt/nginx-1.18.0/
#切换目录
./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 && make install
#编译并安装
##验证
systemctl restart nginx
#重启nginx
vim /apps/nginx/conf/nginx.conf
20 server_tokens off;
#编辑配置文件(修改20行为off关闭状态)
nginx -s reload
#重新加载
[root@liuyanfen12 ~]#curl -I 192.168.10.11
Server: xxxx
#使用新设备查看nginx,服务名为xxxx
vim /apps/nginx/conf/nginx.conf
20 server_tokens on;
#编辑配置文件(修改20行为on打开状态)
nginx -s reload
#重新加载
[root@liuyanfen12 ~]#curl -I 192.168.10.11
Server: xxxx/1128
#使用新设备查看nginx,服务名为xxxx/1128
##总结
server_tokens on 对应 nginx/1.18 xxxx/1128
server_tokens off 对应 nginx xxxx
- 验证
5.2.2 修改启动的进程数
vim /apps/nginx/conf/nginx.conf
3 worker_processes 2;
#修改配置文件(修改第3行进程数为2)
nginx -t
#检查语法错误
nginx -s reload
#重新加载配置文件
pstree -p |grep nginx
#查看nginx进程
vim /apps/nginx/conf/nginx.conf
3 worker_processes auto;
#修改配置文件(修改第3行进程数为auto,表示有几个cpu,就开启几个进程)
nginx -t
#检查语法错误
nginx -s reload
#重新加载配置文件
pstree -p |grep nginx
#查看nginx进程
lscpu
#查看cpu信息
5.2.3 cpu与work进程绑定
将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可以保证此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。
ps axo pid,cmd,psr|grep nginx
#查看进程运行在几号cpu上
vim /apps/nginx/conf/nginx.conf
4 worker_cpu_affinity 00000001 00000010;
#修改配置文件(在第4行加入上述整行内容)
nginx -s reload
#重新加载配置文件
ps axo pid,cmd,psr|grep nginx
#查看进程运行在几号cpu上
CPU序号:
CPU MASK: 00000001:0号CPU
00000010:1号CPU
................
10000000:7号CPU
5.2.4 PID路径
vim /apps/nginx/conf/nginx.conf
11 #pid logs/nginx.pid;
pid 进程号文件位置可以自定义省略
5.2.5 nginx进程的优先级(work进程的优先级)
当你想将nginx的work进程的优先级调高 可以使用nice设置
ps axo pid,cmd,psr,ni|grep nginx|sort -n
#查看默认优先级,默认优先级为0
vim /apps/nginx/conf/nginx.conf
5 worker_priority -20;
#修改配置文件(添加此项)
nginx -s reload
#重新加载配置文件
ps axo pid,cmd,psr,ni|grep nginx|sort -n
#查看优先级
##总结
nice的优先级是 -20 到 19
worker_priority 0;
#工作进程优先级,-20~20(19)
5.2.6 调试work进程打开的文件个数
所有worker进程能打开的文件数量上限,包括:nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制。最好与ulimit -n 或者limits.conf的值保持一致
vim /apps/nginx/conf/nginx.conf
6 worker_rlimit_nofile 65535;
#修改配置文件(添加此项)
vim /etc/security/limits.conf
* - nofile 10000
#修改pam认证文件,在最后添加
5.2.7 服务是否以后台方式运行
一般服务都是后台运行,前台容器中会用到
vim /apps/nginx/conf/nginx.conf
daemon off;
#修改配置文件,添加此项
5.2.8 只有master进程没有worker进程
在测试环境中使用到,实际生产中使用较少
master_process off|on;
#是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on
5.3 event事件
events {
worker_connections 65535;
#设置单个工作进程的最大并发连接数
#需要和master配合,否则无效
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
}
5.4 http设置
http {
...
... #各server的公共配置
server { #每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器
...
}
server {
...
server_name #虚拟主机名
root #主目录
alias #路径别名
location [OPERATOR] URL { #指定URL的特性
...
if CONDITION {
...
}
}
}
}
5.4.1 http配置说明
http模块
http {
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模块
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
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;
# }
#}
5.4.2 mime
此项为支持的文件格式,如果不支持的格式会自动帮你下载,如果支持就会显示在网页上
vim /etc/nginx/mime.types
types {
text/html html htm shtml;
.....................................................................
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/webp webp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
5.4.3 sever 下的 root
- root指定了主页文件的位置
root路径格式 指定文件的路径 url
Syntax: root path;
Default:
root html;
Context: http, server, location,
指明软件的根目录
5.4.4 server模块构建虚拟主机
- 实际只有1台,好像有多台主机
建立独立的配置文件,构建不同虚拟主机,PC端和手机端
vim /etc/nginx/nginx.conf
21 include /apps/nginx/conf.d/*.conf;
#修改配置文件要放在http模块里
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
mkdir -p /apps/nginx/conf.d/
#建立子配置文件
cd /apps/nginx/conf.d/
#切换目录
vim pc.conf
#分别编写配置文件
server {
#模块
listen 80;
#监听端口
server_name www.lucky.com;
#域名
root /data/html/;
#访问目录
}
#也可以使用location模块
server{
listen 80;
server_name www.lucky.com;
location / {
root /data/html/;
}
}
mkdir /data/html -p
#构建数据文件夹
echo /data/html > /data/html/index.html
#构建数据文件
echo pcpcpc >> /data/html/index.html
#构建数据文件
cat /data/html/index.html
/data/html
pcpcpc
#查看构建的数据文件
cp pc.conf m.conf
#复制
vim m.conf
#分别编写配置文件
server{
listen 80;
server_name www.m.com;
root /mnt/html/;
}
mkdir /mnt/html -p
#构建数据文件夹
echo /mnt/html > /mnt/html/index.html
#构建数据文件
echo mmmm >> /mnt/html/index.html
#构建数据文件
cat /mnt/html/index.html
/mnt/html
mmmm
#查看构建的数据文件
nginx -s reload
#重新加载配置文件
#构建数据文件
##验证
使用另一台设备,修改/etc/hosts 文件
[root@liuyanfen12 ~]#vim /etc/hosts
192.168.10.11 nodel1 www.lucky.com www.m.com
#添加此行
[root@liuyanfen12 ~]#curl www.lucky.com
#访问
/data/html
pcpcpc
[root@liuyanfen12 ~]#curl www.m.com
#访问
/mnt/html
mmmm
##基于端口
server{
listen 192.168.10.11:1128;
server_name www.m.com;
root /mnt/html/;
}
- 验证
5.4.5 alias别名
- 别名设置
server {
listen 80;
server_name www.kgc.com;
location /nwes {
root /data/nginx/html/pc/;
#相当于追加,将文件夹news追加到/data/nginx/html/pc/news
}
location /study{
alias /mnt/nginx/sports/;
#相当于替换,你访问study就是访问/mnt/nginx/sports
}
}
cd /apps/nginx/conf.d
#切换目录
#修改配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /xxxx {
alias /opt/;
#访问/xxxx相当于访问/opt
}
}
echo opt > /opt/index.html
#将opt写入/opt/index.html文件中
nginx -t
#检查语法错误
nginx -s reload
#重新加载配置文件
##验证(使用另一台设备)
[root@liuyanfen12 ~]#curl www.lucky.com/xxxx/
opt
#访问/xxxx相当于访问/opt
5.4.6 location匹配
在一个server中location配置段可存在多个,用于实现从url到文件系统的路径映射;ngnix会根据用户请求的url来检查定义的所有location,按一定的优化级找出一个最佳匹配,而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最高的一个url,url是用户请求的字符串,即域名后面的web文件路径,然后使用该location模块中的正则url和字符串,如果匹配成功就结束搜索,并使用此location处理此请求。
location 官方帮助
http://nginx.org/en/docs/http/ngx_http_core_module.html#location
语法规则
##语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
= #用于标准url前,需要请求字串与url精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
^~ #用于标准url前,表示包含正则表达式,并且匹配以指定的正则表达式开头,对url的最左边部分做匹配检查,不区分字符大小写
~ #用于标准url前,表示包含正则表达式,并且区分大小写
~* #用于标准url前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此url的所有的url
#\ #用于标准url前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号
#匹配优先级从高到低:
=, ^~, ~/~*, 不带符号
##例如:
www.baidu.com
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
www.baidu.com/documents/1.jpg
访问路径是 / A
访问路径是 /index.html B
访问路径是 /documents/document.html c
访问路径是 /images/1.gif d
访问路径是 /documents/1.jpg
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,
The “/documents/1.jpg” request will match configuration E.
#先看能不能匹配,再看优先级
匹配优先级从高到低:=, ^~, ~/~*, 不带符号
5.4.6.1 不区分大小写-案例
~* 用来对用户请求的url做模糊匹配,url中无论都是大写、都是小写或者大小写混合,此模式也都会匹配,通常使用此模式匹配用户request中的静态资源并继续做下一步操作,此方式使用较多注意:此方式中,对于Linux文件系统上的文件仍然是区分大小写的,如果磁盘文件不存在,仍会提示404
- ~* 虽然不区分大小写,但是linux系统的文件系统xfs区分大小写
#正则表达式匹配:
location ~* /A.?\.jpg {
#匹配A后面一个或没有字符,以.jpg结尾的图片
root /opt/nginx/html/image;
}
#只要是图片就去 images中找
server{
location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js|css)$ {
root /data/nginx/images/;
}
}
此处的优先级有小问题
理论上 = 比什么都不加的优先级高,但这里是的谁在前面先读取谁。
cd /apps/nginx/conf.d
#切换目录
#修改配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location / {
root /opt/;
}
location = / {
root /data/;
}
}
nginx -t
#检查语法错误
nginx -s reload
#重新加载配置文件
echo /opt > /opt/index.html
echo /data > /data/index.html
##验证
[root@liuyanfen12 ~]#curl 192.168.10.11/
/opt
#访问的是/opt
cd /apps/nginx/conf.d
#切换目录
#修改配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location = /1.jpg {
root /data/nginx/static1;
index index.html;
}
location /1.jpg {
root /data/nginx/static2;
index index.html;
}
location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ {
root /data/nginx/static3;
index index.html;
}
}
nginx -t
#检查语法错误
nginx -s reload
#重新加载配置文件
mkdir -p /data/nginx/static{1,2,3}
#建立文件夹static{1,2,3}
#上传图片到/data/nginx/static{1,2,3},访问测试
#匹配优先级:=, ^~, ~/~*,/
location优先级:(location =) > (location ^~ 路径) > (location ~,~* 正则顺序) >
(location 完整路径) > (location 部分起始路径) > (/)
- 访问测试
- 访问测试
5.4.6.2 动静分离
#直接匹配网站根会加速Nginx访问处理
location = /index.html {
......;
}
location / {
......;
}
#静态资源配置方法1
location ^~ /static/ {
......;
}
#静态资源配置方法2,应用较多
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
......;
}
#多应用配置
location ~* /app1 {
......;
}
location ~* /app2 {
......;
}
5.4.7 access 模块(四层控制)
- 格式
Syntax: allow address | CIDR | unix: | la11; #允许
Default: -
Context: http, server, location, limit_except #适用的模块
Syntax: deny address | CIDR | unix: | all; #拒绝
Default: -
Context: http, server, location, limit_except #适用的模块
Example configuration
location/{
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny a11;
}
##四层控制就是控制ip地址
- 如何查看模块是否默认安装
http://nginx.org/en/docs/http/ngx_http_access_module.html
cd /opt/nginx-1.18.0/
#切换到源码包
./configure --help |grep access
#在源码包中过滤access模块
--without-http_access_module disable ngx_http_access_module
--http-log-path=PATH set http access log pathname
--without-stream_access_module disable ngx_stream_access_module
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.kgc.com;
allow 192.168.10.0/24;
deny 192.168.10.12;
location / {
root /data/nginx/html/pc;
}
}
#匹配了之后就不往下匹配了,所以范围小的写前面
当访问有问题时,默认站点是按文件的名字首字母开头排序
5.4.8 验证模块,需要输入用户名和密码
- 模块名称:ngx_http_auth_basic_module
- 访问控制基于模块 ngx_http_auth_basic_module 实现,可以通过匹配客户端资源进行限制
##语法:
Syntax: auth_basic string | off;
Default:
auth_basic off;
Context: http, server, location, 1imit_except
Syntax: auth_basic_user_file file;
Default: _
Context: http, server, location, 1imit_except
htpasswd
- 此命令来自于httpd-tools包,如果没有安装一下即可
yum install -y httpd httpd-tools
#安装httpd-tools软件包
使用方法
#第一次生成文件
htpasswd -c 文件路径 姓名 交互式生成密码
htpasswd -bc 文件路径 姓名 密码 直接将密码跟在后面
-c 代表新建用户名和密码对应的文件
-b 将密码跟在用户名后
#非第一次生成文件
htpasswd 文件路径 姓名 交互式生成密码
htpasswd -b 文件路径 姓名 密码 直接将密码跟在后面
#第一次
[root@localhost conf.d]#htpasswd -c /mnt/.nginxuser xq
New password:
Re-type new password:
Adding password for user xq
[root@localhost conf.d]#ls -a /mnt
. .. .nginxuser
[root@localhost conf.d]#cat /mnt/.nginxuser
xq:$apr1$Ol.Fzi8t$EDlUGDnyo315OL4RLFKR61
#非第一次
[root@localhost conf.d]#htpasswd -b /mnt/.nginxuser xl 123
Adding password for user xl
[root@localhost conf.d]#
[root@localhost conf.d]#cat /mnt/.nginxuser
xq:$apr1$Ol.Fzi8t$EDlUGDnyo315OL4RLFKR61
xl:$apr1$FMIGLc2A$cJcLXOJVL497JWFDxKsyo/
cd /apps/nginx/conf.d
#切换目录
#编辑配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /admin {
auth_basic "welcome";
##提示信息,不是所有浏览器都有用
auth_basic_user_file /mnt/.nginxuser;
#密码文件存放位置
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
mkdir /data/html/admin
#新建文件夹
echo yonghu > /data/html/admin/index.html
#将yonghu写入到/data/html/admin/index.html文件中(访问页面会出现yonghu)
##验证
192.168.10.11/admin
#使用新设备访问,出现需要输入用户名和密码的页面,输入用户名和密码,完成登录,显示yonghu
5.4.9 自定义错误页面
- 改变默认的错误页面,同时也可以用指定的响应状态码进行响应, 可用位置:http, server, location, if in location
格式
error_page code ... [=[response]] url;
页面错误代码
error_page 固定写法
code 响应码
= 可以将响应码转换
url 访问连接
方法一
vim /data/html/index.html
zhu ye mian
#编辑主页面
cd /apps/nginx/conf.d
#切换目录
#编辑配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
error_page 404 /index.html;
#出现404报错页面,跳到主页面/index.html
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##验证
192.168.10.11/xxxxxxxx
#输入错误页面,跳转到主页面
方法二
cd /apps/nginx/conf.d
#切换目录
#修改配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
error_page 404 /40x.html;
#如果出现404页面,跳转到40x.html
location /40x.html {
root /data/nginx/html/error/;
#自定义/40x.html文件位置为/data/nginx/html/error/
}
}
mkdir -p /data/nginx/html/error/
#建立文件夹
echo "please call admin number 1128" > /data/nginx/html/error/40x.html
#将"please call admin number 1128"写入/data/nginx/html/error/40x.html文件中
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##验证
192.168.10.11/xxxxxxxxx
#输入错误页面,/40x.html页面
5.4.10 日志位置存放
格式
Syntax: error_log file [level];
Default:
error_log logs/error.log error;
Context: main, http, mail, stream, server, location
level: debug, info, notice, warn, error, crit, alert, emerg
error_log /apps/nginx/logs/xxx_error.log;
固定格式 文件路径 级别(info debug等 可以忽略不写)
vim /apps/nginx/conf/nginx.conf
5 error_log /data/error.log;
#修改配置文件(修改第5行错误日志存放位置)
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
ll /data
#查看/data文件夹下是否生成/error.log文件夹
##将两个网站的日志分离
[root@localhost error]#vim /apps/nginx/conf.d/m.conf
server{
listen 80;
server_name www.m.com;
root /data/nginx/m/;
error_log /data/logs/m_error.log;
access_log /data/logs/m_access.log;
}
[root@localhost error]#vim /apps/nginx/conf.d/pc.conf
server{
listen 80;
server_name www.pc.com;
root /data/nginx/pc;
error_log /data/logs/pc_error.log;
access_log /data/logs/pc_access.log;
}
[root@localhost error]#mkdir /data/logs
[root@localhost error]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@localhost error]#nginx -s reload
查看日志是否生效
5.4.11 检测文件是否存在
try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误。
语法格式
Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location
cd /apps/nginx/conf.d
#切换目录
#编辑配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location / {
root /data/;
try_files $uri $uri.html $uri/index.html /about/default.html;
#访问的是路径下的abc文件,那按照设置,先会去找abc,没有abc会在后面加上abc.html,再没有会在路径后补上abc/index.html,最后没有,会有一个兜底的/about/default.html
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
cd /data
#切换目录
mkdir about
#建立文件夹
echo about/default.html > about/default.html
#写入
##验证
[root@liuyanfen12 ~]#curl 192.168.10.11/abc
about/default.html
#使用另一台设备登录检测,出现兜底页面about/default.html
5.4.12 长连接
相关设置
keepalive_timeout timeout [header_timeout];
#设定保持连接超时时长,0表示禁止长连接,默认为65s,通常配置在http字段作为站点全局配置
keepalive_requests number;
#在一次长连接上所允许请求的资源的最大数量,默认为100次,建议适当调大,比如:500
可以加在全局或者 server
keepalive_requests 3;
#最大下载三个资源就会断开
keepalive_timeout 60 65; #只能有一个空格
#开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会被断开,后面的60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时间。
Keep-Alive:timeout=60 #浏览器收到的服务器返回的报文
#如果设置为0表示关闭会话保持功能,将如下显示:
Connection:close #浏览器收到的服务器返回的报文
对哪种浏览器禁用长连接
keepalive_disable none | browser ...;
#对哪种浏览器禁用长连接
5.4.13 作为下载服务器配置
- ngx_http_autoindex_module 模块处理以斜杠字符 “/” 结尾的请求,并生成目录列表,可以做为下载服务
官方文档
http://nginx.org/en/docs/http/ngx_http_autoindex_module.html
相关配置说明
[root@localhost nginx-1.18.0]#./configure --help |grep auto
#自带
--without-http_autoindex_module disable ngx_http_autoindex_module
autoindex on | off;
#自动文件索引功能,默为off
autoindex_exact_size on | off;
#计算文件确切大小(单位bytes),off 显示大概大小(单位K、M),默认on
autoindex_localtime on | off ;
#显示本机时间而非GMT(格林威治)时间,默认off
autoindex_format html | xml | json | jsonp;
#显示索引的页面文件风格,默认html
limit_rate rate;
#限制响应客户端传输速率(除GET和HEAD以外的所有方法),单位B/s,即bytes/second,默认值0,表示无限制,此指令由ngx_http_core_module提供
set $limit_rate
#变量提供限制变量优先级高
如:
location /download {
autoindex on;
#开启下载服务器
autoindex_exact_size on;
#开启确切大小不建议开启
autoindex_localtime on;
#使用当地时间
limit_rate 1024k;
#所有人限速1024k,默认单位是字节数
set $limit_rate 2M;
#谁先生效
alias /opt/download;
}
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /download {
autoindex on;
#开启下载服务器
root /mnt/;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
cd /mnt
#切换目录
mkdir download
#新建文件夹(download不需要index.html文件)
cd download/
#切换目录
cp /etc/fstab .
cp /etc/passwd .
#复制
##验证
192.168.10.11/download
#使用另一台设备登录验证,显示页面
注意:download不需要index.html文件
5.4.14 用户上传资料
- 上传需要借助开发小的程序, 并且程序 5M 和nginx10M都会限制。两者取最小
client_max_body_size 1m;
#设置允许客户端上传单个文件的最大值,默认值为1m,上传文件超过此值会出413错误
client_body_buffer_size size;
#用于接收每个客户端请求报文的body部分的缓冲区大小;默认16k;超出此大小时,其将被暂存到磁盘上的由下面client_body_temp_path指令所定义的位置
client_body_temp_path path [level1 [level2 [level3]]];
#设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为16进制的数字,使用hash之后的值从后往前截取1位、2位、2位作为目录名
上传文件大于限制,错误代码413
5.4.15 其他设置
directio size | off;
#操作完全和aio相反,aio是读取文件而directio是写文件到磁盘,启用直接I/O,默认为关闭,当文件大于等于给定大小时,例如:directio 4m;同步(直接)写磁盘,而非写缓存。
open_file_cache off; #是否缓存打开过的文件信息
open_file_cache max=N [inactive=time];
#nginx可以缓存以下三种信息:
(1) 文件元数据:文件的描述符、文件大小和最近一次的修改时间
(2) 打开的目录结构
(3) 没有找到的或者没有权限访问的文件的相关信息
max=N:#可缓存的缓存项上限数量;达到上限后会使用LRU(Least recently used,最近最少使用)算法实现管理
inactive=time:#缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于
open_file_cache_min_uses
#指令所指定的次数的缓存项即为非活动项,将被删除
open_file_cache_valid time;
#缓存项有效性的检查验证频率,默认值为60s
open_file_cache_errors on | off;
#是否缓存查找时发生错误的文件一类的信息,默认值为off
open_file_cache_min_uses number;
#open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项,默认值为1
举例:
open_file_cache max=10000 inactive=60s;
#最大缓存10000个文件,非活动数据超时时长60s
open_file_cache_valid 60s;
#每间隔60s检查一下缓存数据有效性
open_file_cache_min_uses 5;
#60秒内至少被命中访问5次才被标记为活动数据
open_file_cache_errors on;
#缓存错误信息
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.10.11;
deny all;
}
#除了GET和HEAD之外其它方法仅允许192.168.10.11主机使用,其他都拒绝
6、高级配置
6.1 网页的状态页
- 基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module,否则配置完成之后监测会是提示语法错误
注意:状态页显示的是整个服务器的状态,而非虚拟主机的状态
状态页输出信息说明
##输出信息示例:
Active connections: 1
server accepts handled requests
22 22 28
#上面三个数字分别对应accepts,handled,requests三个值
Reading: 0 Writing: 1 Waiting: 0
##状态页用于输出nginx的基本状态信息说明:
Active connections:
#当前处于活动状态的客户端连接数,包括连接等待空闲连接数=reading+writing+waiting
accepts:
#统计总值,Nginx自启动后已经接受的客户端请求的总数。
handled:
#统计总值,Nginx自启动后已经处理完成的客户端请求总数,通常等于accepts,除非有因worker_connections限制等被拒绝的连接
requests:
#统计总值,Nginx自启动后客户端发来的总的请求数。
Reading:
#当前状态,正在读取客户端请求报文首部的连接的连接数,数值越大,说明排队现象严重,性能不足
Writing:
#当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
Waiting:
#当前状态,正在等待客户端发出请求的空闲连接数,开启 keep-alive的情况下,这个值等于active – (reading+writing)
cd /apps/nginx/conf.d
#切换目录
#修改配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /admin {
auth_basic "welcome";
auth_basic_user_file /mnt/.nginxuser;
}
location /status {
stub_status;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##验证
192.168.10.11/status
#使用新设备访问,显示状态页信息
- 验证
添加用户登录页面
cd /apps/nginx/conf.d
#切换目录
#修改配置文件
vim pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /status {
stub_status;
auth_basic "welcome";
auth_basic_user_file /mnt/.nginxuser;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##验证
192.168.10.11/status
#使用新设备访问,出现需要输入用户名和密码的页面,输入用户名和密码,完成登录,显示状态页信息
6.2 Nginx 第三方模块
6.2.1 ehco模块
开源的echo模块
https://github.com/openresty/echo-nginx-module
cd /apps/nginx
#切换目录
vim conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /ip {
echo "welcome, your ip addr: ";
#如果访问ip,则打印welcome, your ip addr:
echo $remote_addr;
#远端访问地址
}
}
需要的安装包echo-nginx-module-master.zip
cd /opt
#切换目录(将需要的安装包下载或上传到此处)
unzip echo-nginx-module-master.zip
#解压
cd /opt/nginx-1.18.0/
#切换目录
systemctl stop nginx
#关闭nginx服务(编译之前,最好先关掉nginx)
./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=/opt/echo-nginx-module-master
#指定安装目录和需要的模块
make -j2 && make install
#编译并安装
cd /apps/nginx/conf.d
#切换目录
cat pc.conf
#查看配置的子配置文件(是否因为重新编译被覆盖,没有被覆盖就没有问题)
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
systemctl restart nginx
#重新启动nginx服务(重新编译之后最好重启一下服务)
##验证
[root@liuyanfen12 ~]#curl 192.168.10.11/ip
welcome, your ip addr:
192.168.10.12
#使用另一台设备设备访问
- 验证
6.3 变量
http://nginx.org/en/docs/varindex.html
官方文档
6.3.1 内置
常用相关内置变量
vim /apps/nginxconf/nginx.conf
#配置文件
$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for
#此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没有X-Forwarded-For,就使用$remote_addrthe “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.
#示例:
客户机 代理1 代理2 nginx服务器
$proxy_add_x_forwarded_for:在代理1上存的是客户机的ip
$proxy_add_x_forwarded_for:在代理2上存的是客户机的ip,代理1的ip
$proxy_add_x_forwarded_for:nginx上存的是客户机的ip,代理1的ip,代理2的ip
$args;
#变量中存放了URL中的参数,例如:http://www.kgc.org/main/index.do?id=20190221&partner=search(问号后面的内容表示参数)
#返回结果为: id=20190221&partner=search存放的就是这个
#示例:
select * from table where id=1128
$document_root;
#保存了针对当前资源的请求的系统根目录,例如:/apps/nginx/html
$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比如:http://www.kgc.org/main/index.do?id=20190221&partner=search会被定义为/main/index.do
#返回结果为:/main/index.do
$host;
#存放了请求的host名称(服务端)
limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
$remote_port;
#客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user;
#已经经过Auth Basic Module验证的用户名
$request_body_file;
#做反向代理时发给后端服务器的本地资源的名称
$request_method;
#请求资源的方式,GET/PUT/DELETE等
$request_filename;
#当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径,如:/apps/nginx/html/main/index.html
系统的真实路径
$request_uri; https:// www.baidu.com/main/index.do?id=20190221&partner=search
#包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,例如:/main/index.do?id=20190221&partner=search
$scheme;
#请求的协议,例如:http,https,ftp等
$server_protocol;
#保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr;
#保存了服务器的IP地址
$server_name;
#请求的服务器的主机名
$server_port; (443 https; 80 http)
#请求的服务器的端口号
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段
arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores
#用下划线代替横线
#示例: echo $http_User_Agent;
$http_user_agent;
#客户端浏览器的详细信息
$http_cookie;
#客户端的cookie信息
$cookie_<name>
#name为任意请求报文首部字部cookie的key名
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
arbitrary request header field; the last part of a variable name is the field
name converted to lower case with dashes replaced by underscores #用下划线代替横线
#示例:
echo $http_user_agent;
echo $http_host;
$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题
echo $sent_http_server;
$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数
#对比变量$arg是全部,如果要id如下
echo $arg_id;
示例:
location /main {
index index.html;
default_type text/html;
echo "hello world,main-->";
echo $remote_addr;
#打印客户端地址
echo $args;
#参数
echo $arg_user;
#参数中的user
echo $document_root;
#根目录
echo $document_uri;
#访问路径
echo $host;
#服务器的地址
echo $http_user_agent;
#浏览器版本
echo $http_cookie;
#客户端的cookie信息
echo $request_filename;
#真实路径
echo $scheme;
#协议
echo $scheme://$host$document_uri?$args;
#整个链接
}
#修改配置文件(添加下面配置内容)
vim /apps/nginx/conf.d/pc.conf
location /main {
index index.html;
default_type text/html;
echo "hello world,main-->";
echo $remote_addr;
echo $args;
echo $arg_user;
echo $document_root;
echo $document_uri;
echo $host;
echo $http_user_agent;
echo $http_cookie;
echo $request_filename;
echo $scheme;
echo $scheme://$host$document_uri?$args;
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##验证
[root@liuyanfen12 ~]#curl 'http://192.168.10.11/main?user=zhou&title=cto'
#使用另一台访问,查看配置文件信息
- 验证
6.3.2自定义变量
- 假如需要自定义变量名称和值,使用指令set $variable value;
语法格式
Syntax: set $variable value;
Default: —
Context: server, location, if
#修改配置文件(添加下面配置内容)
vim /apps/nginx/conf.d/pc.conf
location /test {
set $name xxxx;
#定义一个名字xxxx
echo $name;
#打印名字
set $my_port $server_port;
#将内置变量,定义给自定义变量
echo $my_port;
#打印自定义变量
location /test {
set $name xxxx;
echo $name;
set $my_port $server_port;
echo $my_port;
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##验证
[root@liuyanfen12 ~]#curl 192.168.10.11/test
#使用另一台设备登录验证
- 验证
6.4 自定义访问日志
6.4.1 日志的格式(可以自由指定)
- 访问日志是记录客户端即用户的具体请求内容信息,而在全局配置模块中的 error log 是记录 nginx服务器运行时的日志保存路径和记录日志的 level,因此两者是不同的,而且Nginx的错误日志一般只有一个,但是访问日志可以在不同 server 中定义多个,定义一个日志需要使用 access_log 指定日志的保存路径,使用 log_format 指定日志的格式,格式中定义要保存的具体日志内容。
访问日志由 ngx_http_log_module 模块实现
语法格式
Syntax: access_log path [format [buffer=size] [gzip[=level]] (flush=time] [if=condition]];access_log off;
Defau1t:
access_log 1ogs/access.1og combined;
Context: http,server, location,if in location,limit_except
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$server_name:$server_port';
access_log logs/access.log main;
格式可以定义多个
##注意: 如果开启include定义自配置文件与日志格式的上下关系,日志格式一定要在include之前,否则会不生效。(一般将include子配置文件路径写在最后)
#修改配置文件(添加下面配置)
vim /apps/nginx/conf/nginx.conf
log_format xxxx '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$server_name:$server_port';
access_log logs/access.log xxxx;
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
[root@liuyanfen12 ~]#curl 192.168.10.11
#使用另一台设备登录访问
tail -f /apps/nginx/logs/access.log
#查看登录访问成功生成的日志
6.4.2 自定义json 格式日志
- 方便ELK收集日志
#修改配置文件(添加下面内容)
vim /apps/nginx/conf/nginx.conf
log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
access_log logs/access.log access_json;
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
[root@liuyanfen12 ~]#curl 192.168.10.11
#使用另一台设备访问
tail -f /apps/nginx/logs/access.log
#查看登录访问成功生成的日志
6.4.3 日志分割
----------------日志切割-------------------
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
6.5 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 ...;
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on | off;
#预压缩,先压缩好,不用临时压缩,消耗cpu
gzip_static on | off;
##注意:不会压缩图片; 太小的文件没必要压缩,压缩说不定变大了
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location / {
root /data/html;
gzip on;
gzip_comp_level 9;
gzip_min_length 1k;
gzip_vary on;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
cd /data/html
#切换目录
dd if=/dev/zero of=/data/html/index.html count=1 bs=5M
#将/data/html/index.html文件变成大文件(便于查看压缩效果)
ll -h
#查看当前路径下文件大小
tail -f /apps/nginx/logs/access.log
#实时查看日志
##压缩
192.168.10.11
#使用主机访问,出现状态码304时,表示的是缓存,没有压缩成功,需要强制刷新(强制刷新快捷键ctrl+F5),出现状态码200时,压缩成功(curl浏览器不能压缩,所以不使用curl访问)
##预压缩#,先压缩好,不用临时压缩,消耗cpu
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location / {
root /data/html;
gzip on;
gzip_comp_level 9;
gzip_min_length 1k;
gzip_vary on;
gzip_static on;
#预压缩
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
gzip index.html
#压缩需要访问的文件
mv index.html.gz q.html.gz
#改名(不能使用默认的index)
192.168.10.11/q.html
#使用主机登录访问
6.6 https功能
- Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议,HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
过程
1.客户端发起HTTPS请求
用户在浏览器里输入一个 https 网址,然后连接到服务器的 443 端口
2.服务端的配置
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥
3.传送服务器的证书给客户端
证书里其实就是公钥,并且还包含了很多信息,如证书的颁发机构,过期时间等等
4.客户端解析验证服务器证书
这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如:颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框提示证书存在问题。如果证书没有问题,那么就生成一个随机值,然后用证书中公钥对该随机值进行非对称加密
5.客户端将加密信息传送服务器
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加感解密了
6. 服务端解密信息
服务端将客户端发送过来的加密信息用服务器私钥解密后,得到了客户端传过来的随机值
7.服务器加密信息并发送信息
服务器将数据利用随机值进行对称加密,再发送给客户端
8.客户端接收并解密信息
客户端用之前生成的随机值解密服务段传过来的数据,于是获取了解密后的内容
nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数–with-http_ssl_module开启
官方文档
https://nginx.org/en/docs/http/ngx_http_ssl_module.html
相关配置
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
自签名证书
#所有的证书需要放在一起不能移开
cd /data
#切换目录
mkdir ssl
#新建文件夹
bash certificate.sh
#运行脚本(将需要的脚本先上传,自签名)
cat kgc.com.crt ca.crt > www.kgc.com.crt
#将两个证书合并
mv kgc.com.key www.kgc.com.key(验证钥匙)
#改名
ll www*
#查看文件
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /data/ssl/www.kgc.com.crt;
ssl_certificate_key /data/ssl/www.kgc.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.lucky.com;
root /data/html/;
location / {
root /data/html;
gzip on;
gzip_comp_level 9;
gzip_min_length 1k;
gzip_vary on;
gzip_static on;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
https://192.168.10.11
#使用主机访问登录,会提示有风险
6.7 自定义图标
favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获面的favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404日志,而且浏览器也会显示404报错
##方法一:服务器不记录访问日志:
location = /favicon.ico {
log_not_found off;
access_log off;
}
##方法二:将图标保存到指定目录访问:
#location ~ ^/favicon\.ico$ {
location = /favicon.ico {
root /data/nginx/html/pc/images;
expires 365d; #设置文件过期时间
}
【定制小图标】
wget www.baidu.com/favicon.ico
放到主目录就可以了
不生效可以重新打开浏览器
7、重写功能(rewrite)
- Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为自动访问,另外还可以在一定程度上提高网站的安全性。
7.1 ngx_http_rewrite_module模块指令
官方文档
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html
7.1.1 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
301 永久重定向(将缓存记录在浏览器中)
302 临时重定向(没有缓存,每次都要重定向)
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 ;
}
}
示例
#修改配置文件,添加if条件语句
[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /data/ssl/www.kgc.com.crt;
ssl_certificate_key /data/ssl/www.kgc.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.lucky.com;
root /data/html/;
location / {
if ( $scheme = http ){
echo "if-----> $scheme";
#如果是http,则打印
}
root /data/html;
gzip on;
gzip_comp_level 9;
gzip_min_length 1k;
gzip_vary on;
gzip_static on;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
#使用另一台设备访问
[root@liuyanfen12 ~]#curl 192.168.10.11
#修改配置文件,添加if条件语句
[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /data/ssl/www.kgc.com.crt;
ssl_certificate_key /data/ssl/www.kgc.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.lucky.com;
root /data/html/;
location / {
if (!-e $request_filename){
return 302 /index.html;
#如果访问的页面不存在,直接跳转到主页面
}
root /data/html;
gzip on;
gzip_comp_level 9;
gzip_min_length 1k;
gzip_vary on;
gzip_static on;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
#使用另一台设备访问
[root@liuyanfen12 ~]#curl 192.168.10.11
301 永久重定向(将缓存记录在浏览器中)
302 临时重定向(没有缓存,每次都要重定向)
7.1.2 return
- return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置
语法格式
www.lucky.com/test/
404
return code;
#返回给客户端指定的HTTP状态码
return code [text];
#返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code url;
#返回给客户端的URL地址
示例
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /test {
return 666 "hello";
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
#使用另一台设备访问
[root@liuyanfen12 ~]#curl 192.168.10.11/test
hello[root@liuyanfen12 ~]#
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /test {
default_type text/plain;
return 302 http://www.baidu.com;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
192.168.10.11/test
#使用主机访问,跳转到百度
7.1.3 set指令
- 指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key value,value可以是text, variables和两者的组合。
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;
}
7.1.4 break指令
- 用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和location、if块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行
使用语法
if ($slow) {
limit_rate 10k;
break;
}
location /main {
root /data/html/;
index index.html;
default_type text/html;
set $name kgc;
echo $name;
break; #location块中break后面指令还会执行
set $my_port $server_port;
echo $my_port;
}
7.2 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
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户301
示例
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /bj {
rewrite ^/bj/(.*) /beijing/$1 permanent;
#访问bj跳转到beijing,此处的$1代表后项引用
#rewrite ^/bj/(.*) /beijing/$1 break;
#将permanent换成break,没有区别
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
cd /data/html
#切换目录
mkdir beijing
#新建文件夹
echo beijing > /data/html/beijing/index.html
#将内容beijing写入/data/html/beijing/index.html文件中
[root@liuyanfen12 ~]#curl 192.168.10.11/bj/ -L
[root@liuyanfen12 ~]#curl 192.168.10.11/beijing/
#使用另一台设备访问,不论访问/bj/还是/beijing/都显示beijing(注意/bj/要加-L选项)
示例:http跳转https
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /bj {
rewrite ^/bj/(.*) /beijing/$1 permanent;
}
location / {
#针对全站跳转
if ($scheme = http ){
#如果没有加条件判断,会导致死循环
rewrite /(.*) https://$host/$1 permanent;
#访问http跳转为https
}
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
http://192.168.10.11
#访问http跳转为https
7.3 防盗链
- 防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
none:
#请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked:
#请求报文有referer首部,但无有效值,比如为空。
server_names:
#referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string:
#自定义指定字符串,但可使用*作通配符。示例: *.kgc.org www.kgc.*
regular expression:
#被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:~.*\.kgc\.com
7.3.1 实现盗链
##设备一:(地址:192.168.10.11)
cd /data/html
#切换目录(在当前路径下上传需要的图片)
192.168.10.11/1.jpg
#使用主机访问图片
##设备二:(地址:192.168.10.12)
systemctl start httpd
#开启httpd服务
systemctl status httpd
#查看状态
cd /var/www/html
#切换目录
#编辑配置文件,添加配置
vim index.html
<html>
<body>
<h1>this is yunjisuan </h1>
<img src="http://www.lucky.com/1.jpg"/>
</body>
</html>
##在主机上添加dns解析
C:/Windows/System32/drivers/etc/hosts 文件
192.168.10.11 www.lucky.com
##验证
192.168.10.12
#使用设备二地址访问,显示设备一上传的图片,实现盗链(设备一的图片被设备二盗用显示,点击量算设备二的,但消耗的资源算设备一的)
- 验证
7.3.2 实现防盗链
1、如果非法referer访问,直接跳转到403页面
##设备一:(192.168.10.11)
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location ~* \.(jpg|gif|swf|jpeg|bmp)$ {
root /data/html;
valid_referers none blocked *.lucky.com lucky.com;
if ( $invalid_referer ) {
return 403;
}
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
192.168.10.12
#使用主机访问设备二地址,跳转到403,不显示图片
##说明:
~* \.(jpg|gif|swf|jpeg|bmp)$:这段正则表达式表示匹配不区分大小写,以.jpg 或.gif 或.swf 或.jpeg 或.bmp结尾的文件
Valid_referers:设置信任的网站,可以正常使用图片。
None :浏览器中referer为空的情况,就是直接在浏览器访问图片。
Blocked :referer 不为空的情况 ,但是值被代理或防火墙删除了,这些值不以 http://或https://开头。后面的网址或者域名:referer 中包含相关字符串的网址。
if 语句:如果链接的来源域名不在 valid_referers 所列出的列表中,$invalid_referer 为1,则执行后面的操作,即进行重写或返回403页面。
2、如果非法referer访问,直接跳转到指定的图片(error.png)
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location ~* \.(jpg|gif|swf|jpeg|bmp)$ {
root /data/html;
valid_referers none blocked *.lucky.com lucky.com;
if ( $invalid_referer ) {
rewrite ^/ http://www.lucky.com/error.png;
#如果是非法的referer访问,跳转到指定的图片error.png
#return 403;
}
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
192.168.10.12
#使用主机访问设备二地址,跳转到指定的error.png
7.4 其它相关高级功能
自动生成nginx配置文件
https://www.digitalocean.com/community/tools/nginx
第三方模块
https://github.com/agile6v/awesome-nginx/
lua帮助
https://www.runoob.com/lua/lua-tutorial.html
8、反向代理
- 反向代理:代理的是服务端,负载均衡
反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将nginx本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能
相关配置
ngx_http_proxy_module
#将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module
#用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组(负载均衡)
ngx_stream_proxy_module
#将客户端的请求以tcp协议转发至指定服务器处理(四层代理)
ngx_http_fastcgi_module
#将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module
#将客户端对Python的请求以uwsgi协议转发至指定服务器处理
同构协议:代理服务器两边请求一样
异构协议:代理服务器两边请求不一样
实现 http 反向代理
官方文档
https://nginx.org/en/docs/http/ngx_http_proxy_module.html,
8.1 反向代理配置参数
官方文档
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
相关配置参数
proxy_pass;
#用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头部IP
地址:端口的方式
#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
示例:
10.0.0.8/web
location /web {
index index.html;
proxy_pass http://10.0.0.18:8080;
#8080后面无url,即无 / 符号,需要将location后面url附加到proxy_pass指定的url后面,此行为类似于root
#proxy_pass指定的url不带斜线将访问的/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.kgc.org/web
#如果location定义其url时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能使用url; 即不能有/ ,用户请求时传递的url将直接附加至后端服务器之后
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块,默认即为开启
8.2 反向代理单台web 服务器
- 实现单台反向代理
http协议反向代理
##设备二:(地址:192.168.10.12)
cd /var/www/html
#切换目录
#编辑配置文件,添加配置
vim index.html
<html>
<body>
<h1>this is yunjisuan </h1>
</body>
</html>
[root@liuyanfen12 html]#curl 192.168.10.12
#访问本机地址,显示/var/www/html/index.html中的配置
##设备一:(地址:192.168.10.11)
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location / {
proxy_pass http://192.168.10.12;
#反向代理,访问本机(192.168.10.11)跳转到192.168.10.12地址
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
[root@liuyanfen12 html]#curl 192.168.10.11
#访问设备一地址(192.168.10.11),显示/var/www/html/index.html中的配置
- 在真实服务器上,做防火墙规则
iptables -A INPUT -s 192.168.10.11 -j DROP
客户端再次访问,会出现504网关超时(有可能只是处理时间久,服务器不一定挂了),时间较长1分钟,没有定义代理超时时间
iptables -A INPUT -s 192.168.91.100 -j REJECT
客户端再次访问,会出现502,一般出现502代表后端真实服务器挂了
502 网关不可达,代表后端真实服务器宕机
504 网关超时,(有可能只是单纯处理时间久,服务器不一定挂了)
- 针对某个url进行访问
1、不加 / :
##设备一:(192.168.10.11)
#修改配置文件,添加下面配置
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location ~* /api {
proxy_pass http://192.168.10.12;
#是将location上的url追加在后面
#192.168.10.11/api/---->192.168.10.12/api/
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##设备二:(192.168.10.12)
cd /var/www/html
#切换目录
mkdir api
#新建文件夹
echo api > api/index.html
#将api写入文件/var/www/html/api/index.html中
##验证
[root@liuyanfen12 html]#curl 192.168.10.11/api/
#使用设备二访问设备一地址(192.168.10.11),显示api
2、加 / :
##设备一:(192.168.10.11)
#修改配置文件,添加下面配置
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /api {
proxy_pass http://192.168.10.12/;
#是将location上的url替换成proxy配置里的连接
#192.168.10.11/api/---->192.168.10.12
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##验证
[root@liuyanfen12 html]#curl 192.168.10.11/api/
#使用设备二访问设备一地址(192.168.10.11),显示192.168.10.12的配置
不加 / 是追加,将location上的url追加在后面(一般来讲,不加/)(192.168.10.11/api/---->192.168.10.12/api/)
加 / 是替换,将location上的url替换成proxy配置里的连接,正则表达式不允许替换,否则会出现语法错误(192.168.10.11/api/---->192.168.10.12)
- 不加 / 表示追加
- 加 / 表示替换
8.3 指定location实现反向代理—动静分离
设备一(地址:192.168.10.11)
#修改配置文件,添加下面配置
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
location /api {
proxy_pass http://192.168.10.12;
}
location /xx {
proxy_pass http://192.168.10.13;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
设备二(地址:192.168.10.12)
cd /var/www/html
#切换目录
echo dongtai 7-2 7-2 > index.html
#将dongtai 7-2 7-2写入文件index.html
cat index.html
#查看index.html文件内容
设备三(地址:192.168.10.13)
cd /var/www/html
#切换目录
echo jingtai 7-3 7-3 7-3 > index.html
#将jingtai 7-3 7-3 7-3写入文件index.html
cat index.html
#查看index.html文件
##验证
[root@localhost html]#curl 192.168.10.11/index.html
jingtai 7-3 7-3 7-3
#使用本机访问/index.html,显示jingtai
[root@localhost html]#curl 192.168.10.11/api/
dongtai 7-2 7-2
#使用本机访问/api,显示dongtai
- 验证
8.4 反向代理—缓存功能
关闭后端服务器后,图片无法访问;缓存功能默认关闭,需要开启
相关配置参数
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:2
#定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=2^20=1048576个目录
keys_zone=proxycache:20m
#指内存中缓存的大小,主要用于存放key和metadata(如:使用次数),一般1M可存放8000个左右的key
inactive=120s
#缓存有效时间
max_size=10g;
#最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
proxy_cache proxycache;
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
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
示例—实现缓存
#修改主配置文件,添加下面配置
vim /apps/nginx/conf/nginx.conf
proxy_cache_path /data/nginx/proxycache/ levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
mkdir /data/nginx
#新建文件夹(先建文件夹,再重新加载配置文件,不然会错。/proxycache文件会自动生成)
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
#修改子配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
proxy_cache proxycache;
#开启缓存
proxy_cache_key $request_uri;
#记录完整路径
#proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 302 301 10m;
#200 302 301 缓存10分钟
proxy_cache_valid any 5m;
#any 缓存5分钟
location /api {
proxy_pass http://192.168.10.12;
}
location ~* \.(jpg|png|html|gif|txt|mp4)$ {
proxy_pass http://192.168.10.13;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
tree /data/nginx/proxycache/
#查看/proxycache文件下内容(没有缓存记录)
192.168.10.11/1.jpg
#使用主机访问设备一(图片上传的位置在设备三/data/html/下面)
tree /data/nginx/proxycache/
#查看/proxycache文件下内容(有缓存记录)
8.4.1 添加首部字段
- nginx基于模块 ngx_http_headers_module 可以实现对后端服务器响应给客户端的报文中添加指定的响应首部字段
相关配置参数
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;
示例
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
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;
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;
location /api {
proxy_pass http://192.168.10.12;
}
location ~* \.(jpg|png|html|gif|txt|mp4)$ {
proxy_pass http://192.168.10.13;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
##验证
[root@liuyanfen13 ~]#curl 192.168.10.11 -I
#使用另一台设备访问
8.5 实现反向代理—客户端IP透传
8.5.1 单级代理ip透传
设备一地址:192.168.10.11
设备二地址:192.168.10.12
设备三地址:192.168.10.13
#修改配置文件
vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
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;
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#添加客户端IP和反向代理服务器IP到请求报文头部
location / {
proxy_pass http://192.168.10.12;
#访问本机(192.168.10.11)跳转到192.168.10.12
}
}
[root@liuyanfen13 ~]#curl 192.168.10.11
#使用设备三(192.168.10.13)访问设备一(192.168.10.11)
[root@liuyanfen12 ~]#tail -f /var/log/httpd/access_log
#查看设备二的日志(看不到是谁访问的)
实现客户端ip透传
#修改设备一配置文件,添加下面内容
vim /apps/nginx/conf.d/pc.conf
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#修改设备二httpd配置文件,在196行添加\"%{X-Forwarded-For}i"内容
[root@liuyanfen12 html]#vim /etc/httpd/conf/httpd.conf
196 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i" combined
[root@liuyanfen13 ~]#curl 192.168.10.11
#使用设备三(192.168.10.13)访问设备一(192.168.10.11)
[root@liuyanfen12 ~]#tail -f /var/log/httpd/access_log
#查看设备二的日志,能看到设备三(192.168.10.13)的地址
8.5.2 多级代理ip透传
一级代理上面已配置完成,下面配置二级透传,实现多级代理ip透传
#设备二与设备三开启nginx服务
设备二操作步骤:
#修改配置文件,将子配置文件路径写入主配置文件中
vim /apps/nginx/conf/nginx.conf
include /apps/nginx/conf.d/*.conf;
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
#修改配置文件,添加下面内容
[root@liuyanfen12 html]#vim /apps/nginx/conf.d/qa.conf
server {
listen 80;
server_name www.lucky.com;
root /data/html/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://192.168.10.13;
}
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
设备三操作步骤:
cd /usr/share/nginx/html
#切换目录
echo this is 192.168.10.13 > index.html
#将this is 192.168.10.13内容写入主页面文件
cat index.html
#查看主页面内容
设备一操作步骤:
curl 192.168.10.11
#使用设备一访问自己,显示设备三主页面this is 192.168.10.13
设备三操作步骤:
tail -f /var/log/nginx/access.log
#查看日志内容,实现ip透传
8.6 http反向代理—负载均衡
在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能
官方文档
https://nginx.org/en/docs/http/ngx_http_up
相关配置参数
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一致性
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
8.6.1 调度算法—轮询算法
设备一地址:192.168.10.11
设备二地址:192.168.10.12
设备三地址:192.168.10.13
开始之前,将设备二、三的nginx服务关闭,开启httpd服务
设备二操作步骤:
systemctl start httpd
#开启httpd服务
cd /var/www/html
#切换目录
echo this is 192.168.10.12 > index.html
#将this is 192.168.10.12内容写入主页面文件
cat index.html
#查看主页面内容
设备三操作步骤:
systemctl start httpd
#开启httpd服务
cd /var/www/html
#切换目录
echo this is 192.168.10.13 > index.html
#将this is 192.168.10.13内容写入主页面文件
cat index.html
#查看主页面内容
设备一操作步骤:
#修改配置文件
vim /apps/nginx/conf/nginx.conf
20 upstream web {
21 server 192.168.10.12;
22 server 192.168.10.13;
23 }
24 #include /apps/nginx/conf.d/*.conf;
#将子配置文件路径注释掉
64 location / {
65 proxy_pass http://web/;
66 index index.html index.htm;
67 }
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
curl 192.168.10.11
#访问代理服务器地址设备一,12、13交替出现
8.6.2 调度算法—加权轮询
#修改配置文件
vim /apps/nginx/conf/nginx.conf
20 upstream web {
21 server 192.168.10.12 weight=3;
22 server 192.168.10.13;
23 }
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
curl 192.168.10.11
#访问代理服务器地址设备一,12出现3次,13出现1次
8.6.3 调度算法—ip hash
#修改配置文件
vim /apps/nginx/conf/nginx.conf
upstream web {
hash $remote_addr;
server 192.168.10.12;
server 192.168.10.13;
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
curl 192.168.10.11
#访问本机,第一次出现哪个地址,就一直是那个地址
8.6.4 调度算法—url hash
#修改配置文件
vim /apps/nginx/conf/nginx.conf
upstream web {
hash $request_uri;
server 192.168.10.12;
server 192.168.10.13;
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
curl 192.168.10.11
#访问本机地址,发送请求的地址一旦确定,不会轻易改变
8.6.5 调度算法—cookie hash
#修改配置文件
vim /apps/nginx/conf/nginx.conf
upstream web {
hash $cookie_hello;
server 192.168.10.12 weight=3;
server 192.168.10.13;
}
nginx -t
#检查语法
nginx -s reload
#重新加载配置文件
curl -b hello=q 192.168.10.11
curl -b hello=a 192.168.10.11
#访问本机,地址会根据cookie中关键字的变化而发生改变
8.6.6 调度算法—最少连接数
least_conn;
#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
8.6.7 调度算法—fair 根据响应时间
- 此种算法可以依据页面大小和加载时间长短智能的进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。
9、LNMP 架构
- 环境准备lnmp需要安装nginx 、mysql、php、论坛软件
9.1 安装前的准备流程
systemctl disable --now firewalld
setenforce 0
#关闭防火墙
ls /opt
Discuz_X3.4_SC_UTF8.zip nginx-1.22.0.tar.gz php-7.1.10.tar.bz2 wordpress-6.1.1-zh_CN.zip
#安装之前,上传需要的文件
yum -y install pcre-devel zlib-devel gcc gcc-c++ make
#安装依赖包
useradd -M -s /sbin/nologin nginx
#创建运行用户
(Nginx 服务程序默认以 nobody 身份运行,建议为其创建专门的用户账号,以便更准确地控制其访问权限)
9.2 编译安装nginx
cd /opt
#切换目录
tar xf nginx-1.22.0.tar.gz
#解压
cd nginx-1.22.0/
#切换目录
./configure \
--prefix=/usr/local/nginx \
#指定nginx的安装路径
--user=nginx \
#指定用户名
--group=nginx \
#指定组名
--with-http_stub_status_module
#启用 http_stub_status_module 模块以支持状态统计
cd nginx-1.22.0/
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module
make -j2
#编译
make install
#安装
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
#让系统识别nginx的操作命令可以自动补全nginx
#添加Nginx系统服务,可以使用systemctl去管理nginx
vim /lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -1 $MAINPID
ExecStop=/bin/kill -3 $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
#重新加载配置文件
systemctl enable --now nginx.service
#自启动nginx
systemctl status nginx
#查看nginx状态
9.3 编译安mysql
准备好本次的安装包:mysql-boost-5.7.20.tar.gz
##安装Mysql环境依赖包
yum -y install \
ncurses \
ncurses-devel \
bison \
cmake
yum -y install gcc gcc-c++ cmake bison bison-devel zlib-devel libcurl-devel libarchive-devel boost-devel ncurses-devel gnutls-devel libxml2-devel openssl-devel libevent-devel libaio-devel
#安装软件包
##创建运行用户
useradd -M -s /sbin/nologin mysql
##编译安装
cd /opt
#切换目录
tar xf mysql-boost-5.7.20.tar.gz
#解压(boost数据库的拓展功能)
cd /opt/mysql-5.7.20/
#切换目录
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
#指定mysql安装路径
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
#指定mysql进程监听套接字文件(数据库连接文件)的存储路径
-DSYSCONFDIR=/etc \
#指定配置文件的存储路径
-DSYSTEMD_PID_DIR=/usr/local/mysql \
#指定进程文件的存储路径
-DDEFAULT_CHARSET=utf8 \
#指定默认使用的字符集编码,如utf8
-DDEFAULT_COLLATION=utf8_general_ci \
#指定默认使用的字符集校对规则
-DWITH_EXTRA_CHARSETS=all \
#指定支持其他字符集编码
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
#安装INNOBASE存储引擎
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
#安装ARCHIVE存储引擎
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
#安装BLACKHOLE存储引擎
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
#安装FEDERATED存储引擎
-DMYSQL_DATADIR=/usr/local/mysql/data \
#指定数据库文件的存储路径
-DWITH_BOOST=boost \
#指定boost的路径,若使用mysql-boost集成包安装,则-DWITH_BOOST=boost
-DWITH_SYSTEMD=1
#生成便于systemctl管理的文件
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DWITH_BOOST=boost \
-DWITH_SYSTEMD=1
make -j2
#编译
make install
#安装
##修改mysql 配置文件
vim /etc/my.cnf
[client]
port = 3306
socket=/usr/local/mysql/mysql.sock
[mysqld]
user = mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port = 3306
character-set-server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket=/usr/local/mysql/mysql.sock
bind-address = 0.0.0.0
skip-name-resolve
max_connections=2048
default-storage-engine=INNODB
max_allowed_packet=16M
server-id = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
##更改mysql安装目录和配置文件的属主属组
chown -R mysql:mysql /usr/local/mysql/
chown mysql:mysql /etc/my.cnf
##设置路径环境变量
echo 'export PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH' >> /etc/profile
source /etc/profile
#刷新,使/etc/profile文件生效
##初始化数据库
cd /usr/local/mysql/bin/
#只能用相对路径运行(不能使用绝对路径)
./mysqld \
--initialize-insecure \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data
##添加mysqld系统服务
cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
systemctl daemon-reload
#重新加载
systemctl start mysqld.service
#开启服务
systemctl enable mysqld
#自启动
mysql -uroot
#不修改密码直接登录
##修改mysql的登录密码
mysqladmin -u root -p password "abc123"
给root账号设置密码为abc123,提示输入的是原始密码(为空)要求输入的是原密码直接回车即可
enter password
#出现上面一行内容时,直接按回车键
##10、授权远程登录
mysql -u root -p
9.4 编译安装php软件
本次使用的php软件包为:php-7.1.10.tar.bz2
##安装环境依赖包
yum -y install gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel
##编译安装
cd /opt
#切换目录
tar xf php-7.1.10.tar.bz2
#解压
cd php-7.1.10
#切换目录
./configure \
#指定安装路径和需要的模块
--prefix=/usr/local/php \
--with-mysql-sock=/usr/local/mysql/mysql.sock \
--with-mysqli \
--with-zlib \
--with-curl \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-openssl \
--enable-fpm \
--enable-mbstring \
--enable-xml \
--enable-session \
--enable-ftp \
--enable-pdo \
--enable-tokenizer \
--enable-zip
make -j2
#编译
make install
#安装
##路径优化,做软链接
ln -s /usr/local/php/bin/* /usr/local/bin/
ln -s /usr/local/php/sbin/* /usr/local/sbin/
##调整PHP配置文件
php有三个配置文件:
php.ini #主配置文件
php-fpm.conf #进程服务配置文件
www.conf #扩展配置文件
#①、调整主配置文件:
cp /opt/php-7.1.10/php.ini-development /usr/local/php/lib/php.ini
#复制配置文件
vim /usr/local/php/lib/php.ini
--1170行--修改
mysqli.default_socket = /usr/local/mysql/mysql.sock
--939行--取消注释,修改
date.timezone = Asia/Shanghai
php -m
#验证安装的模块
#②、调整进程服务配置文件:
cd /usr/local/php/etc/
#切换目录
cp php-fpm.conf.default php-fpm.conf
#复制
vim php-fpm.conf
--17行--去掉";"注释
pid = run/php-fpm.pid
#③、调整扩展配置文件:
cd /usr/local/php/etc/php-fpm.d/
#切换目录
cp www.conf.default www.conf
#复制
##启动php-fpm
/usr/local/php/sbin/php-fpm -c /usr/local/php/lib/php.ini
#启动时以/usr/local/php/lib/php.ini文件为主
#PHP-FPM(FastCGI Process Manager:FastCGI 进程管理器)是一个 PHPFastCGI 管理器, 由于Nginx服务器不能处理动态页面,需要由 Nginx 把动态请求交给 php-fpm 进程进行解析。
cd /opt/php-7.1.10/sapi/fpm
#切换目录
cp php-fpm.service /usr/lib/systemd/system/php-fpm.service
#复制
systemctl start php-fpm.service
#开启php-fpm服务
netstat -anpt | grep 9000
#查看php-fpm进程
systemctl status php-fpm.service
#查看php-fpm状态
9.5 配置Nginx支持PHP解析
vim /usr/local/nginx/conf/nginx.conf
--65行--取消注释,修改
location ~ \.php$ {
root html; $document_root
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name; #将 /scripts 修改为nginx的工作目录
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #$document_root 代表当前请求在root指令中指定的值
include fastcgi_params;
}
nginx -s reload
#重新加载配置文件
systemctl restart nginx.service
#重启服务
##验证PHP测试页
vim /usr/local/nginx/html/index.php
<?php
phpinfo();
?>
##验证lnmp的是否搭建成功:
192.168.10.11/index.php
##数据库的用户名
用户名@主机名
root@192.168.10.11
root@192.168.10.12
##验证数据库工作是否正常
mysql -u root -p
CREATE DATABASE bbs;
GRANT all ON bbs.* TO 'bbsuser'@'%' IDENTIFIED BY 'admin123';
#新建数据库用户bbsuser,密码是admin123,并且授权bbsuser可以访问bbs数据库中的所有资源
GRANT all ON bbs.* TO 'bbsuser'@'localhost' IDENTIFIED BY 'admin123';
flush privileges;
#刷新
bbsuser@% #用户名 地址
bbsuser@localhost
vim /usr/local/nginx/html/index.php
#替换原来的测试页内容
<?php
$link=mysqli_connect('192.168.10.11','bbsuser','admin123');
if($link) echo "<h1>Success!!</h1>";
else echo "Fail!!";
?>
浏览器访问
http://192.168.10.11/index.php
9.6 安装论坛
##【部署 Discuz!社区论坛 Web 应用】
cd /opt
#切换目录
unzip Discuz_X3.4_SC_UTF8.zip
#解压
cd /opt/dir_SC_UTF8/
#切换目录
cp -r upload/ /usr/local/nginx/html/bbs/
#复制
##调整论坛目录的权限:
cd /usr/local/nginx/html/bbs/
#切换目录
chown -R nginx.nginx ./config/
chown -R nginx.nginx ./data/
chown -R nginx.nginx ./uc_client/
chown -R nginx.nginx ./uc_server/
都要处理
chmod -R 777 ./config/
chmod -R 777 ./data/
chmod -R 777 ./uc_client/
chmod -R 777 ./uc_server/
##论坛页面访问
http://192.168.10.11/bbs/install/index.php
----------------------------------------------------------------------------------------------------------
数据库服务器:localhost ###本地架设就用localhost,如何不是在在本机上就要填写IP地址和端口号
数据库名字:bbs
数据库用户名:bbsuser
数据库密码:admin123
管理员账号:admin
管理员密码:admin123
----------------------------------------------------------------------------------------------------------
##安装完后访问论坛页面:
http://192.168.10.11/bbs/index.php
http://192.168.10.11/bbs/admin.php
9.7 安装博客
cd /opt
#切换目录
unzip wordpress-6.1.1-zh_CN.zip
#解压
cp -r wordpress /usr/local/nginx/html/
#复制安装页面在wp-admin下
cd /usr/local/nginx/html/
#切换目录
chmod 777 wordpress/ -R
#修改权限
##验证数据库工作是否正常
mysql -u root -p
#授权远程登录
CREATE DATABASE blog;
GRANT all ON blog.* TO 'bloguser'@'%' IDENTIFIED BY 'admin123';
#新建数据库用户bloguser,密码是admin123,并且授权bloguser可以访问blog数据库中的所有资源
GRANT all ON blog.* TO 'bloguser'@'localhost' IDENTIFIED BY 'admin123';
flush privileges;
#刷新
wordpress/wp-admin
##访问验证
http://192.168.10.11/wordpress/wp-admin/install.php
数据库名字:blog
数据库用户名:bloguser
数据库密码:admin123
#访问搭建完成的博客
http://192.168.10.11/wordpress/wp-admin/index.php
10、 内核参数调优
默认的Linux内核参数考虑的是最通用场景,不符合用于支持高并发访问的Web服务器的定义,根据业务特点来进行调整,当Nginx作为静态web内容服务器、反向代理或者提供压缩服务器的服务器时,内核参数的调整都是不同的,此处针对最通用的、使Nginx支持更多并发请求的TCP网络参数做简单的配置
修改/etc/sysctl.conf
fs.file-max = 1000000
#表示单个进程较大可以打开的句柄数
net.ipv4.tcp_tw_reuse = 1
#参数设置为 1 ,表示允许将TIME_WAIT状态的socket重新用于新的TCP链接,这对于服务器来说意义重大,因为总有大量TIME_WAIT状态的链接存在
net.ipv4.tcp_keepalive_time = 600
#当keepalive启动时,TCP发送keepalive消息的频度;默认是2小时,将其设置为10分钟,可更快的清理无效链接
net.ipv4.tcp_fin_timeout = 30
#当服务器主动关闭链接时,socket保持在FIN_WAIT_2状态的较大时间
net.ipv4.tcp_max_tw_buckets = 5000
#表示操作系统允许TIME_WAIT套接字数量的较大值,如超过此值,TIME_WAIT套接字将立刻被清除并打印警告信息,默认为8000,过多的TIME_WAIT套接字会使Web服务器变慢
net.ipv4.ip_local_port_range = 1024 65000
#定义UDP和TCP链接的本地端口的取值范围
net.ipv4.tcp_rmem = 10240 87380 12582912
#定义了TCP接受缓存的最小值、默认值、较大值
net.ipv4.tcp_wmem = 10240 87380 12582912
#定义TCP发送缓存的最小值、默认值、较大值
net.core.netdev_max_backlog = 8096
#当网卡接收数据包的速度大于内核处理速度时,会有一个列队保存这些数据包。这个参数表示该列队的较大值
net.core.rmem_default = 6291456
#表示内核套接字接受缓存区默认大小
net.core.wmem_default = 6291456
#表示内核套接字发送缓存区默认大小
net.core.rmem_max = 12582912
#表示内核套接字接受缓存区较大大小
net.core.wmem_max = 12582912
#表示内核套接字发送缓存区较大大小
注意:以上的四个参数,需要根据业务逻辑和实际的硬件成本来综合考虑
net.ipv4.tcp_syncookies = 1
#与性能无关。用于解决TCP的SYN攻击
net.ipv4.tcp_max_syn_backlog = 8192
#这个参数表示TCP三次握手建立阶段接受SYN请求列队的较大长度,默认1024,将其设置的大一些可使出现Nginx繁忙来不及accept新连接时,Linux不至于丢失客户端发起的链接请求
net.ipv4.tcp_tw_recycle = 1
#这个参数用于设置启用timewait快速回收
net.core.somaxconn=262114
#选项默认值是128,这个参数用于调节系统同时发起的TCP连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此需要结合高并发请求数来调节此值。
net.ipv4.tcp_max_orphans=262114
#选项用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤立链接将立即被复位并输出警告信息。这个限制指示为了防止简单的DOS攻击,不用过分依靠这个限制甚至认为的减小这个值,更多的情况是增加这个值