跳转到主内容
思享编程网:思考分享,玩转编程世界!

企业高性能web服务器(nginx)

一、Nginx 安装 Nginx版本和安装方式

Nginx版本

Mainline version 主要开发版本,一般为奇数版本号,比如1.19 Stable version 当前最新稳定版,一般为偶数版本,如:1.20 Legacy versions 旧的稳定版,一般为偶数版本,如:1.18

Nginx安装可以使用yum或源码安装,但是推荐使用源码编译安装 yum的版本比较旧 编译安装可以更方便自定义相关路径 使用源码编译可以自定义相关功能,更方便业务的上的使用 1.Nginx 编译安装 wget下载或用Moba将安装包导入mnt:

安装gcc编译器:

创建nginx用户,该用户无法登录系统且没有家目录:

解压缩:

编译:

👆

[root@Nginx nginx-1.24.0]# ./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 然后执行这个:

nginx完成安装以后,有四个主要的目录:

conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他

的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params 两个文件,配置文件一般都有一个样板配置文件,是以.default为后缀,使用时可将其复制并将default后缀 去掉即可。

html目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web 文件是默认的错误页面提示页面。

logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比 如/var/logs/nginx里面。

sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。

然后关闭火墙 2.验证版本及编译参数

export PATH=$PATH:/usr/local/nginx/sbin

3.使用安装完成的二进制文件nginx

-v示例:

[root@Nginx ~]# nginx -v nginx version: nginx/1.18.0

参数解释: Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives] Options: -?,-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 #设置全局指令,注意和 配置文件不要同时配置,否则冲突

4.Nginx 启动文件

[Unit]

Description=The NGINX HTTP and reverse proxy server After=syslog.target network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target 启动:

二、平滑升级和回滚 升级 解压并编译新版本:

[root@Nginx nginx]# tar zxf nginx-1.26.1.tar.gz

[root@Nginx nginx]# cd nginx-1.26.1/

#开始编译新版本 [root@Nginx nginx-1.26.1]# ./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无需要make install [root@Nginx nginx-1.26.1]# make 查看两个版本:

1.把之前的旧版的nginx命令备份:

2.把新版本的nginx命令复制过去:

检测一下有没有问题

3.开启新进程 USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的 nginx

↑此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进 程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。

两个master的进程都在运行,只是旧的master不在监听,由新的master监听80。

4.回收旧版本

↑旧版本的mast不想看见的话可以用 kill -9 旧ID 干掉

回滚 如果升级的版本发现问题需要回滚,可以重新拉起旧版本的worker 回滚文件: ↓做之前要先备份新版文件 cp nginx nginx.26

三、Nginx 核心配置详解 1.更改nginx编译源码隐藏版本信息 👇 注意:这一步要在编译安装前修改

2.默认的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.全局配置 Main 全局配置段常见的配置指令分类 正常运行必备的配置 优化性能相关的配置 用于调试及定位问题相关的配置 事件驱动相关的配置 全局配置说明: vim /usr/local/nginx/conf/nginx.conf

user nginx nginx; #启动Nginx工作进程的用户和组

worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同 worker_cpu_affinity 00000001 00000010 00000100 00001000 | auto ; #将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进 #程独占以一核心CPU,但是可以保证此进程不运行在其他核心上,这就极大减少了nginx的工作进程在不同的 #cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务 #器的性能。

CPU MASK: 00000001:0号CPU 00000010:1号CPU 10000000:7号CPU #示例 worker_cpu_affinity 0001 0010 0100 1000;第0号---第3号CPU worker_cpu_affinity 0101 1010; #示例 worker_processes 4; worker_cpu_affinity 00000010 00001000 00100000 10000000; [root@centos8 ~]# ps axo pid,cmd,psr | grep nginx 31093 nginx: master process /apps 1 34474 nginx: worker process 1 34475 nginx: worker process 3 34476 nginx: worker process 5 34477 nginx: worker process 7 #错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit | alert | emerg] #error_log logs/error.log; #error_log logs/error.log notice; error_log /usr/local/nginx/logs/error.log error; #pid文件保存路径 pid /usr/local/nginx/logs/nginx.pid; worker_priority 0; #工作进程优先级,-20~20(19) worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限, #包括:Nginx的所有连接(例如与代理服务器的连接等) #而不仅仅是与客户端的连接 #另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件 数的限制 #最好与ulimit -n 或者limits.conf的值保持一致,

示例: 实现 nginx 的高并发配置:

安装压力测试软件:

