一.Web 服务介绍
1.1Apache
Apache 经典的 Web 服务端
Apache起初由美国的伊利诺伊大学香槟分校的国家超级计算机应用中心开发
目前经历了两大版本分别是1.X和2.X
其可以通过编译安装实现特定的功能
Apache prefork 模型
预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024
每个子进程有一个独立的线程响应用户请求
相对比较占用内存,但是比较稳定,可以设置最大和最小进程数
是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景
Apache worker 模型
一种多进程和多线程混合的模型
有一个控制进程,启动多个子进程
每个子进程里面包含固定的线程
使用线程程来处理请求
当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,
由于其使用了线程处理请求,因此可以承受更高的并发
优点:相比prefork 占用的内存较少,可以同时处理更多的请求
缺点:使用keepalive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超 时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在 prefork模式下,同样会发生)
Apache event模型
Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型,属于事件驱动模型(epoll)
每个进程响应多个请求,在现在版本里的已经是稳定可用的模式
它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题 (某些线程因为被keepalive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)
event MPM中,会有一个专门的线程来管理这些keepalive类型的线程
当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keepalive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控制
1.2Nginx-高性能的 Web 服务端
Nginx历经十几年的迭代更新(https://nginx.org/en/CHANGES), 目前功能已经非常完善且运行稳 定,另外Nginx的版本分为开发版、稳定版和过期版,nginx以功能丰富著称,它即可以作为http服务 器,也可以作为反向代理服务器或者邮件服务器能够快速的响应静态网页的请求
1.3服务端 I/O 流程
I/O在计算机中指Input/Output, IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数), 是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的 I/O请求数量为单位,I/O请求通常为读或写数据操作请求。
一次完整的I/O是用户空间的进程数据与内核空间的内核数据的报文的完整交换,但是由于内核空间与用 户空间是严格隔离的,所以其数据交换过程中不能由用户空间的进程直接调用内核空间的内存数据,而 是需要经历一次从内核空间中的内存数据copy到用户空间的进程内存当中,所以简单说I/O就是把数据从 内核空间中的内存数据复制到用户空间中进程的内存当中。
服务器的I/O
磁盘I/O
网络I/O : 一切皆文件,本质为对socket文件的读写
1.3.1磁盘 I/O
磁盘I/O是进程向内核发起系统调用,请求磁盘上的某个资源比如是html 文件或者图片,然后内核通过相 应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存, 如果是比较大的数据也需要等待时间
1.3.2网络 I/O
网络通信就是网络协议栈到用户空间进程的IO就是网络IO
网络I/O 处理过程
获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3)
构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4)
返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-7)
二.Nginx 架构和安装
2.1Nginx编译安装
官方源码包下载地址:https://nginx.org/en/download.html
编译安装示例:
配置好软件仓库
wget https://nginx.org/download/nginx-1.24.0.tar.gz
dnf install gcc pcre-devel zlib-devel openssl-devel -y
tar zxf nginx-1.24.0.tar.gz
cd nginx-1.24.0/
useradd -s /sbin/nologin -M nginx
./configure --prefix=/usr/local/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
验证版本及编译参数
vim ~/.bash_profile
export PATH=$PATH:/usr/local/nginx/sbin
source ~/.bash_profile
2.2平滑升级和回滚
有时候我们需要对Nginx版本进行升级以满足对其功能的需求,例如添加新模块,需要新功能,而此时 Nginx又在跑着业务无法停掉,这时我们就可能选择平滑升级
2.2.1平滑升级流程
将旧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
平滑升级示例
wget https://nginx.org/download/nginx-1.26.2.tar.gz
cd nginx-1.26.2/
./configure --with-http_ssl_module --withhttp_v2_module
--with-http_realip_module --with-http_stub_status_module --withhttp_gzip_static_module
--with-pcre --with-stream --with-stream_ssl_module --
with-stream_realip_module
make
查看两个版本
把之前的旧版的nginx命令备份
cd /usr/local/nginx/sbin/
cp nginx nginx.24
将新版本的nginx命令复制过去
\cp -f /root/nginx-1.26.2/objs/nginx /usr/local/nginx/sbin/
检测:
kill -USR2 44776 #nginx worker ID
kill -WINCH 44776
2.2.2回滚
cp nginx nginx.26
mv nginx.24 nginx
mv: overwrite 'nginx'? y
kill -HUP 44776
kill -WINCH 44776
三.Nginx 核心配置
3.1配置文件
主配置文件:nginx.conf
子配置文件: include conf.d/*.conf
fastcgi, uwsgi,scgi 等协议相关的配置文件
mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
Nginx 主配置文件的配置指令方式:
directive value [value2 ...];
注意
(1) 指令必须以分号结尾
(2) 支持使用配置变量 内建变量:由Nginx模块引入,可直接引用
自定义变量:由用户使用set命令定义,格式: set variable_name value;
引用变量:$variable_name
默认的nginx.conf 配置文件格式说明
#全局配置端,对全局生效,主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,Nginx的PID路
径,日志路径等。
user nginx nginx;
worker_processes 1; #启动工作进程数数量
events { #events #设置快,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多
个网络连接,使用哪种事件驱动模型 #处理请求,每个工作进程可以同时支持的
最大连接数,是否开启对多工作进程下的网络连接进行序列化等。
worker_connections 1024; #设置单个nginx工作进程可以接受的最大并发,作为web服务器
的时候最大并发数为 #worker_connections *
worker_processes,作为反向代理的时候为
#(worker_connections * worker_processes)/2
}
http { #http块是Nginx服务器配置中的重要部分,缓存、代理和日志格
式定义等绝大多数功能和第三方模块都 #可以在这设置,http块可
以包含多个server块,而一个server块中又可以包含多个location块,
#server块可以配置文件引入、MIME-Type定义、日志自定义、是
否启用sendfile、连接超时时间和 #单个链接的请求上限等。
include mime.types;
default_type application/octet-stream;
sendfile on; #作为web服务器的时候打开sendfile加快静态文件传输,指定是
否使用
#sendfile系统调用来传输文件
#sendfile系统调用在两个文件描述符之间直接传递数据(完全在
内核中操作)
#从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率
很高,被称之为零拷贝,
#硬盘 >> kernel buffer (快速拷贝到kernelsocket
buffer) >>协议栈。
keepalive_timeout 65; #长连接超时时间,单位是秒
server { #设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多
个location模块
#比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个
server 可以使用一个端口比如都使用 #80端口提供web服务
listen 80; #配置server监听的端口
server_name localhost; #本server的名称,当访问此名称的时候nginx会调用当前serevr
内部的配置进程匹配。
location / { #location其实是server的一个指令,为nginx服务器提供比较
多而且灵活的指令
#都是在location中体现的,主要是基于nginx接受到的请求字符
串
#对用户请求的UIL进行匹配,并对特定的指令进行处理
#包括地址重定向、数据缓存和应答控制等功能都是在这部分实现
#另外很多第三方模块的配置也是在location模块中配置。
root html; #相当于默认页面的目录名称,默认是安装目录的相对路径,可以使
用绝对路径配置。
index index.html index.htm; #默认的页面文件名称
}
error_page 500 502 503 504 /50x.html; #错误页面的文件名称
location = /50x.html { #location处理对应的不同错误码的页面定
义到/50x.html
#这个跟对应其server中定义的目录下。
root html; #定义默认页面所在的目录
}
}
#和邮件相关的配置
#mail {
# ...
# } mail 协议相关配置段
#tcp代理配置,1.9版本以上支持
#stream {
# ...
# } stream 服务器相关配置段
#导入其他路径的配置文件
#include /apps/nginx/conf.d/*.conf
}
3.1.1全局配置
Main 全局配置段常见的配置指令分类
正常运行必备的配置
优化性能相关的配置
用于调试及定位问题相关的配置
事件驱动相关的配置
eg:实现 nginx 的高并发配置
ulimit -n 102400
ab -c 5000 -n 10000 http://10.0.0.8/
默认配置不支持高并发,会出现错误日志
修改配置
vim /etc/security/limits.conf
* - nproc 100000
vim /usr/local/nginx/conf/nginx.conf
worker_rlimit_nofile 100000;
systemctl restart nginx
3.2http 配置块
#在响应报文中将指定的文件扩展名映射至MIME对应的类型
include /etc/nginx/mime.types;
default_type application/octet-stream; #除mime.types中的类型外
#指定其它文件的默认MIME类型,浏览
器一般会提示下载
types {
text/html html;
image/gif gif;
image/jpeg jpg;
}
eg:
vim /usr/local/nginx/html/lee.php
<?php
phpinfo();
?>
测试:
vim /usr/local/nginx/conf/nginx.conf
default_type text/html;
nginx -s reload
3.3核心配置
基于不同的IP、不同的端口以及不用得域名实现不同的虚拟主机,依赖于核心模块
ngx_http_core_module实现。
3.3.1新建一个 PC web 站点
mkdir /usr/local/nginx/conf.d/
vim /usr/local/nginx/conf/nginx.conf
http {
include /usr/local/nginx/conf.d/*.conf;
}
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
}
mkdir -p /webdata/nginx/timinglee.org/lee/html
echo lee.timinglee.org > /webdata/nginx/timinglee.org/lee/html/index.html
nginx -s reload
测试:
3.3.2root 与 alias
root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location /dirtest { #必须建立/mnt/dirtest才能访问
root /mnt;
}
}
mkdir /mnt/dirtest/
echo dirtest page > /mnt/dirtest/index.html
nginx -s reload
测试:
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于 location上下文,此指令使用较少
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location /dirtest {
root /mnt;
}
location /alias { #注意about后不要加/
#使用alias的时候uri后面如果加了斜杠,则下面的路径配置
必须加斜杠,否则403
alias /mnt/dirtest; #当访问alias的时候,会显示alias定义的/mnt/dirtest
里面的内容
}
}
nginx -s reload
测试:
3.3.3location 的详细使用
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;
ngnix会根据用户请求的URI来检查定义的所有location,按一定的优先级找出一个最佳匹配,
而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最 高的一个uri
uri是用户请求的字符串,即域名后面的web文件路径
然后使用该location模块中的正则url和字符串,如果匹配成功就结束搜索,并使用此location处理 此请求。
= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立
即处理请求
^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头
#对uri的最左边部分做匹配检查,不区分字符大小写
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
~* #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此uri的所有的uri
\ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号
匹配优先级从高到低:
=, ^~, ~/~*, 不带符号
3.3.3.1精确匹配
mkdir /webdata/nginx/timinglee.org/lee/images -p
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location = /logo.png {
root /webdata/nginx/timinglee.org/lee/images;
}
}
上传logo.jpg图片到/webdata/nginx/timinglee.org/lee/images,重启Nginx并访问测试
3.3.3.2区分大小写
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location ~ /logo.PNG {
root /webdata/nginx/timinglee.org/lee/images;
}
}
重启Nginx并访问测试
3.3.3.3不区分大小写
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location ~* /logo.PNG {
root /webdata/nginx/timinglee.org/lee/images;
}
}
3.3.3.4URI开始
mkdir /webdata/nginx/timinglee.org/lee/images/images{1,2}
echo image1 > /webdata/nginx/timinglee.org/lee/images/images1/index.html
echo image1 > /webdata/nginx/timinglee.org/lee/images/images2/index.html
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location ^~ /images {
root /webdata/nginx/timinglee.org/lee/images;
index index.html;
}
location /images1 {
root /webdata/nginx/timinglee.org/lee/images;
}
}
测试:
3.3.3.5文件名后缀
mkdir /webdata/nginx/timinglee.org/lee/images
#上传一个图片到/webdata/nginx/timinglee.org/lee/images
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js|css)$ {
root /webdata/nginx/timinglee.org/lee/images;
index index.html;
}
}
nginx -s reload
3.3.3.6优先级
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location ^~ /images {
root /webdata/nginx/timinglee.org/lee/images;
index index.html;
}
location /images1 {
root /webdata/nginx/timinglee.org/lee/images;
}
location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ {
root /data/nginx/static3;
index index.html;
}
}
匹配优先级:=, ^~, ~/~*,/
3.3.4Nginx 账户认证功能
由 ngx_http_auth_basic_module 模块提供此功能
htpasswd -cmb /usr/local/nginx/conf/.htpasswd admin lee
htpasswd -mb /usr/local/nginx/conf/.htpasswd lee lee
mkdir /webdata/nginx/timinglee.org/lee/login
echo login > /webdata/nginx/timinglee.org/lee/login/index.html
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
location /login {
root /webdata/nginx/timinglee.org/lee;
index index.html;
auth_basic "login password";
auth_basic_user_file "/usr/local/nginx/conf/.htpasswd";
}
}
测试:
3.3.5自定义错误页面
自 定义错误页,同时也可以用指定的响应状态码进行响应, 可用位置:http, server, location, if in location
mkdir /webdata/nginx/timinglee/lee/errors -p
echo error page > /webdata/nginx/timinglee/lee/errors/40x.html
server {
listen 80;
server_name lee.timinglee.org;
error_page 404 /40x.html
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
}
测试:
3.3.6自定义错误日志
mkdir "/var/log/nginx" -p
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
error_page 404 /40x.html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
}
重启nginx并访问不存在的页面进行测试并验证是在指定目录生成新的日志文件
测试:
3.3.7检测文件是否存在
try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如 果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一 个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内 部500错误。
echo "index.html is not exist" > /webdata/nginx/timinglee.org/lee/error/default.html
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
error_page 404 /40x.html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
}
测试:
3.3.8长连接配置
keepalive_requests 3;
keepalive_timeout 65 60;
#开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会被断开,第二个数字60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时间。
Keep-Alive:timeout=60 #浏览器收到的服务器返回的报文
#如果设置为0表示关闭会话保持功能,将如下显示:
#Connection:close 浏览器收到的服务器返回的报文
测试:
3.3.9作为下载服务器配置
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,同时设置,此项优级高.
eg:
mkdir -p /webdata/nginx/timinglee.org/lee/download
cp /root/anaconda-ks.cfg
/webdata/nginx/timinglee.org/lee/download
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
location /download {
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
limit_rate 1024k;
}
测试:
四.Nginx 高级配置
4.1Nginx 状态页
基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module,否则配置完成之后监测会是提示法错误
location /nginx_status {
stub_status;
auth_basic "auth login";
auth_basic_user_file /apps/nginx/conf/.htpasswd;
allow 192.168.0.0/16;
allow 127.0.0.1;
deny all;
}
状态页用于输出nginx的基本状态信息
4.2Nginx 压缩功能
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;
eg:
mkdir /webdata/nginx/timinglee.org/lee/data
cp /usr/local/nginx/logs/access.log /webdata/nginx/timinglee.org/lee/data/data.txt
echo test > /webdata/nginx/timinglee.org/lee/data/test.html
vim /usr/local/nginx/conf/nginx.conf
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_types text/plain application/javascript application/x-javascript text/css
application/xml text/javascript application/x-httpd-php image/gif image/png;
gzip_vary on;
nginx -s reload
测试:
4.3Nginx的版本隐藏
用户在访问nginx的时候,我们可以从报文中获得nginx的版本,相对于裸漏版本号的nginx,我们把其隐 藏起来更安全
cd nginx-1.24.0
vim src/core/nginx.h
#define nginx_version 1026001
#define NGINX_VERSION "1.0"
#define NGINX_VER "HAHA/" NGINX_VERSION
4.4Nginx 变量使用
nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
变量可以分为内置变量和自定义变量
内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。
4.4.1内置变量
$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的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
eg:
环境设置:
./configure --prefix=/usr/local/nginx/ \
--add-module=/root/echo-nginx-module-0.63 \
--add-module=/root/memc-nginx-module-0.20 \
--add-module=/root/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
nginx -s reload
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /var {
default_type text/html;
echo $remote_addr;
echo $args;
echo $document_root;
echo $document_uri;
echo $host;
echo $http_user_agent;
echo $request_filename;
echo $scheme;
echo $scheme://$host$document_uri?$args;
echo $http_cookie;
echo $cookie_key2;
echo $http_Accept;
}
}
测试:
4.4.2自定义变量
Syntax: set $variable value;
Default: —
Context: server, location, if
eg:
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /var {
default_type text/html;
set $name timinglee;
echo $name;
set $web_port $server_port;
echo $web_port;
}
}
测试:
五Nginx Rewrite
Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求
此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库
rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能
比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问
另外还可以在一定程度上提高网站的安全性。
5.1ngx_http_rewrite_module 模块指令
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行 配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断。
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间 使用以下符号链接:
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
5.1.1 if 指令
vim /usr/local/nginx/conf.d/vhosts.conf
location /test {
index index.html;
default_type text/html;
if ( $scheme = http ){
echo "if ---------> $scheme";
}
if ( $scheme = https ){
echo "if ---------> $scheme";
}
}
location /test2 {
if ( !-e $request_filename ){
echo "$request_filename is not exist";
return 409;
}
}
测试:
5.1.2set 指令
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key
另外set定义格式为set $key value,value可以是text, variables和两者的组合。
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /test3{
set $name lee;
echo $name;
}
}
测试:
5.1.3 break 指令
用于中断当前相同作用域(location)中的其他Nginx配置
与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效
位于后面的 ngx_http_rewrite_module 模块中指令就不再执行 Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,、
该指令可以在server块和locationif块中使用
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /break{
default_type text/html;
set $name lee;
echo $name;
break;
set $port $server_port;
echo $port;
}
}
测试:
有break与无break的区别
5.1.4return 指令
return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重 定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配 置都将不被执行,return可以在server、if 和 location块进行配置
return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容
#可以调用变量,其中text如果有空格,需要用单或双引号
return code URL; #返回给客户端的URL地址
vim /usr/local/nginx/conf.d/vhosts,conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /return {
default_type text/html;
if ( !-e $request_filename){
return 301 http://www.baidu.com;
#return 666 "$request_filename is not exist";
}
echo "$request_filename is exist";
}
}
测试:
5.2 rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配, rewrite主要是针对用户请求的URL或者是URI做具体处理
rewrite regex replacement [flag];
正则表达式格式
. #匹配除换行符以外的任意字符
\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 这几个字母以外的任意字符
5.2.1rewrite flag
利用nginx的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时 重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型
跳转型指由客户端浏览器重新对新地址进行请求
代理型是在WEB服务器内部实现跳转
flag 说明
redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作
#而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,
#而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户
5.2.2域名永久与临时重定向
名的临时的调整,后期可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳 转,这种情况浏览器不会缓存跳转,临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。
vim /usr/local/nginx/conf.d/vhosts.conf
location / {
root /data/nginx/html/pc;
index index.html;
rewrite / http://www.baidu.com permanent;
#rewrite / http://www.baidu.com redirect;
}
5.2.2.1 永久重定向301
域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到 客户端浏览器
永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息,即使nginx服务器无法访问,浏览器也 会利用缓存进行重定向
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location / {
#rewrite / http://lee.timinglee.com redirect;
rewrite / http://lee.timinglee.com permanent;
}
}
server {
listen 80;
server_name lee.timinglee.com;
root /webdata/nginx/timinglee.com/lee;
}
5.2.2.2 临时重定向302
域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器 不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS解析记录,这也是临时重定向与永久 重定向最大的本质区别。
即当nginx服务器无法访问时,浏览器不能利用缓存,而导致重定向失败
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location / {
rewrite / http://lee.timinglee.com redirect;
#rewrite / http://lee.timinglee.com permanent;
}
}
server {
listen 80;
server_name lee.timinglee.com;
root /webdata/nginx/timinglee.com/lee;
}
5.2.3rewrite
自动跳转 https
编译
./configure --prefix=/usr/local/nginx/ --add-module=/root/echo-nginx-module-0.63 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/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 --with-http_ssl_module
cd /usr/local/nginx/
mkdir certs
openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/nginx/certs/timinglee.org.key \
-x509 -days 365 -out /usr/local/nginx/certs/timinglee.org.crt
vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
listen 443 ssl;
server_name www.timinglee.org;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/timinglee.org.crt;
ssl_certificate_key /usr/local/nginx/certs/timinglee.org.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
location / {
if ( $scheme = http ){
rewrite /(.*) https://$host/$1 redirect;
}
if ( !-e $request_filename ){
rewrite /(.*) https://$host/index.html redirect;
}
}
}
测试:
5.2.4判断文件是否存在
vim /usr/local/nginx/conf.d/pc.conf
location / {
root /data/nginx/html/pc;
index index.html;
if (!-e $request_filename) {
rewrite .* http://www.timinglee.org/index.html; #实现客户端浏览器的302跳转
#rewrite .* /index.html; #web服务器内部跳转
}
}
5.3防盗链
防盗链基于客户端携带的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
eg:
location /images {
valid_referers none blocked server_names *.timinglee.org ~/.baidu/.;
if ( $invalid_referer ){
rewrite ^/ http://www.timinglee.org/daolian.png;
}
}
六 Nginx 反向代理功能
反向代理: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协议转发至指定服务器处理
6.1 实现 http 反向代理
6.1.1 http 协议反向代理
proxy_pass; #用来设置将客户端请求转发给的后端服务器的主机
#可以是主机名(将转发至后端服务做为主机头首部)、IP地址:端口的方式
#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
location /web {
index index.html;
proxy_pass http://172.25.254.30:8080; #8080后面无uri,即无 / 符号,
#需要将location后面url 附加到proxy_pass指定的
url后面
#此行为类似于root
#proxy_pass指定的uri不带斜线将访问的/web
#等于访问后端服务器
proxy_pass http://172.25.254.40:8080/; #8080后面有uri,即有 / 符号
#相当于置换,即访问/web时实际返回proxy_pass后面
uri内容
#此行为类似于alias
#proxy_pass指定的uri带斜线
#等于访问后端服务器的
#http://172.25.254.40:8080/index.html
#内容返回给客户端
} # http://nginx/web/index.html ==>
http://1:8080
#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能
使用uri
#即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后
server {
...
server_name HOSTNAME;
location ~|~* /uri/ {
proxy_pass http://host:port; #proxy_pass后面的url 不能加/
}
...
}
http://HOSTNAME/uri/ --> http://host/uri/
proxy_hide_header field; #用于nginx作为反向代理的时候
#在返回给客户端http响应时
#隐藏后端服务器相应头部的信息
#可以设置在http,server或location块
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 首部字段大小不敏感
proxy_pass_header Server;
proxy_pass_header Date;
proxy_pass_request_body on | off;
#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启
proxy_set_header;
#可更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的
时候,就要更改每一个报文的头部
location ~ /web {
proxy_pass http://172.25.254.20:80;
proxy_hide_header ETag;
proxy_pass_header Server;
proxy_pass_request_body on;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $remote_addr;
}
vim /etc/httpd/conf/httpd.conf
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%
{User-Agent}i\"" combined
6.1.1.1反向代理单台 web 服务器
vim /usr/local/nginx/conf/conf.d/pc.conf
server {
listen 80;
server_name www.timinglee.org;
location / {
proxy_pass http://172.25.254.200;
}
}
6.1.1.2指定 location 实现反向代理
针对指定的 location
server {
listen 80;
server_name www.timinglee.org;
location / {
proxy_pass http://172.25.254.200;
}
location ~ /static {
proxy_pass http://172.25.254.100:8080;
}
}
mkdir /var/www/html/static
echo static 172.25.254.200 > /var/www/html/static/index.html
echo 172.25.254.100 > /var/www/html/index.html
针对特定的资源实现代理
vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timinglee.org;
location / {
proxy_pass http://172.25.254.30;
}
location ~ \.(png|jpg|gif) {
proxy_pass http://172.25.254.20:8080;
}
}
6.1.1.3缓存功能
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
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; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,
否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 |
http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
#在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
#示例
proxy_cache_use_stale error http_502 http_503;
proxy_cache_methods GET | HEAD | POST ...;
#对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
6.1.1.3.1非缓存场景压测
准备后端httpd服务器
cat /var/log/messages > ./log.htm
ab -n1000 -c100 http://www.timinglee.org/static/index.html
6.1.1.3.2准备缓存配置
vim /usr/local/nginx/conf/nginx.conf
#gzip on;
proxy_cache_path /apps/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m
inactive=120s max_size=1g; #配置在nginx.conf http配置段
vim /usr/local/nginx/conf.d/vhost.conf
location ~ /static { #要缓存的URL 或者放在server配置项对所有URL都进行缓存
proxy_pass http://172.25.254.20:8080;
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 1m; #必须指定哪些响应码的缓存
}
#/data/nginx/proxycache/ 目录会自动生成
tree /usr/local/nginx/proxy_cache/
6.1.1.3.3访问并验证缓存文件
ab -n1000 -c100 http://www.timinglee.org/static/index.html
ab -n 2000 -c200 http://www.magedu.org/static/log.html
6.1.2 http 反向代理负载均衡
在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而 且不能对后端服务器提供相应的服务器状态监测,Nginx 可以j基于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做hashhash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑
定
ip_hash;
#源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计
算,以实现会话保持
least_conn;
#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
6.1.2.1后端多台 web服务器
环境配置:
两台后端服务器apache
一台nginx
nginx 172.25.254.100
server1 172.25.254.150
server2 172.25.254.200
server1
dnf install httpd -y
echo "server1 172.25.254.150" > /var/www/html/index.html
systemctl enable --now httpd
server2
dnf install httpd -y
echo "server2 172.25.254.200" > /var/www/html/index.html
systemctl enable --now httpd
nginx
vim /usr/local/nginx/conf.d/pc.conf
upstream webserver {
#ip_hash;
#hash $request_uri consistent;
#hash $cookie_lee
#least_conn;
server 172.25.254.150:8080 weight=1 fail_timeout=15s max_fails=3;
server 172.25.254.200:80 weight=1 fail_timeout=15s max_fails=3;
server 172.25.254.100:80 backup;
}
server {
listen 80;
server_name www.timinglee.org;
location ~ / {
proxy_pass http://webserver;
}
}
eg:
基于Cookie 实现会话绑定
vim /usr/local/nginx/conf.d/vhosts.conf
http {
upstream websrvs {
hash $cookie_hello; #hello是cookie的key的名称
server 10.0.0.101:80 weight=2;
server 10.0.0.102:80 weight-1;
}
}
vim /usr/local/nginx/conf/conf.d/pc.conf
upstream webserver {
#ip_hash;
#hash $request_uri consistent;
hash $cookie_lee;
#least_conn;
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.timinglee.org;
location ~ / {
proxy_pass http://webserver;
}
}
6.2实现 Nginx 四层负载均衡
Nginx在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于 DNS的域名解析,其配置方式和指令和http 代理类似,其基于ngx_stream_proxy_module模块实现tcp 负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、 调度算法等高级功能。
6.2.1 tcp负载均衡配置参数
stream { #定义stream相关的服务;
Context:main
upstream backend { #定义后端服务器
hash $remote_addr consistent; #定义调度算法
server backend1.example.com:12345 weight=5; #定义具体server
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns { #定义后端服务器
server 10.0.0.1:53; #定义具体server
server dns.example.com:53;
}
server { #定义server
listen 12345; #监听IP:PORT
proxy_connect_timeout 1s; #连接超时时间
proxy_timeout 3s; #转发超时时间
proxy_pass backend; #转发到具体服务器组
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}
6.2.2 负载均衡: MySQL
在apache中安装mysql
dnf install mariadb-server -y
vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=20
systemctl start mariadb
mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
mysql -ulee -plee -h172.25.254.150 -e "select @@server_id"
nginx
vim /usr/local/nginx/conf/tcp/tcp.conf
stream {
upstream mysql_server {
server 172.25.254.150:3306 max_fails=3 fail_timeout=30s;
server 172.25.254.200:3306 max_fails=3 fail_timeout=30s;
}
server {
listen 172.25.254.100:3306;
proxy_pass mysql_server;
proxy_connect_timeout 30s;
proxy_timeout 300s;
}
}
6.2.3udp 负载均衡: DNS
stream {
upstream dns_server{
server 172.25.254.20:53 max_fails=3 fail_timeout=30s;
server 172.25.254.30:53 max_fails=3 fail_timeout=30s;
}
server {
listen 172.25.254.10:53 udp;
proxy_pass dns_server;
proxy_timeout 1s;
proxy_responses 1; # 使用UDP协议时,设置代理服务器响应客户端期望的数据报文数
# 该值作为会话的终止条件
error_log logs/dns.log;
}
}
6.3 实现 FastCGI
6.3.1 FastCGI配置指令
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
}
6.3.2 FastCGI : Nginx与php-fpm在同一服务器
源码编译php
dnf install -y bzip2 systemd-devel libxml2-devel sqlite-devel
libpng-devel libcurl-devel oniguruma-devel
tar zxf php-8.3.9.tar.gz
./configure \
--prefix=/usr/local/php \ #安装路径
--with-config-file-path=/usr/local/php/etc \ #指定配置路径
--enable-fpm \ #用cgi方式启动程序
--with-fpm-user=nginx \ #指定运行用户身份
--with-fpm-group=nginx \
--with-curl \ #打开curl浏览器支持
--with-iconv \ #启用iconv函数,转换字符编码
--with-mhash \ #mhash加密方式扩展库
--with-zlib \ #支持zlib库,用于压缩http压缩传输
--with-openssl \ #支持ssl加密
--enable-mysqlnd \ #mysql数据库
--with-mysqli \
--with-pdo-mysql \
--disable-debug \ #关闭debug功能
--enable-sockets \ #支持套接字访问
--enable-soap \ #支持soap扩展协议
--enable-xml \ #支持xml
--enable-ftp \ #支持ftp
--enable-gd \ #支持gd库
--enable-exif \ #支持图片元数据
--enable-mbstring \ #支持多字节字符串
--enable-bcmath \ #打开图片大小调整,用到zabbix监控的时候用到了这个模块
--with-fpm-systemd #支持systemctl 管理cgi
php优化:
cd /usr/local/php/etc
cp php-fpm.conf.default php-fpm.conf
vim php-fpm.conf
pid = run/php-fpm.pid
cd php-fpm.d/
cp www.conf.default www.conf
cd /root/php-8.3.9/
cp php.ini-production /usr/local/php/etc/php.ini
vim /usr/local/php/etc/php.ini
[Date]
; Defines the default timezone used by the date functions
; https://php.net/date.timezone
date.timezone = Asia/Shanghai
cd /root/php-8.3.9/
cp sapi/fpm/php-fpm.service /lib/systemd/system/
# Mounts the /usr, /boot, and /etc directories read-only for processes invoked by
this unit.
#ProtectSystem=full
systemctl start php-fpm.service
nginx转发配置
vim /usr/local/nginx/conf.d/php.conf
server {
listen 80;
server_name php.timinglee.org;
root /data/php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
6.3.3 php的动态扩展模块(php的缓存模块)
环境准备
安装memcache模块
tar zxf memcache-8.2.tgz
cd memcache-8.2/
dnf install autoconf
phpize
./configure && make && make install
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-nonzts-20230831/
复制测试文件到nginx发布目录中
cd memcache-8.2/
cp example.php memcache.php /data/php/
vim /data/php/memcache.php
define('ADMIN_USERNAME','admin'); // Admin Username
define('ADMIN_PASSWORD','lee'); // Admin Password
define('DATE_FORMAT','Y/m/d H:i:s');
define('GRAPH_SIZE',200);
define('MAX_ITEM_DUMP',50);
$MEMCACHE_SERVERS[] = 'localhost:11211'; // add more as an array
#$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array
配置php加载memcache模块
vim /usr/local/php/etc/php.ini
;extension=zip
extension=memcache
;zend_extension=opcache
systemctl reload php-fpm
部署memcached
dnf install memcached -y
systemctl enable --now memcached.service
6.3.4 php高速缓存
rm -fr /usr/local/nginx/
tar zxf srcache-nginx-module-0.33.tar.gz
tar zxf memc-nginx-module-0.20.tar.gz
cd nginx-1.26.2/
./configure --prefix=/apps/nginx --user=nginx --
group=nginx --with-http_ssl_module --with-http_v2_module --withhttp_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=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module0.33
make && make install
vim /usr/local/nginx/conf.d/php.conf
upstream memcache {
server 127.0.0.1:11211;
keepalive 512;
}
server {
listen 80;
server_name php.timinglee.org;
root /data/php;
location /memc {
internal;
memc_connect_timeout 100ms;
memc_send_timeout 100ms;
memc_read_timeout 100ms;
set $memc_key $query_string; #使用内置变量$query_string来作为key
set $memc_exptime 300; #缓存失效时间300秒
memc_pass memcache;
}
location ~ \.php$ {
set $key $uri$args; #设定key的值
srcache_fetch GET /memc $key; #检测mem中是否有要访问的php
srcache_store PUT /memc $key; #缓存为加载的php数据
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
七 nginx 二次开发版本
7.1编译安装 openresty
dnf -yq install gcc pcre-devel openssl-devel perl
useradd -r -s /sbin/nologin nginx
cd /usr/local/src
wget https://openresty.org/download/openresty-1.17.8.2.tar.gz
tar xf openresty-1.17.8.2.tar.gz
cd openresty-1.17.8.2/
./configure \
--prefix=/apps/openresty \
--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
ln -s /usr/local/openresty/bin/* /usr/bin/