nginx
访问网站过程
利用DNS协议进行域名解析 --> 建立tcp协议三次握手过程 --> 客户端发出访问网站相应页面请求(发出http协议请求报文) --> 服务端发出相应访问页面的请求信息(发出http) --> 断开tcp协议四次挥手过程
2. 利用DNS协议进行域名解析
DNS称为域名系统,主要作用是负责把域名解析对应的IP地址。就是把www.baidu.com 解析为对应的IP地址 ,有了IP地址就相当于知道百度服务器在哪了,接下来就是去找它。
DNS体系中,查找记录,分为两种查找方式:递归查询和迭代查询。
1、 递归查询:由DNS客户端发起,一级一级的向上提交查询申请,直至查询终止
2、 迭代查询:一般情况下由DNS服务器之间完成,即本地DNS向上一级DNS提交查询,上级DNS并不直接返回查询结果,而是告知DNS应该向哪里去查找。
在真正的DNS查询过程中,是包含递归查询和迭代查询的。无论任何方式的查找过程,在每个环节,都会先查找缓存。DNS服务器如果没有了缓存就失去了意义。。。
请记住查询顺序:
HOSTS表--> 本地DNS -->上层DNS(包括根DNS)
3.建立tcp协议三次握手过程
1)简单说明TCP协议
IP 协议定义了一套自己的地址规则,称为 IP 地址。它实现了路由功能,允许某个局域网的 A 主机,向另一个局域网的 B 主机发送消息。
IP 协议只是一个地址协议,并不保证数据包的完整。如果路由器丢包(比如缓存满了,新进来的数据包就会丢失),就需要发现丢了哪一个包,以及如何重新发送这个包。这就要依靠 TCP 协议。
简单说,TCP 协议的作用是,保证数据通信的完整性和可靠性,防止丢包。
TCP三次握手建立过程简单说明:
1.由客户端(用户)发送建立TCP连接的请求报文,其中报文中包含seq序列号,是由发送端随机生成的。
并且还将报文中SYN字段置为1,表示需要建立TCP连接请求。
2.服务端(就是百度服务器)会回复客户端(用户)发送的TCP连接请求报文,其中包含seq序列号,也是由回复端随机生成的,
并且将回复报文的SYN字段置1,而且会产生ACK验证字段,ACK验证字段数值是在客户端发过来的seq序列号基础上加1进行回复:
并且还会回复ack确认控制字段,以便客户端收到信息时,知晓自己的TCP建立请求已得到了确认。
3.客户端收到服务端发送的TCP建立请求后,会使自己的原有序列号加1进行再次发送序列号,
并且再次回复ACK验证请求,在B端发送过来的seq基础上加1,进行回复;同时也会回复ack确认控制字段,
以便B收到信息时,知晓自己的TCP建立请求已经得到了确认。
4.客户端发出访问网站相应页面请求(发出http协议请求报文)
5.断开tcp协议四次挥手过程
-
当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次挥手”。
-
第一次挥手:
-
Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
-
第二次挥手:
-
Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
-
第三次挥手:
-
Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
-
第四次挥手:
简单来说就是:
1) 拿url去DNS解析IP地址,(查本地DNS缓存)
2) 浏览器 根据IP地址 80端口,建立tcp连接
3) 发送http请求 (请求行 请求头 请求体)
请求行: 请求方法 url HTTP版本
请求头: 键值对
host: 主机名
user-agent: 客户端浏览器信息
请求体:
GET
POST
4) 服务器端给客户端发送http响应
状态码: 200 OK
响应内容: 页面交给浏览器解析
5) 断开tcp连接
nginx简介
nginx(发音同engine x)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行。
nginx由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler使用。
第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
nginx的特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
nginx的特性与优点
nginx的特性
nginx是一个很牛的高性能Web和反向代理服务器,它具有很多非常优越的特性:
- 在高连接并发的情况下,nginx是Apache服务器不错的替代品,能够支持高达50000个并发连接数的响应
- 使用epoll and kqueue作为开发模型
- nginx作为负载均衡服务器:nginx既可在内部直接支持和PHP程序对外进行服务,也可支持作为HTTP代理服务器对外进行服务
- nginx采用C进行编写,不论系统资源开销还是CPU使用效率都比Perlbal要好很多
nginx的优点
- 高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2-3万并发连接数
- 内存消耗少:在3万并发连接下,开启的10个nginx进程才消耗150M内存(15M*10=150M)
- 配置文件非常简单:风格跟程序一样通俗易懂
- 成本低廉:nginx为开源软件,可以免费使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币
- 支持Rewrite重写规则:能够根据域名、URL的不同,将HTTP请求分到不同的后端服务器群组
- 内置的健康检查功能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端访问
- 节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头
- 稳定性高:用于反向代理,宕机的概率微乎其微
- 模块化设计:模块可以动态编译
- 外围支持好:文档全,二次开发和模块较多
- 支持热部署:可以不停机重载配置文件
- 支持事件驱动、AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化
nginx的基本功能
- 静态资源的web服务器,能缓存打开的文件描述符
- http、smtp、pop3协议的反向代理服务器
- 缓存加速、负载均衡
- 支持FastCGI(fpm,LNMP),uWSGI(Python)等
- 模块化(非DSO机制),过滤器zip、SSI及图像的大小调整
- 支持SSL
nginx的安装与配置
nginx的安装
//创建系统用户nginx [root@localhost ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make wget [root@localhost ~]# yum -y groups mark install 'Development Tools //下载安装包 [root@localhost ~]# wget http://nginx.org/download/nginx-1.20.0.tar.gz //创建系统用户 [root@localhost ~]# useradd -r -M -s /sbin/nologin nginx //创建日志存放目录 [root@localhost ~]# mkdir -p /var/log/nginx [root@localhost ~]# chown -R nginx.nginx /var/log/nginx //编译安装 [root@localhost src]# tar xf nginx-1.20.0.tar.gz [root@localhost src]# cd nginx-1.20.0 [root@localhost nginx-1.20.0]# ./configure \ > --prefix=/usr/local/nginx \ > --user=nginx \ > --group=nginx \ > --with-debug \ > --with-http_ssl_module \ > --with-http_realip_module \ > --with-http_image_filter_module \ > --with-http_gunzip_module \ > --with-http_gzip_static_module \ > --with-http_stub_status_module \ > --http-log-path=/var/log/nginx/access.log \ > --error-log-path=/var/log/nginx/error.log //配置环境变量 [root@localhost nginx-1.20.0]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh [root@localhost nginx-1.20.0]# . /etc/profile.d/nginx.sh //启动服务 [root@localhost nginx-1.20.0]# nginx [root@localhost nginx-1.20.0]# ss -antl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:80 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22
nginx.conf配置详解
nginx.conf的内容分为以下几段:
- main配置段:全局配置段。其中main配置段中可能包含event配置段
- event {}:定义event模型工作特性
- http {}:定义http协议相关的配置
配置指令:要以分号结尾,语法格式如下:
derective value1 [value2 ...];
支持使用变量:
- 内置变量:模块会提供内建变量定义
- 自定义变量:
set var_name value
用于调试、定位问题的配置参数
daemon {on|off}; //是否以守护进程方式运行nginx,调试时应设置为off
master_process {on|off}; //是否以master/worker模型来运行nginx,调试时可以设置为off
error_log 位置 级别; //配置错误日志
error_log里的位置和级别能有以下可选项:
| 位置 | 级别 |
|---|---|
| file stderr syslog:server=address[,parameter=value] memory:size |
debug:若要使用debug级别,需要在编译nginx时使用--with-debug选项 info notice warn error crit alert emerg |
正常运行必备的配置参数
user USERNAME [GROUPNAME]; //指定运行worker进程的用户和组 pid /path/to/pid_file; //指定nginx守护进程的pid文件 worker_rlimit_nofile number; //设置所有worker进程最大可以打开的文件数,默认为1024 worker_rlimit_core size; //指明所有worker进程所能够使用的总体的最大核心文件大小,保持默认即可
优化性能的配置参数
worker_processes n; //启动n个worker进程,这里的n为了避免上下文切换,通常设置为cpu总核心数-1或等于总核心数 worker_cpu_affinity cpumask ...; //将进程绑定到某cpu中,避免频繁刷新缓存 //cpumask:使用8位二进制表示cpu核心,如: 0000 0001 //第一颗cpu核心 0000 0010 //第二颗cpu核心 0000 0100 //第三颗cpu核心 0000 1000 //第四颗cpu核心 0001 0000 //第五颗cpu核心 0010 0000 //第六颗cpu核心 0100 0000 //第七颗cpu核心 1000 0000 //第八颗cpu核心 timer_resolution interval; //计时器解析度。降低此值,可减少gettimeofday()系统调用的次数 worker_priority number; //指明worker进程的nice值
事件相关的配置:event{}段中的配置参数
accept_mutex {off|on}; //master调度用户请求至各worker进程时使用的负载均衡锁;on表示能让多个worker轮流地、序列化地去响应新请求
lock_file file; //accept_mutex用到的互斥锁锁文件路径
use [epoll | rtsig | select | poll]; //指明使用的事件模型,建议让nginx自行选择
worker_connections #; //每个进程能够接受的最大连接数
网络连接相关的配置参数
keepalive_timeout number; //长连接的超时时长,默认为65s keepalive_requests number; //在一个长连接上所能够允许请求的最大资源数 keepalive_disable [msie6|safari|none]; //为指定类型的UserAgent禁用长连接 tcp_nodelay on|off; //是否对长连接使用TCP_NODELAY选项,为了提升用户体验,通常设为on client_header_timeout number; //读取http请求报文首部的超时时长 client_body_timeout number; //读取http请求报文body部分的超时时长 send_timeout number; //发送响应报文的超时时长
fastcgi的相关配置参数
LNMP:php要启用fpm模型
配置示例如下:
location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; //定义反向代理 fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; }
常需要进行调整的参数
- worker_processes
- worker_connections
- worker_cpu_affinity
- worker_priority
nginx平滑升级
流程:
- 获取原编译参数
- 下载需要的模块(GitHub等网站拉取)
- 重新编译,加上--add-module=/MODULE_PATH
- 备份程序并停止服务
- 覆盖新程序
- 启动新程序
[root@nginx ~]# nginx -V nginx version: nginx/1.20.0 built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) built with OpenSSL 1.1.1g FIPS 21 Apr 2020 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log # 下载新模块echo-nginx-module [root@nginx ~]# cd /usr/src/ [root@nginx src]# wget https://github.com/openresty/echo-nginxmodule/archive/refs/heads/master.zip [root@nginx src]# unzip master.zip [root@nginx src]# ls debug echo-nginx-module-master kernels master.zip nginx-1.20.0 nginx1.20.0.tar.gz # 重新编译软件 [root@nginx src]# cd nginx-1.20.0/ [root@nginx nginx-1.20.0]# ./configure \ --prefix=/usr/local/nginx \ --user=nginx \ --group=nginx \ --with-debug \ --with-http_ssl_module \ --with-http_realip_module \ --with-http_image_filter_module \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_stub_status_module \ --http-log-path=/var/log/nginx/access.log \ --error-log-path=/var/log/nginx/error.log \ --add-module=/usr/src/echo-nginx-module-master [root@nginx nginx-1.20.0]# make # 停止服务、备份原程序、将原程序替换 并 启动新程序 [root@nginx ~]# nginx -s stop && \ mv /usr/local/nginx/sbin/nginx /tmp/ && \ cp /usr/src/nginx-1.20.0/objs/nginx /usr/local/nginx/sbin/ && \ /usr/local/nginx/sbin/nginx # 检查是否升级成功 [root@nginx ~]# nginx -V nginx version: nginx/1.20.0 built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) built with OpenSSL 1.1.1g FIPS 21 Apr 2020 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=/usr/src/echo-nginx-module-maste
测试新模块
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { echo "this is a test!"; } # 检查语法是否有误 [root@nginx ~]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok验证 nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@nginx ~]# nginx -s reload
nginx作为web服务器时使用的配置:http{}段的配置参数
http{...}:配置http相关,由ngx_http_core_module模块引入。nginx的HTTP配置主要包括四个区块,结构如下:
http {//协议级别
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
gzip on;
upstream {//负载均衡配置
...
}
server {//服务器级别,每个server类似于httpd中的一个<VirtualHost>
listen 80;
server_name localhost;
location / {//请求级别,类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系
root html;
index index.html index.htm;
}
}
}
http{}段配置:
server { listen 80; server_name www.xxx.com; root "/vhosts/web"; }
listen:指定监听的地址和端口
listen address[:port];
listen port;
server_name 后面可跟多个主机,名称可使用正则表达式或通配符
当有多个server时,匹配顺序如下: 先做精确匹配检查 左侧通配符匹配检查,如*.idfsoft.com 右侧通配符匹配检查,如mail.* 正则表达式匹配检查,如~ ^.*\.idfsoft\.com$ default_server
root path 设置资源路径映射,用于指明请求的URL所对应的资源所在的文件系统上的起始路径
alias path 用于location配置段,定义路径别名
error_page code [...] [=code] URI | @name 根据http响应状态码来指明特用的错误页面,例如 error_page 404 /404_customed.html
[=code]:以指定的响应码进行响应,而不是默认的原来的响应,默认表示以新资源的响应码为其响应码,例如 error_page 404 =200 /404_customed.html
location区段,通过指定模式来与客户端请求的URI相匹配
#功能:允许根据用户请求的URI来匹配定义的各location,匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能
#语法:location [ 修饰符 ] pattern {......}
常用修饰符说明:
| 修饰符 | 功能 |
|---|---|
| = | 精确匹配 |
| ~ | 正则表达式模式匹配,区分大小写 |
| ~* | 正则表达式模式匹配,不区分大小写 |
| ^~ | 前缀匹配,类似于无修饰符的行为,也是以指定模块开始,不同的是,如果模式匹配,那么就停止搜索其他模式了,不支持正则表达式 |
| @ |
定义命名location区段,这些区段客户端不能访问,只可以由内部产生的请求来访问,如try_files或error_page等 |
nginx平滑升级过程:
1.获取之前的编译参数
2.下载新模块
3.重新编译软件,--add-module=新模块的路径
4.编译,替换主程序(原程序先备份)
5.启动新程序
Nginx信号简介
主进程支持的信号
TERM,INT: 立刻退出QUIT: 等待工作进程结束后再退出KILL: 强制终止进程HUP: 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程。USR1: 重新打开日志文件USR2: 启动新的主进程,实现热升级WINCH: 逐步关闭工作进程
工作进程支持的信号
TERM,INT: 立刻退出QUIT: 等待请求处理结束后再退出USR1: 重新打开日志文件
[root@localhost ~]# wget https://github.com/openresty/echo-nginx-module/archive/refs/heads/master.zip [root@localhost ~]# unzip master.zip [root@localhost ~]# nginx -V nginx version: nginx/1.20.0 built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) built with OpenSSL 1.1.1g FIPS 21 Apr 2020 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log [root@localhost ~]# tar -xf nginx-1.20.0.tar.gz [root@localhost nginx-1.20.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=../echo-nginx-module-master/ [root@localhost nginx-1.20.0]# make //替换主程序 [root@localhost nginx-1.20.0]# mv /usr/local/nginx/sbin/nginx /opt/nginx_$(date +%F) [root@localhost nginx-1.20.0]# mv objs/nginx /usr/local/nginx/sbin/ [root@localhost nginx-1.20.0]# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` [root@localhost nginx-1.20.0]# nginx -V nginx version: nginx/1.20.0 built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) built with OpenSSL 1.1.1g FIPS 21 Apr 2020 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=../echo-nginx-module-master/
没有修饰符表示必须以指定模式开始 如:
server { listen 80; server_name localhost; location /test { echo "11111"; }
那么有几种正确匹配的方式例如:(其中ip就是指IP地址)
- http://ip/test
- http://ip/test?p1=11?p2=22
- http://ip/test/

=:表示必须与指定的模式精确匹配,如:
server { listen 80; server_name localhost; location = /test { echo "11111"; }
那么如下内容就可正确匹配:
- http://ip/test
- http://ip/test?p1=11?p2=22

~:表示指定的正则表达式要区分大小写,如:
server { listen 80; server_name localhost; location ~ /test$ { echo "2222"; }
那么如下内容就可正确匹配:
- http://ip/test
- http://ip/test?p1=11?p2=22
如下内容则无法匹配:
- http://ip/test/
- http://ip/TEST
- http://ip/testabc

~*:表示指定的正则表达式不区分大小写,如:
server { listen 80; server_name localhost; location ~* /test$ { echo "3333"; }
那么如下内容就可正确匹配:
- http://ip/test
- http://ip/test?p1=11?p2=22
- http://ip/TEST
如下内容则无法匹配:
- http://ip/test/
- http://ip/testabc

~:类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,则停止搜索其他模式
查找顺序和优先级:由高到底依次为
- 带有
=的精确匹配优先 - 正则表达式按照他们在配置文件中定义的顺序
- 带有
^~修饰符的,开头匹配 - 带有
~或~*修饰符的,如果正则表达式与URI匹配 - 没有修饰符的精确匹配
优先级次序如下:
( location = 路径 ) --> ( location ^~ 路径 ) --> ( location ~ 正则 ) --> ( location ~* 正则 ) --> ( location 路径 )
访问控制
用于location段
allow:设定允许哪台或哪些主机访问,多个参数间用空格隔开
deny:设定禁止哪台或哪些主机访问,多个参数间用空格隔开
示例:
allow 192.168.1.1/32 172.16.0.0/16; deny all;
拒绝本机访问nginx状态页面

基于用户认证
auth_basic "欢迎信息"; auth_basic_user_file "/path/to/user_auth_file"
授权用户
[root@nginx ssl]# yum -y install httpd-tools [root@nginx conf]# htpasswd -c -m .user_auth_file tom New password: Re-type new password: Adding password for user tom [root@nginx conf]# ls -a | grep .user_auth_file .user_auth_file [root@nginx conf]# cat .user_auth_file tom:$apr1$OhUzbIS3$f1MpCShCyvCYtMUIn6BMD1
配置(必须要用绝对路径)
[root@nginx conf]# vim nginx.conf location /status { stub_status on; auth_basic "欢迎查看"; auth_basic_user_file "/usr/local/nginx/conf/.user_auth_file"; } [root@nginx conf]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@nginx conf]# nginx -s reload

https配置
生成私钥,生成证书签署请求并获得证书,然后在nginx.conf中配置如下内容:
server { listen 443 ssl; server_name www.idfsoft.com; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.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; } }
使用zabbix监控nginx状态
编写监控脚本
[root@nginx ~]# cat /usr/local/etc/zabbix_scripts/nginx_status.sh #!/bin/bash case $1 in Active) /usr/bin/curl -s 127.0.0.1/status | awk 'NR==1 {print $3}' ;; reading) /usr/bin/curl -s 127.0.0.1/status | grep 'Reading'|cut -d" " -f2 ;; Writing) /usr/bin/curl -s 127.0.0.1/status | grep 'Writing'|cut -d" " -f4 ;; Waiting) /usr/bin/curl -s 127.0.0.1/status | grep 'Waiting'|cut -d" " -f6 ;; acceptes) /usr/bin/curl -s 127.0.0.1/status | awk 'NR==3{print $1}' ;; handled) /usr/bin/curl -s 127.0.0.1/status | awk 'NR==3{print $2}' ;; requests) /usr/bin/curl -s 127.0.0.1/status | awk 'NR==3{print $3}' ;; *) echo "Usage: $0 {Active|reading|Writing|Waiting|acceptes|handled|requests}" ;; esac [root@nginx ~]# vim /usr/local/etc/zabbix_agentd.conf UserParameter=nginx_check_status[*],/usr/local/etc/zabbix_scripts/nginx_status.sh $1
zabbix server端测试
[root@localhost etc]# zabbix_get -s 192.168.122.131 -k 'nginx_check_status[Active]' 1 [root@localhost etc]# zabbix_get -s 192.168.122.131 -k 'nginx_check_status[Writing]' 1
在Zabbix的WEB页面添加监控项
添加主机组
Configuration —— Host groups —— 右上角 Create host group

添加主机组

添加监控项

rewrite (url 重写)
语法:rewrite regex replacement flag;,如:
将url 开头为/imgs 下所有的以.jpg结尾的文件路径全部转成 /images下所有.jpg结尾的文件
rewrite ^/imgs/(.*\.jpg)$ /images/$1 break;
在nginx网页访问目录下创建一个目录,在里面放入一张图片
[root@nginx images]# pwd /usr/local/nginx/html/images [root@nginx images]# ls 'u=1667287789,917956653&fm=26&gp=0.jpg'

将原图片存放位置修改名字
[root@nginx imgs]# cd .. [root@nginx html]# mv imgs images [root@nginx html]# ls 50x.html images index.html test

将rewrite机制写入配置文件中
location /imgs { rewrite ^/imgs/(.*\.jpg)$ /images/$1 break; }

还有一种写法
rewrite ^/images/(.*\.jpg)$ www.baidu.com break; location /imgs { rewrite ^/imgs/(.*\.jpg)$ http://www.baidu.com break; } [root@nginx html]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@nginx html]# nginx -s reload

直接访问到了百度
常见的flag
| flag | 作用 |
|---|---|
| last | 基本上都用这个flag,表示当前的匹配结束,继续下一个匹配,最多匹配10个到20个 一旦此rewrite规则重写完成后,就不再被后面其它的rewrite规则进行处理 而是由UserAgent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程 |
| break | 中止Rewrite,不再继续匹配 一旦此rewrite规则重写完成后,由UserAgent对新的URL重新发起请求, 且不再会被当前location内的任何rewrite规则所检查 |
| redirect | 以临时重定向的HTTP状态302返回新的URL |
| permanent | 以永久重定向的HTTP状态301返回新的URL |
rewrite模块的作用是用来执行URL重定向。这个机制有利于去掉恶意访问的url,也有利于搜索引擎优化(SEO)
nginx使用的语法源于Perl兼容正则表达式(PCRE)库,基本语法如下:
| 标识符 | 意义 |
|---|---|
| ^ | 必须以^后的实体开头 |
| $ | 必须以$前的实体结尾 |
| . | 匹配任意字符 |
| [] | 匹配指定字符集内的任意字符 |
| [^] | 匹配任何不包括在指定字符集内的任意字符串 |
| | | 匹配 | 之前或之后的实体 |
| () | 分组,组成一组用于匹配的实体,通常会有 | 来协助 |
捕获子表达式,可以捕获放在()之间的任何文本,比如:
^(hello|sir)$ //字符串为“hello sir”捕获的结果:$1=hello$2=sir //这些被捕获的数据,在后面就可以当变量一样使用了
redirect
[root@nginx html]# vim /usr/local/nginx/conf/nginx.conf location /imgs { rewrite ^/imgs/(.*\.jpg)$ /images/$1 redirect; } [root@nginx html]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@nginx html]# nginx -s reload

permanent.
[root@nginx html]# vim /usr/local/nginx/conf/nginx.conf location /imgs { rewrite ^/imgs/(.*\.jpg)$ /images/$1 permanent; } [root@nginx html]# nginx -s reload

last
[root@nginx html]# vim /usr/local/nginx/conf/nginx.conf location /imgs { rewrite ^/imgs/(.*\.jpg)$ /images/$1 last; } location /images { rewrite ^/images/(.*\.jpg)$ http://www.baidu.com last; } [root@nginx html]# nginx -s reload

刷新直接跳转到了百度
break
[root@nginx html]# vim /usr/local/nginx/conf/nginx.conf location /imgs { rewrite ^/imgs/(.*\.jpg)$ /images/$1 break; } location /images { rewrite ^/images/(.*\.jpg)$ http://www.baidu.com last; } [root@nginx html]# nginx -s reload
if
语法:if (condition) {...}
应用场景:
- server段
- location段
常见的condition
- 变量名(变量值为空串,或者以“0”开始,则为false,其它的均为true)
- 以变量为操作数构成的比较表达式(可使用=,!=类似的比较操作符进行测试)
- 正则表达式的模式匹配操作
- ~:区分大小写的模式匹配检查
- ~*:不区分大小写的模式匹配检查
- !~和!~*:对上面两种测试取反
- 测试指定路径为文件的可能性(-f,!-f)
- 测试指定路径为目录的可能性(-d,!-d)
- 测试文件的存在性(-e,!-e)
- 检查文件是否有执行权限(-x,!-x)
基于浏览器实现分离案例
if ($http_user_agent ~ Firefox) { rewrite ^(.*)$ /firefox/$1 break; } if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } if ($http_user_agent ~ Chrome) { rewrite ^(.*)$ /chrome/$1 break; }
防盗链案例
location ~* \.(jpg|gif|jpeg|png)$ { valid_referers none blocked www.idfsoft.com; if ($invalid_referer) { rewrite ^/ http://www.idfsoft.com/403.html; } }
反向代理与负载均衡
nginx通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离以及负载均衡,从而大大提高服务器的处理能力。
nginx实现动静分离,其实就是在反向代理的时候,如果是静态资源,就直接从nginx发布的路径去读取,而不需要从后台服务器获取了。
但是要注意,这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync做服务端自动同步或者使用NFS、MFS分布式共享存储。
Http Proxy模块,功能很多,最常用的是proxy_pass和proxy_cache
如果要使用proxy_cache,需要集成第三方的ngx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候去做,如:
./configure --add-module=../ngx_cache_purge-1.0 ......
nginx通过upstream模块来实现简单的负载均衡,upstream需要定义在http段内
在upstream段内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,如:
环境
| 系统/软件 | IP |
| redhat8 /nginx | 192.168.100.145 |
| redhat8 /httpd | 192.168.100.100 |
| redhat8 /httpd | 192.168.100.200 |
//写一个测试文件到第一台机 [root@test1 ~]# echo "test1" > /var/www/html/index.html [root@test1 ~]# systemctl start httpd //写一个测试文件到第二台机 [root@test2 ~]# echo "test2" > /var/www/html/index.html [root@test2 ~]# systemctl start httpd [root@test1 ~]# curl 192.168.100.100 test1 [root@test2 ~]# curl 192.168.100.200 test2
准备工作已经做完,开始配置nginx
upstream index.html { server 192.168.100.100; server 192.168.100.200; } server { listen 80; server_name localhost; location / { proxy_pass http://index.html; }
[root@nginx html]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@nginx html]# nginx -s reload


upstream index.html { server 192.168.100.100 weight=2; server 192.168.100.200; } [root@nginx html]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@nginx html]# nginx -s reload
前两次访问的是test1,后一次就是test2了


因为他们的端口号都是一致的,所以不用加端口号,不一样的话就需要加上端口号;不然就会触发nginx的健康检查机制
案例
第一台机修改配置监听端口80改成8080
[root@nginx nginx]# vim /etc/httpd/conf/httpd.conf [root@nginx nginx]# systemctl restart httpd [root@nginx nginx]# ss -antl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 *:8080 *:* LISTEN 0 128 [::]:22 [::]:*

一直访问的rs2,因为他访问不到rs1的80端口。
//将nginx配置文件中ip后加上端口号 upstream index.html { server 192.168.100.100:8080 weight=2; server 192.168.100.200:80; } [root@nginx nginx]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@nginx nginx]# nginx -s reload


ip_hash;一台主机分配一个请求
//加上ip_hash upstream index.html { ip_hash; server 192.168.100.100:8080 weight=2; server 192.168.100.200:80; } [root@nginx nginx]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@nginx nginx]# nginx -s reload
[root@nginx html]# curl 192.168.100.145 test1 [root@nginx html]# curl 192.168.100.145 test1 [root@nginx html]# curl 192.168.100.145 test1 [root@nginx html]# curl 192.168.100.145 test1 [root@nginx html]# curl 192.168.100.145 test1
一直访问的test1
注意:这个方法本质还是轮询,而且由于客户端的ip可能是不断变化的,比如动态ip,代理,FQ等,因此ip_hash并不能完全保证同一个客户端总是由同一个服务器来处理。
定义好upstream后,需要在server段内添加如下内容:
server { location / { proxy_pass http://index.html; } }
浙公网安备 33010602011771号