测试: -n:请求总量 -c:并发量

4.建立nginx站点:

测试:

5.root 与 alias root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location

alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于 location上下文,此指令使用较少

6.location 的详细使用 在一个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

#匹配优先级从高到低: =, ^~, ~/~*, 不带符号

nginx -s reload 测试:

测试:

7.Nginx 账户认证功能 由 ngx_http_auth_basic_module 模块提供此功能

测试:

8.自定义错误页面 自定义错误页,同时也可以用指定的响应状态码进行响应, 可用位置:http, server, location, if in location

测试:

9.自定义错误日志

测试:

10.检测文件是否存在 try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如 果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。

只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。

最后一个参数是回退URI且必须存在,否则会出现内部500错误。

11.长连接配置

keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长,0表示禁止长连接,

默认为75s #通常配置在http字段作为站点全局配置 keepalive_requests 数字; #在一次长连接上所允许请求的资源的最大数量 #默认为100次,建议适当调大,比如:500

安装测试软件;

测试:

12.作为下载服务器配置

location /download {

autoindex on; #自动索引功能 autoindex_exact_size on; #计算文件确切大小(单位bytes),此为默认值,off只显示 大概大小(单位kb、mb、gb) 四 Nginx 高级配置 4.1 Nginx 状态页 基于nginx 模块 ngx_http_stub_status_module 实现, 在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module 否则配置完成之后监测会是提示法错误 Note 注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态 autoindex_localtime on; #on表示显示本机时间而非GMT(格林威治)时间,默为为off显 示GMT时间 limit_rate 1024k; #限速,默认不限速 } 建立共享资源存放目录:

测试:

四、Nginx 高级配置 1.Nginx 状态页 基于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的基本状态信息: #输出信息示例: Active connections: 291 server accepts handled requests 16630948 16630948 31070465 上面三个数字分别对应accepts,handled,requests三个值 Reading: 6 Writing: 179 Waiting: 106 Active connections: #当前处于活动状态的客户端连接数 #包括连接等待空闲连接数=reading+writing+waiting accepts: #统计总值,Nginx自启动后已经接受的客户端请求连接的总数。

handled: #统计总值,Nginx自启动后已经处理完成的客户端请求连接总数 #通常等于accepts,除非有因worker_connections限制等被拒绝的连接 requests: #统计总值,Nginx自启动后客户端发来的总的请求数 Reading: #当前状态,正在读取客户端请求报文首部的连接的连接数 #数值越大,说明排队现象严重,性能不足 Writing: #当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明 访问量很大 Waiting: #当前状态,正在等待客户端发出请求的空闲连接数 开启 keep-alive的情况下,这个值等于active – (reading+writing)

测试:

2.Nginx 压缩功能 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.Nginx的版本隐藏 用户在访问nginx的时候,我们可以从报文中获得nginx的版本,相对于裸漏版本号的nginx,我们把其隐藏起来更安全( 编译之前设置 )

4.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为任意请求报文首部字部cookie的key名 $http_ #name为任意请求报文首部字段,表示记录请求报文的首部字段,name的对应的首部字段名需要为小写,如果有 横线需要替换为下划线

先备份原本的主和子配置文件 systemctl stop nginx 编译中添加插件:

make & make install 重新编译安装 将原来的主和子配置文件覆盖新的主和子配置文件 systemctl restart nginx 编辑配置文件:

测试:

5.自定义变量

测试:

五、Nginx Rewrite 相关功能 Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求 此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库 rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问 另外还可以在一定程度上提高网站的安全性。

1.ngx_http_rewrite_module 模块指令 if 指令 用于条件匹配判断,并根据条件判断结果选择不同的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 #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接) #注意: #如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。

#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false

测试:

set 指令 指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key另外set定义格式为set $key value,value可以是text, variables和两者的组合。

测试:

break 指令 用于中断当前相同作用域(location)中的其他Nginx配置 与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效位于后面的 ngx_http_rewrite_module 模块中指令就不再执行Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置, 该指令可以在server块和locationif块中使用

测试:

👾注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行 return 指令 return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重 定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置

测试:

2.rewrite 指令 通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配, rewrite主要是针对用户请求的URL或者是URI做具体处理 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] #匹配除了lee 这几个字母以外的任意字符 rewrite 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重写后返回错误的给用户 rewrite案例: 域名永久与临时重定向 域名的临时的调整,后期可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳 转,这种情况浏览器不会缓存跳转,临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存 永久重定向301: 域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到 客户端浏览器 永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息,即使nginx服务器无法访问,浏览器也 会利用缓存进行重定向

