一、nginx简介
Nginx:engine X ,2002年开发,分为社区版和商业版(nginx plus ) 2019年3月11日 F5 Networks 6.7亿美元的价格收购
Nginx是免费的、开源的、高性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理服务器
- 解决C10K问题(10K Connections)
- Nginx官网:http://nginx.org nginx
其它的二次发行版: Tengine:由淘宝网发起的Web服务器项目。
它在Nginx的基础上,针对大访问量网站的需求,添加 了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了 很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。从2011年12月开始, Tengine成为一个开源项目官网:http://tengine.taobao.org/
OpenResty:基于 Nginx 与 Lua 语言的高性能 Web 平台, 章亦春团队开发,官网:http://openr esty.org/cn/
1.1功能
- 静态的web资源服务器html,图片,js,css,txt等静态资源
- http/https协议的反向代理
- 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
- tcp/udp协议的请求转发(反向代理)
- imap4/pop3协议的反向代理
1.2基础特性
- 模块化设计,较好的扩展性
- 高可靠性
- 支持热部署:不停机更新配置文件,升级版本,更换日志文件
- 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
- event-driven,aio,mmap,sendfile
二、Nginx 架构和进程
2.1Nginx 进程结构
web请求处理机制
- 多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直 到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务 器资源耗尽而无法提供请求
- 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程和此客 户端进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器 对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可 以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作 了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
Nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成。
2.2Nginx 进程间通信
工作进程是由主进程生成的,主进程使用fork()函数,在Nginx服务器启动过程中主进程根据配置文件决 定启动工作进程的数量,然后建立一张全局的工作表用于存放当前未退出的所有的工作进程,主进程生 成工作进程后会将新生成的工作进程加入到工作进程表中,并建立一个单向的管道并将其传递给工作进 程,该管道与普通的管道不同,它是由主进程指向工作进程的单向通道,包含了主进程向工作进程发出 的指令、工作进程ID、工作进程在工作进程表中的索引和必要的文件描述符等信息。
主进程与外界通过信号机制进行通信,当接收到需要处理的信号时,它通过管道向相关的工作进程发送 正确的指令,每个工作进程都有能力捕获管道中的可读事件,当管道中有可读事件的时候,工作进程就 会从管道中读取并解析指令,然后采取相应的执行动作,这样就完成了主进程与工作进程的交互。
2.3Nginx 模块介绍
nginx 有多种模块
- 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件 驱动机制 、进程管理等核心功能
- 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应 头设置 等等
- 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如: Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
- 邮件服务模块:主要用于支持 Nginx 的邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
- Stream服务模块: 实现反向代理功能,包括TCP协议代理
- 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支 持等
- nginx高度模块化,但其模块早期不支持DSO机制;1.9.11 版本支持动态装载和卸载
模块分类:
核心模块:core module 标准模块: HTTP 模块: ngx_http_* HTTP Core modules #默认功能 HTTP Optional modules #需编译时指定 Mail 模块: ngx_mail_* Stream 模块 ngx_stream_* 第三方模块
三、Nginx 安装与配置
3.1安装
Nginx版本
- Mainline version 主要开发版本,一般为奇数版本号,比如1.19
- Stable version 当前最新稳定版,一般为偶数版本,如:1.20
- Legacy versions 旧的稳定版,一般为偶数版本,如:1.18
Nginx安装可以使用yum或源码安装,但是推荐使用源码编译安装
- yum的版本比较旧
- 编译安装可以更方便自定义相关路径
- 使用源码编译可以自定义相关功能,更方便业务的上的使用
Nginx 编译安装
编译器介绍
源码安装需要提前准备标准的编译器,GCC的全称是(GNU Compiler collection),其有GNU开发,并以 GPL即LGPL许可,是自由的类UNIX即苹果电脑Mac OS X操作系统的标准编译器,因为GCC原本只能处理C语 言,所以原名为GNU C语言编译器,后来得到快速发展,可以处理C++,Fortran,pascal,objective C, java以及Ada等其他语言,此外还需要Automake工具,以完成自动创建Makefile的工作,Nginx的一些模块 需要依赖第三方库,比如: pcre(支持rewrite),zlib(支持gzip模块)和openssl(支持ssl模块) 等
安装示例:
#先下载要用到的包 dnf install gcc pcre-devel zlib-devel openssl-devel -y #解压我们放到其中的压缩包 tar zxf nginx-1.24.0.tar.gz #到目录下 cd /nginx/nginx-1.24.0/ #添加 useradd -s /sbin/nologin -M nginx #解析 ./configure --prefix=/usr/local/nginx \ --user=nginx \ # 指定nginx运行用户 --group=nginx \ # 指定nginx运行组 --with-http_ssl_module \ # 支持https:// --with-http_v2_module \ # 支持http版本2 --with-http_realip_module \ # 支持ip透传 --with-http_stub_status_module \ # 支持状态页面 --with-http_gzip_static_module \ # 支持压缩 --with-pcre \ # 支持正则 --with-stream \ # 支持tcp反向代理 --with-stream_ssl_module \ # 支持tcp的ssl加密 --with-stream_realip_module # 支持tcp的透传ip make && make install
[root@Nginx nginx-1.24.0]# ls /usr/local/nginx/ conf html logs sbin
验证版本及编译参数
写入
source ~/.bash_profile
就可以通过
nginx -V #详细信息 nginx -v #版本信息
3.2nginx的平滑升级及版本回滚
有时候我们需要对Nginx版本进行升级以满足对其功能的需求,例如添加新模块,需要新功能,而此时 Nginx又在跑着业务无法停掉,这时我们就可能选择平滑升级
- 将旧Nginx二进制文件换成新Nginx程序文件(注意先备份)
- 向master进程发送USR2信号 master进程修改pid文件名加上后缀.oldbin,成为nginx.pid.oldbin master
- 进程用新Nginx文件启动新master进程成为旧master的子进程,系统中将有新旧两个Nginx主 进程共同提供Web服务,当前新的请求仍然由旧Nginx的worker进程进行处理,将新生成的master进 程的PID存放至新生成的pid文件nginx.pid
- 向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止
- 向旧master进程发送QUIT信号,关闭老master,并删除Nginx.pid.oldbin文件
- 如果发现升级有问题,可以回滚∶向老master发送HUP,向新master发送QUIT
平滑升级和回滚案例
#解压 tar zxf nginx-1.26.1.tar.gz #切换目录 cd /nginx/nginx-1.26.2/
导入文件包
#解压 tar zxf echo-nginx-module-0.63.tar.gz
#解析 ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --add-module=/nginx/echo-nginx-module-0.63 --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
平滑
查看版本信息
ll objs/nginx /usr/local/nginx/sbin/nginx
#把之前的旧版的nginx命令备份 cd /usr/local/nginx/sbin/ cp nginx nginx.24 #把新版本的nginx命令复制过去 \cp -f /root/nginx/nginx-1.26.1/objs/nginx /usr/local/nginx/sbin #检测一下有没有问题 nginx -t
查看版本进程号
ps aux | grep nginx
kill -UER2 13116 #USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的nginx #此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80 #此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。
#查看生效版本 curl -I localhost
#回收旧版本 kill -WINCH 48732 #然后再次查看 curl -I localhost
回滚
如果升级的版本发现问题需要回滚,可以重新拉起旧版本的worker
cd /usr/local/nginx/sbin/ cp nginx nginx.26 mv nginx.24 nginx mv: overwrite 'nginx'? y ps aux | grep nginx kill -HUP 13116 kill -WINCH 167455 curl -I localhost
3.3nginx命令参数
-?,-h : this help -v : show version and exit -V : show version and configure options then exit #显示版本和编译参数 -t : test configuration and exit #测试配置文件是否异 -T : test configuration, dump it and exit #测试并打印 -q : suppress non-error messages during configuration testing #静默模式 -s signal : send signal to a master process: stop, quit, reopen, reload #发送信号,reload信号 会生成新的worker,但master不会重新生成 -p prefix : set prefix path (default: /etc/nginx/) #指定Nginx 目录 -c filename : set configuration file (default: /etc/nginx/nginx.conf) #配置文件路径 -g directives : set global directives out of configuration file #设置全局指令,注意和配置文件不要同时配置,否则冲突
nginx -s stop #关闭nginx nginx -s reload #刷新 nginx -g "worker_processes 6;" #文件中一定要没有此参数
这一行注释掉
vim /usr/local/nginx/conf/nginx.conf
3.4nginx启动脚本编写
systemctl daemon-reload systemctl start nginx
一定要把nginx关掉才写
3.5nginx全局参数优化
Nginx的配置文件的组成部分:
- 主配置文件:nginx.conf
- 子配置文件: include conf.d/*.conf
- fastcgi, uwsgi,scgi 等协议相关的配置文件
- mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮
- 件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某
- 种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动
- 使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
nginx 配置文件格式说明配置文件由指令与指令块构成 每条指令以;分号结尾,指令与值之间以空格符号分隔 可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐 指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块 include语句允许组合多个配置文件以提升可维护性 使用#符号添加注释,提高可读性 使用$符号使用变量 部分指令的参数支持正则表达式
Nginx 主配置文件的配置指令方式:
directive value [value2 ...]; 注意 (1) 指令必须以分号结尾 (2) 支持使用配置变量 内建变量:由Nginx模块引入,可直接引用 自定义变量:由用户使用set命令定义,格式: set variable_name value; 引用变量:$variable_name
主配置文件结构:四部分
main block:主配置段,即全局配置段,对http,mail都有效 #事件驱动相关的配置 event { ... } #http/https 协议相关配置段 http { ... } #默认配置文件不包括下面两个块 #mail 协议相关配置段 mail { ... } #stream 服务器相关配置段 stream { ... }
全局配置
Main 全局配置段常见的配置指令分类
- 正常运行必备的配置
- 优化性能相关的配置
- 用于调试及定位问题相关的配置
- 事件驱动相关的配置
3.6location用法
- 在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;
- ngnix会根据用户请求的URI来检查定义的所有location,按一定的优先级找出一个最佳匹配,
- 而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最 高的一个uri
- uri是用户请求的字符串,即域名后面的web文件路径
- 然后使用该location模块中的正则url和字符串,如果匹配成功就结束搜索,并使用此location处理 此请求。
#语法规则: location [ = | ~ | ~* | ^~ ] uri { ... } = #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求 ^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头 #对uri的最左边部分做匹配检查,不区分字符大小写 ~ #用于标准uri前,表示包含正则表达式,并且区分大小写 ~* #用于标准uri前,表示包含正则表达式,并且不区分大写 不带符号 #匹配起始于此uri的所有的uri \ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号 #匹配优先级从高到低: =, ^~, ~/~*, 不带符号
匹配案例-优先级
#匹配优先级:=, ^~, ~/~*,/ location优先级:(location =) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 完整路径) > (location 部分起始路径) > (/)
3.7nginx的用户认证
由 ngx_http_auth_basic_module 模块提供此功能
3.8自定义日志
#重启nginx并访问不存在的页面进行测试并验证是在指定目录生成新的日志文件
3.9nginx文件检测
try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如 果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一 个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内 部500错误。
语法格式
Syntax: try_files file ... uri; try_files file ... =code; Default: — Context: server, location
:如果不存在页面, 就转到default.html页面
3.10nginx长链接控制
keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长,0表示禁止长连接,默认为75s #通常配置在http字段作为站点全局配置 keepalive_requests 数字; #在一次长连接上所允许请求的资源的最大数量 #默认为100次,建议适当调大,比如:500
keepalive_requests 3; keepalive_timeout 65 60; #开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会被断 开,第二个数字60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时 间。 Keep-Alive:timeout=60 #浏览器收到的服务器返回的报文 #如果设置为0表示关闭会话保持功能,将如下显示: #Connection:close 浏览器收到的服务器返回的报文
3.11nginx下载服务器
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 4k; #也可以通变量限速,单位B/s,同时设置,此项优级高.
实现下载站点
cp /root/anaconda-ks.cfg /data/web/download
3.12状态页
- 基于nginx 模块 ngx_http_stub_status_module 实现,
- 在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module
- 否则配置完成之后监测会是提示法错误
注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态
配置示例:
vim /usr/local/nginx/conf.d/status.conf
3.13nginx的压缩功能
Nginx支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文 件大小将比源文件显著变小,样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相 应的CPU资源。
Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module,默认是内置模块
配置指令如下:
#启用或禁用gzip压缩,默认关闭 gzip on | off; #压缩比由低到高从1到9,默认为1,值越高压缩后文件越小,但是消耗cpu比较高。基本设定未4或者5 gzip_comp_level 4; #禁用IE6 gzip功能,早期的IE6之前的版本不支持压缩 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; #预压缩,即直接从磁盘找到对应文件的gz后缀的式的压缩文件返回给用户,无需消耗服务器CPU #注意: 来自于ngx_http_gzip_static_module模块 gzip_static on | off;
测试
3.14nginx的内建变量
- nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
- 变量可以分为内置变量和自定义变量
- 内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值
常用内置变量
$remote_addr; #存放了客户端的地址,注意是客户端的公网IP $args; #变量中存放了URL中的所有参数 #例如:https://search.jd.com/Search?keyword=手机&enc=utf-8 #返回结果为: keyword=手机&enc=utf-8 $is_args #如果有参数为? 否则为空 $document_root; #保存了针对当前资源的请求的系统根目录,例如:/webdata/nginx/timinglee.org/lee。 $document_uri; #保存了当前请求中不包含参数的URI,注意是不包含请求的指令 #比如:http://lee.timinglee.org/var?\id=11111会被定义为/var #返回结果为:/var $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请求生成的文件绝对路径, #如:webdata/nginx/timinglee.org/lee/var/index.html $request_uri; #包含请求参数的原始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; #虚拟主机的端口号 $http_user_agent; #客户端浏览器的详细信息 $http_cookie; #客户端的所有cookie信息 $cookie_<name> #name为任意请求报文首部字部cookie的key名 $http_<name> #name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有 横线需要替换为下划线 #示例: echo $http_user_agent; echo $http_host; $sent_http_<name> #name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有 问题 echo $sent_http_server; $arg_<name> #此变量存放了URL中的指定参数,name为请求url中指定的参数 echo $arg_id;
3.15Nginx Rewrite 相关功能
- Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求
- 此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库
- rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能
- 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问
- 另外还可以在一定程度上提高网站的安全性。
3.15.1if 指令
用于条件匹配判断,并根据条件判断结果选择不同的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
3.15.2set 指令
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key
另外set定义格式为set $key value,value可以是text, variables和两者的组合。
3.15.3break 指令
- 用于中断当前相同作用域(location)中的其他Nginx配置
- 与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效
- 位于后面的 ngx_http_rewrite_module 模块中指令就不再执行
- Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置
- 该指令可以在server块和locationif块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行ngx_http_rewrite_module 模块的指令,其它指令还会执行
3.15.4return 指令
return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重 定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配 置都将不被执行,return可以在server、if 和 location块进行配置
语法格式:
return code; #返回给客户端指定的HTTP状态码 return code [text]; #返回给客户端的状态码及响应报文的实体内容 #可以调用变量,其中text如果有空格,需要用单或双引号 return code URL; #返回给客户端的URL地址
3.15.5rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配, rewrite主要是针对用户请求的URL或者是URI做具体处理
语法格式 :
rewrite regex replacement [flag];
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成 后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的 标志位用于控制此循环机制
如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301
正则表达式格式
. #匹配除换行符以外的任意字符 \w #匹配字母或数字或下划线或汉字 \s #匹配任意的空白符 \d #匹配数字 \b #匹配单词的开始或结束 ^ #匹配字付串的开始 $ #匹配字符串的结束 * #匹配重复零次或更多次 + #匹配重复一次或更多次 ? #匹配重复零次或一次 (n) #匹配重复n次 {n,} #匹配重复n次或更多次 {n,m} #匹配重复n到m次 *? #匹配重复任意次,但尽可能少重复 +? #匹配重复1次或更多次,但尽可能少重复 ?? #匹配重复0次或1次,但尽可能少重复 {n,m}? #匹配重复n到m次,但尽可能少重复 {n,}? #匹配重复n次以上,但尽可能少重复 \W #匹配任意不是字母,数字,下划线,汉字的字符 \S #匹配任意不是空白符的字符 \D #匹配任意非数字的字符 \B #匹配不是单词开头或结束的位置 [^x] #匹配除了x以外的任意字符 [^lee] #匹配除了magedu 这几个字母以外的任意字符
3.15.6Nginx 防盗链
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标 记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗 链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
none: #请求报文首部没有referer首部, #比如用户直接在浏览器输入域名访问web网站,就没有referer信息。 blocked: #请求报文有referer首部,但无有效值,比如为空。 server_names: #referer首部中包含本主机名及即nginx 监听的server_name。 arbitrary_string: #自定义指定字符串,但可使用*作通配符。示例: *.timinglee.org www.timinglee.* regular expression: #被指定的正则表达式模式匹配到的字符串,要使用~开头,例如: ~.*\.timinglee\.com
示例:
3.16nginx的反向代理
反向代理: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协议或者tcp协议访问后端服务器
异构代理:用户访问的资源时需要经过处理后才能返回的,比如php,python,等等,这种访问资源需 要经过处理才能被访问
反向代理配置参数
#官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass proxy_pass; #用来设置将客户端请求转发给的后端服务器的主机 #可以是主机名(将转发至后端服务做为主机头首部)、IP地址:端口的方式 #也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持 #示例: location /web { index index.html; proxy_pass http://172.25.254.30:8080; proxy_pass http://172.25.254.40:8080/; } # http://nginx/web/index.html ==> http://1:8080 #重启Nginx测试访问效果: #curl -L http://www.timinglee.org/web #如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能使用uri #即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后 server { ... server_name HOSTNAME; location ~|~* /uri/ { proxy_pass http://host:port; #proxy_pass后面的url 不能加/ } ... } http://HOSTNAME/uri/ --> http://host/uri/
proxy_hide_header field; location /web { index index.html; proxy_pass http://10.0.0.18:8080/; proxy_hide_header ETag; }
示例:
3.17nginx的反向代理负载均衡
在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而 且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于ngx_http_upstream_module模块提 供服务器分组转发、权重分配、状态监测、调度算法等高级功能
http upstream配置参数
#自定义一组服务器,配置在http块内 upstream name { server ..... ...... } #示例 upstream backend { server backend1.example.com weight=5; server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; server backup1.example.com backup; } server address [parameters]; #配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。 #server支持的parameters如下: weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等 max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制 max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测 fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒 backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器 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
反向代理示例: 后端多台 web服务器
环境说明:
172.25.254.100 #Nginx 代理服务器 172.25.254.10 #后端web A,Apache部署 172.25.254.20 #后端web B,Apache部署
部署后端 Apache服务器
172.25.254.10: yum install httpd -y echo "web1 172.25.254.10" > /var/www/html/index.html systemctl enable --now httpd 172.25.254.20“ yum install httpd -y echo "web2 172.25.254.20" > /var/www/html/index.html systemctl enable --now httpd
部署 nginx
upstream webserver { server 172.25.254.20:8080 weight=1 fail_timeout=15s max_fails=3; server 172.25.254.30:80 weight=1 fail_timeout=15s max_fails=3; server 172.25.254.10:80 backup; } server { listen 80; server_name www.gxx.org; root /data/web/html; index index.html location ~ / { proxy_pass http://webserver; } }
3.18FastCGI
3.18.1简介
CGI的由来: 最早的Web服务器只能简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏 览器,也就是静态html文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动态技 术,比如像php(1995年)、java(1995)、python(1991)语言开发的网站,但是nginx/apache服务器并不 能直接运行 php、java这样的文件,apache实现的方式是打补丁,但是nginx缺通过与第三方基于协议实 现,即通过某种特定协议将客户端请求转发给第三方服务处理,第三方服务器会新建新的进程处理用户 的请求,处理完成后返回数据给Nginx并回收进程,最后nginx在返回给客户端,那这个约定就是通用网 关接口(common gateway interface,简称CGI),CGI(协议) 是web服务器和外部应用程序之间的接口 标准,是cgi程序和web服务器之间传递信息的标准化接口。
为什么会有FastCGI? 、
CGI协议虽然解决了语言解析器和 Web Server 之间通讯的问题,但是它的效率很低,因为 Web Server 每收到一个请求都会创建一个CGI进程,PHP解析器都会解析php.ini文件,初始化环境,请求结束的时候 再关闭进程,对于每一个创建的CGI进程都会执行这些操作,所以效率很低,而FastCGI是用来提高CGI性 能的,FastCGI每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请 求。这样的话每个请求都不用再重新创建一个进程了,大大提升了处理效率。
什么是PHP-FPM?
PHP-FPM(FastCGI Process Manager:
- FastCGI进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能。
- 进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自web server 的请求 worker进程一般会有多个
- 每个进程中会嵌入一个PHP解析器,进行PHP代码的处理。
3.18.2FastCGI配置指令
Nginx基于模块ngx_http_fastcgi_module实现通过fastcgi协议将指定的客户端请求转发至php-fpm处 理,其配置指令如下:
fastcgi_pass address:port; #转发请求到后端服务器,address为后端的fastcgi server的地址,可用位置:location, if in location fastcgi_index name; #fastcgi默认的主页资源,示例:fastcgi_index index.php; fastcgi_param parameter value [if_not_empty]; #设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将Nginx的内置变量赋值给自定义key fastcgi_param REMOTE_ADDR $remote_addr; #客户端源IP fastcgi_param REMOTE_PORT $remote_port; #客户端源端口 fastcgi_param SERVER_ADDR $server_addr; #请求的服务器IP地址 fastcgi_param SERVER_PORT $server_port; #请求的服务器端口 fastcgi_param SERVER_NAME $server_name; #请求的server name Nginx默认配置示例: location ~ \.php$ { root /scripts; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默认脚本路径 #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; #此文件默认系统已提供,存放的相对路径为 prefix/conf }
3.18.3FastCGI实战案例 : Nginx与php-fpm在同一服务器
将nginx1.26.2/重新解析
./configure --prefix=/usr/local/nginx \ --add-module=/nginx/echo-nginx-module-0.63 \ --add-module=/nginx/memc-nginx-module-0.20 \ --add-module=/nginx/srcache-nginx-module-0.33 \ --user=nginx --group=nginx \ --with-http_v2_module \ --with-http_realip_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-stream \ --with-stream_ssl_module \ --with-stream_realip_module \ --with-pcre
以上完成会显示
接着输入
make && make install
下载,并编译php,编译前将这些东西下好
yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel oniguruma-devel -y
此链接可以利用wget传入
成功
make && make install
成功
php相关配置优化
1)
2)
3)
4)
vim /lib/systemd/system/php-fpm.service
5)重启,查看端口
systemctl start php-fpm.service netstat -antlupe | grep php
准备测试界面
mkdir /data/web/php -p
添加php环境变量
source ~/.bash_profile
nginx配置转发
nginx -s reload
访问验证php测试页面
3.19php的动态扩展模块(php的缓存模块)
缓存优化
将文件拖入root下解压
tar zxf memcache-8.2.tgz
切换到
cd memcache-8.2/ #下载 yum install autoconf -y phpize #解析 ./configure && make && make install
解析完成
查看目录下
复制文件
编辑文件
vim /data/web/php/memcache.php
刷新
systemctl reload php-fpm.service
下载
yum install memcached -y systemctl enable --now memcached.service netstat -antlupe | grep memcache
结果
高速缓存
编辑nginx配置文件
刷新
nginx -s reload
结果