reload

临时重定向302: 域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器 不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS解析记录,这也是临时重定向与永久 重定向最大的本质区别。

即当nginx服务器无法访问时,浏览器不能利用缓存,而导致重定向失败

reload

rewrite 案例: break 与 last

[root@nginx]# mkdir /data/web/html/{test1,test2,break,last}

[root@nginx]# echo test1 > /data/web/html/test1/index.html [root@nginx]# echo test2 > /data/web/html/test2/index.html [root@nginx]# echo last > /data/web/html/last/index.html [root@nginx]# echo break > /data/web/html/break/index.html

[root@nginx nginx]# vim conf.d/vhosts.conf server { listen 80; server_name www.timinglee.org; root /data/web/html; index index.html; location /break { root /data/web/html; rewrite ^/break/(.*) /test1/$1 break; rewrite ^/test1/(.*) /test2/$1 ; } location /last { root /data/web/html; rewrite ^/last/(.*) /test1/$1 last; rewrite ^/test1/(.*) /test2/$1 ; } location /test1 { default_type text/html; return 666 "new test1"; } location /test2 { root /data/web/html; } } #测试: [root@client ~]# curl -L www.timinglee.org/break/index.html test1 [root@client ~]# curl -L www.timinglee.org/last/index.html new test1[root@client ~]#

break

:终止当前

rewrite

规则,不再匹配后续规则或

location

last

:完成当前

rewrite

规则后,重新匹配

location

默认行为为

last

,可根据需求选择合适的指令。

rewrite案例: 自动跳转 https 案例:基于通信安全考虑公司网站要求全站 https,因此要求将在不影响用户请求的情况下将http请求全部自动跳转至 https,另外也可以实现部分 location 跳转 制作证书:

reload 测试:

rewrite 案例: 判断网页存在与否 案例:当用户访问到公司网站的时输入了一个错误的URL,可以将用户重定向至官网首页

reload 测试:

3.Nginx 防盗链 防盗链基于客户端携带的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 正常通过搜索引擎搜索web 网站并访问该网站的referer信息如下: 日志

实现盗链 在一个web 站点盗链另一个站点的资源信息,比如:图片、视频等

#盗链者web页面: 盗链

#使用别人的图片链接

欢迎大家

狂点老李出门见喜

#使用别人的网页链接

实现防盗链 基于访问安全考虑,nginx支持通过ngx_http_referer_module模块,检查访问请求的referer信息是否有效 实现防盗链功能

六、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协议转发至指定服务器处理 逻辑调用关系:

访问逻辑图:

同构代理:用户不需要其他程序的参与,直接通过http协议或者tcp协议访问后端服务器 异构代理:用户访问的资源时需要经过处理后才能返回的,比如php,python,等等,这种访问资源需要经过处理才能被访问

1.实战案例: 反向代理针对特定的资源实现代理(动静分离) 要求:将用户对域 www.zk.org 的请求转发给后端服务器处理

RS1和RS2安装httpd并启动,关闭火墙和selinux RS2安装php,并在默认发布目录写info.php

测试:

2.反向代理示例: 缓存功能 编辑主配置文件:

编辑子配置文件:

访问并验证缓存文件:

验证缓存目录结构及文件大小:

3.http 反向代理负载均衡 注意: 本节实验过程中先关闭缓存 配置:

reload 测试:

4.基于Cookie 实现会话绑定

reload 测试:

5.实现 Nginx 四层负载均衡 Nginx在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于 DNS的域名解析,其配置方式和指令和http 代理类似,其基于ngx_stream_proxy_module模块实现tcp 负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、 调度算法等高级功能。

如果编译安装,需要指定 --with-stream 选项才能支持ngx_stream_proxy_module模块 tcp负载均衡配置参数 👺注意:tcp的负载均衡要位于http语句块之外

udp 负载均衡实例: DNS 两RS配置DNS:

测试下dns配置:

在http外指定新的子配置文件目录:

建立目录和子配置文件:

👆如果要53端口同时开udp和tcp的话就要多复制出条server块然后把第二个server块的udp去掉

访问测试: 从前端主机成功轮询访问到100和200server

负载均衡实例: MySQL 后端两RS服务器安装 MySQL:

配置server_id:

启动服务:

设置账号密码并测试:

前端主机nginx配置: 因为只能有一个stream,所以要写在已有的配置文件里👇

测试通过nginx负载轮询后端MySQL:

6.实现 FastCGI 1.FastCGI配置指令 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 } 2.FastCGI实战案例 : Nginx与php-fpm在同一服务器 编译安装 编译安装更方便自定义参数或选项,所以推荐大家使用源码编译 解决php依赖:

[root@Nginx ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel

libpng-devel libcurl-devel oniguruma-devel

如果oniguruma-devel没有则:

解压源码并安装:

#解压源码并安装

[root@Nginx ~]# ./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相关配置优化

生成主配置文件:

生成启动文件:

准备php测试页面

Nginx配置转发 Nginx安装完成之后默认生成了与fastcgi的相关配置文件,一般保存在nginx的安装路径的conf目录当 中,比如/apps/nginx/conf/fastcgi.conf、/apps/nginx/conf/fastcgi_params

DNS解析:

测试:

添加php环境变量:

3.php的动态扩展模块(php的缓存模块) 软件下载:http://pecl.php.net/package/memcache

安装memcache模块

复制测试文件到nginx发布目录中

👆修改状态页面的登陆密码和memcache的访问接口 配置php加载memcache模块

部署memcached

测试:

性能对比:

4.php高速缓存

部署方法 在我们安装的nginx中默认不支持memc和srcache功能,需要借助第三方模块来让nginx支持此功能,所以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 --add-module=/mnt/memc-nginx-module-0.20 --add-module=/mnt/srcache-nginx-module-0.33

编译安装:

恢复备份配置文件:

编辑配置文件:

upstream memcache {

server 127.0.0.1:11211; keepalive 512; }

server { listen 80; server_name php.zk.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 二次开发版本 openresty Nginx 是俄罗斯人发明的, Lua 是巴西几个教授发明的,中国人章亦春把 LuaJIT VM 嵌入到 Nginx中, 实现了OpenResty 这个高性能服务端解决方案 OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。

用于方便地搭建能够处理超高并发、扩展性极高的动态Web 应用、Web 服 务和动态网关。

OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将Nginx 有效地变成一个强大的通用 Web 应用平台。

这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

OpenResty 由于有功能强大且方便的的API,可扩展性更强,如果需要实现定制功能,OpenResty是个不错的选择 官网: http://openresty.org/cn/ 编译安装 openresty: 因为openresty与nginx冲突,所以编译安装 openresty前要把nginx卸载:

下载:

解压并编译:

./configure --prefix=/usr/local/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

启动:

八、io 磁盘 I/O 磁盘I/O是进程向内核发起系统调用,请求磁盘上的某个资源比如是HTML 文件或者图片,然后内核通过 相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内 存,如果是比较大的数据也需要等待时间 网络 I/O

不论磁盘和网络I/O 每次I/O,都要经由两个阶段: 第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长 第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短 I/O 模型 可分为同步/异步和阻塞/非阻塞。

同步/异步:关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。

同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态。

阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。

非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。

总结: 同步阻塞模型:需要进程主动询问内核是否处理完成,并且在此期间不能做别的。

同步非阻塞模型:进程可以在等待时做别的,但进程仍需每隔一段时间查看内核是否处理完成。

异步阻塞模型:进程可以在等待时做别的,但内核开始将数据拷贝至用户空间时通知进程,进程不能做别的要等待拷贝完成。

异步非阻塞模型:进程全程无需额外等待可以做别的,直到内核完成拷贝通知进程。

这四种 I/O 模型中,越往后,阻塞越少。

这些模型都可以配合多路复用io模型使用 多路复用io模型: I/O 多路复用主要包括:

select

poll

epoll

三种系统调用,

select

/

poll

/

epoll

的优势在于 单个进程即可同时处理多个 网络连接的 I/O 操作。

它的基本原理是:select/poll/epoll这个函数会持续轮询它所负责的所有套接字(socket),当某个套接字有数据到达时,就会通知用户进程。

select/poll 本质是「轮询模型」:内核每次都要遍历所有监听的 fd,fd 越多遍历开销越大,高并发下性能瓶颈明显;最大监听 fd 数受系统限制(1024),无法突破。

epoll 本质是「事件驱动模型」:内核维护就绪事件链表,仅当 fd 就绪时才主动通知,无遍历开销,是高并发场景的最优选择;监听fd数无硬限制,仅受系统内存 / 文件描述符上限约束。

边缘触发(ET)是 epoll 高性能关键:相比 LT 的重复通知,ET 仅通知 1 次,减少内核和用户态的交互次数,需配合非阻塞 IO使用(避免数据未读完导致阻塞)。

相关文章