Nginx

DNS查询过程

TCP创建

HTTP创建

请求的method

​ get:获取url资源(看朋友圈)

​ post:提交,更新或创建资源,是非幂等的(发布朋友圈)

​ put:向指定url传送更新的资源,是幂等的(更新朋友圈)

​ delete:向指定url删除资源(删除朋友圈)

​ head:用于检查 (仅获取header部分的内容)

请求的header

image-20250324171110224.png

http1.0短链接:一次tcp握手,一次请求,断开

http1.1长链接:一次tcp握手,多次请求,断开

(若网页出现加载时间过长,可在F12查看是否有服务在长时间加载或卡住了,再修改对应的服务问题)

HTTP响应

响应的header

image-20250324173415481.png

响应的状态码

状态码说明

image-20250324173622777.png

常见状态码

200:表示客户端成功接收到服务端返回的数据

206:客户端发完请求后,服务端只返回了一部分数据,例如下载大文件时,没下载完会出现

301:永久重定向(http-->https)

302:临时重定向

400:客户端请求语法错误,服务端无法理解

401:服务端开启了用户验证,客户端没有提供正确的验证信息

403:服务端不允许客户端访问页面(客户端权限不足),或没找到默认返回页面(所有web服务器默认的返回页面都是index.html,需要在服务端修改或添加默认返回页面)

404:客户端请求的资源不存在(请求路径错误或服务端不存在这个资源)

413:客户端向服务端发送了一个大文件,且文件的大小超过了服务端的限制(例如1MB)

500:服务端出现了内部错误,需要人为排查(链接数据库类服务异常时会出现)

502:服务器充当代理角色时,后端代理的服务器不可用或没有正常回应

503:服务当前不可用,通常是服务器停用或超载导致服务器无法处理客户端请求

504:服务器充当带角色时,后端服务没有按时返回数据,超时了(例如代理向后端申请要70s,但设定了后端60s没有回应就显示超时,此时需要调整超时时限)

TCP断开

nginx网络IO模型

用户请求 Nginx 这样的 web服务器获取磁盘中的文件时,系统是如何处理的?

image-20250325084416670.png

用户每一次请求都会发生一次IO操作:而每次IO,都要经由两个阶段:

第一步:将数据从磁盘加载至内核的内存空间(缓存区),等待数据准备完成,时间较长。

第二步:将数据从内核缓冲区复制到用户空间的进程内存(缓存区),时间较短。

第三步:Nginx封装数据为响应报文发送。

1.nginx下发指令给内核后,nginx是等待,还是不等待继续处理新的请求;

2.数据拷贝到内核缓存中了,通知nginx应用程序,阻塞

同步/异步

关注消息通知机制

同步:

调用者发送指令给被调用者,被调用者需要获取资源后返回给调用者,同步指调用者需要主动去询问被调用者当前的运行状态

异步:

调用者发送指令给被调用者,被调用者需要获取资源后返回给调用者,异步指被调用者会主动给调用者返回当前的运行状态

阻塞/非阻塞

阻塞:

IO操作需要完成后才能返回用户空间,调用结果返回前,调用者挂起

非阻塞:

IO操作发起后立刻给用户进程返回状态值,无需等待IO操作完成,在最终结果返回前调用者不会被挂起

IO组合模型

同步阻塞:

调用者需要主动查询运行状态,且IO操作完成前不能处理别的请求(不主动返回状态且挂起)

同步非阻塞:

调用者需要主动查询运行状态,但IO操作完成前可以先去处理别的请求(不主动返回状态不挂起)

异步阻塞:

被调用者会主动返回运行状态,但IO操作完成前不能处理别的请求(主动返回状态且挂起)

异步非阻塞:

被调用者会主动返回运行状态,且IO操作完成前可以先去处理别的请求(主动返回状态不挂起)

IO模型对比

image-20250325093427461.png

IO模型实现

select:对应IO复用模型

poll:对应IO复用模型

Epoll:对应IO复用模型,具有信号驱动IO的某些特性

NginxWeb

nginx组成部分

1、nginx二进制可执行文件,是nginx本身框架以及相关模块构建的二进制文件,所有功能由他提供

2、nginx.conf,他能决定开启哪些功能或开启后定义怎样的行为去处理请求

3、access.log,会记录nginx处理的每一条http的请求信息,响应信息

4、error.log,出现不可预期的问题时,可通过error.log去定位问题

Nginx安装

安装依赖

yum install -y gcc gcc-c++ autoconf pcre pcre-devel make automake httpd-tools

创建一个文件

/etc/yum.repos.d/nginx.repo

#稳定版
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

#开发/最新版
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
压缩epel源防止冲突

gzip /etc/yum.repos.d/epel.repo

生成缓存

makecache

安装nginx

yuminstall nginx

还原epel.repo

gzip -d /etc/yum.repos.d/epel.repo

附加:如果有其它服务冲突,则停止服务

systemctl stop httpd
systemctl disable httpd

启动且开机自启nginx

sysytemctl start nginx
systemctl start nginx

检查服务端口

netstat -lntp

Nginx目录结构

[root@web01 ~]# rpm -ql nginx
/etc/logrotate.d/nginx
/etc/nginx -->安装位置
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf -->提供的默认站点
/etc/nginx/fastcgi_params -->nginx通过模块链接php程序时需要传递的一些变量
/etc/nginx/mime.types -->支持的类型
/etc/nginx/modules -->模块
/etc/nginx/nginx.conf -->主配置文件
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params -->nginx通过模块链接python程序时需要传递的一些变量

/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service -->服务的启动与停止文件

/usr/lib64/nginx -->nginx二进制文件
/usr/lib64/nginx/modules

/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade

/usr/sbin/nginx
/usr/sbin/nginx-debug

/usr/share/doc/nginx-1.26.1
/usr/share/doc/nginx-1.26.1/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html

/var/cache/nginx -->nginx缓存目录
/var/log/nginx -->nginx日志目录

Nginx配置文件

纯文本类型,以区块形式组织,每个区块用一对大括号{ }表示开始和结束

image-20250326171430907.png
image-20250326171507488.png
image-20250326171543859.png
image-20250326171618569.png
image-20250326171658484.png
image-20250326171737960.png

Global全局模块

image-20250326173656036.png

Events事件模块

image-20250326173729899.png

HTTP核心模块

image-20250326173806924.png
image-20250326173828494.png

核心模块总结

Nginx中的 http、server、location 之间的关系 :

1、http标签用来解决用户的请求与响应

2、server标签用来响应某个具体的网站

3、location标签用来匹配网站具体url路径

http{ }下可以有多个server{ },一个server{ }下允许有多个location{ }

搭建游戏站点(要求必须用域名访问)

1、编写nginx配置文件

vim /etc/nginx/conf.d/game.zjh.net.conf

server {
        listen 80;          #监听80端口
        server_name game.zjh.net;         #使用的域名

​        location / {
​                            root /code                 #访问域名后去根下的code下找代码
​                            index index.html;    #默认返回的页面
​       }					#此处配置命令需要code下有index.html,否则找不到,无法运行

}
2、准备对应的网站代码

根据配置文件创建/code

unzip tetris-master.zip -d /code/

3、检查nginx配置语法

nginx -t

systemctl reload nginx.service

4、通过浏览器输入域名访问

将game.zjh.net解析到10.0.0.7上,修改C:\Windows\System32\drivers\etc\hosts文件即可(需要以管理员身份运行记事本打开)

默认服务

server {
	listen 80 default_server;

​                  #默认显示这个站点

​	server_name wx.zjh.net;

​    location / {
​		root /code1;
​		index index.html;
​      }

}

不推荐的方法:不允许通过ip访问页面(会返回自定义的错误代码)

把不需要的nginx默认界面压缩

gzip /etc/nginx/conf.d/default.conf

配置一个新的默认文件

vim /etc/nginx/conf.d/localhost.conf

server {
	listen 80 default_server;
	return 504;
}

推荐方法:通过ip访问时强制跳转到某个页面

server {
	listen 80 default_server;
	return 301 https://jd.com;
}

Nginx虚拟主机

在一台服务器上运行多个网站

实现方式
1、基于多ip实现

eth0:old page

eth1:new page

2、基于多端口实现

a:8080

b:8081

实例(将服务绑定在8081端口上):
server {
        listen 8081;

​        location / {
​            root /server/port1;
​            index index.html;
​    }

}

mkdir -p /server/port1

echo "8081 port web site" > /server/port1/index.html

3、基于相同的端口,但使用不同的server_name来区分,实现在一台服务器上运行多个站点

Nginx配置文件-autoindex设置

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;      (设置可以显示中文字体)

        location / {
                root /repo;
                index index.html;
    
                autoindex on;      (如果指定目录下没有index,则自动生成客户端请求的目录里的文件列表)
                autoindex_exact_size off;   (关闭精准显示字节大小,on则是显示所有字节大小)
                autoindex_localtime on;     (开启后文件显示的生成时间为本地时间)
        }

}

设置通过域名访问时展示index页面,域名后添加(例:data)时才展示资源列表

优化前:
server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;

        location / {   (只通过域名访问会展示自定义的页面)
                root /repo;
                index index.html;
    
        }
    
        location /data {    (在域名后加/data才能访问资源列表)
                root /repo;    #此时请求的是/repo/data
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
        }
}
优化后:
server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;           (相同的定义可以放在server中表示全局变量)

        location / {
                index index.html;
    
        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
        }
}

模拟企业内网仓库

[root@oldxu mirror]# cat

/etc/nginx/conf.d/mirror.oldxu.net.conf

server {

​					listen 80;

​					server_name mirror.oldxu.net; charset utf-8;

​					root /mirror;

 

​					location / {

​								index index.html;

​				}

\#提供yum仓库目录 

​					location /repo {

​								autoindex on; 

​								autoindex_exact_size off; 

​								autoindex_localtime on;

​					}

}

#使用rsync同步

[root@oldxu mirror]# rsync -avz rsync://rsync.mirrors.ustc.edu.cn/repo/cent os/ /mirror/repo/

# 将该目录创建为仓库目录

createrepo /mirror/rep

访问控制模块(控制某个页面只能由特定ip访问)

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;

        location / {
                index index.html;
    
        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
    
                allow 10.0.0.1/32;   (只允许某个主机ip可以访问/data)
                deny all;			 (其他全部拒绝)
        }
}

基础认证模块

安装服务

yum install httpd-tools -y

创建用户与密码

htpasswd -c -b /etc/nginx/ngx_passwd zjh 1

配置文件

vim /etc/nginx/conf.d/mirrors.zjh.net.conf

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;

        location / {
                index index.html;
    
        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
    
                allow 10.0.0.1/32;
                deny all;
    
                auth_basic "ciallo~";
                auth_basic_user_file /etc/nginx/ngx_passwd;
        }
}

Nginx限速限流

#请求限制的定义(定义限制请求来源的ip,并生成一个10m的空间来存放访问的频次信息,限制每秒处理一个请求)

limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;



#第一个参数:zone=req_one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应

#第二个参数:burst=3,设置一个大小为3的缓冲区,当有大量请求过来时,超过了访问频次限制的请求可以先放到这个缓冲区内

#第三个参数:nodelay,超过访问频次并且缓冲区也满了的时候,则会返回503,如果没有设置,则所有请求会等待排队

limit_req zone=req_one burst=5 nodelay;
limit_req_status 500;    (可自定义超出访问限制时返回什么状态码)
        location / {
                index index.html;

        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
    
                allow 10.0.0.1/32;
                deny all;
    
                auth_basic "ciallo~";
                auth_basic_user_file /etc/nginx/ngx_passwd;
        }
}

Nginx连接限制

limit_req_zone \$binary_remote_addr zone=req_one:10m rate=1r/s;

#连接限制的定义(基于ip地址限制同时下载的资源个数)

limit_conn_zone $binary_remote_addr zone=conn_od:10m;

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;

limit_req zone=req_one burst=5 nodelay;
limit_req_status 500;
limit_conn conn_od 2; (引用连接限制定义,一次只能同时下载两个资源)
limit_rate 200k;
        location / {
                index index.html;

        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
    
               allow 10.0.0.1/32;
               deny all;
    
               auth_basic "ciallo~";
               auth_basic_user_file /etc/nginx/ngx_passwd;
        }
}

Nginx限制下载速度

limit_req_zone \$binary_remote_addr zone=req_one:10m rate=1r/s;

limit_conn_zone $binary_remote_addr zone=conn_od:10m;

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;

limit_req zone=req_one burst=5 nodelay;
limit_req_status 500;
limit_conn conn_od 2; 
limit_rate 200k;       -->(限制下载速度为200k)

limit_rate_after 200m;      -->(当下载到200m时开启下载限速)

​        location / {
​                index index.html;

        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
    
               allow 10.0.0.1/32;
               deny all;
    
               auth_basic "ciallo~";
               auth_basic_user_file /etc/nginx/ngx_passwd;
        }

}

Nginx状态监控

limit_req_zone \$binary_remote_addr zone=req_one:10m rate=1r/s;

limit_conn_zone $binary_remote_addr zone=conn_od:10m;

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;

limit_req zone=req_one burst=5 nodelay;
limit_req_status 500;
limit_conn conn_od 2; 
limit_rate 200k;

limit_rate_after 200m;

​        location / {
​                index index.html;

        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
    
               allow 10.0.0.1/32;
               deny all;
    
               auth_basic "ciallo~";
               auth_basic_user_file /etc/nginx/ngx_passwd;
        }
        #添加一个状态监控页面
        location /ngx_status {
                    stub_status;(开启状态监控模块)
                    allow 127.0.0.1;(允许本机地址查看页面)
                    allow 10.0.0.1/32;(允许windows本机查看页面)
                    deny all;
        }

}

Active connections(当前活跃的连接数,包括waiting等待连接数)
server()
accepts(已接收的tcp总连接数)
handled(已处理的tcp总连接数)
requests(当前总http请求数)
Reading(当前读取的请求头数量)
Writing(当前响应的请求头数量)
Waiting(当前等待请求的空闲客户端连接数)

image-20250331144728086.png

提取当前网页状态的数值

#curl网页提权信息并筛选活跃连接数

curl -HHost:mirrors.zjh.net http://127.0.0.1/ngx_status | awk 'NR==1{print $NF}'

#curl网页提取信息并筛选失败的tcp连接数(已接收-已处理等于失败连接数)

curl -HHost:mirrors.zjh.net http://127.0.0.1/ngx_status | awk 'NR==3{print $1-$2}'

Nginx资源压缩

图片压缩:
limit_req_zone \$binary_remote_addr zone=req_one:10m rate=1r/s;

limit_conn_zone $binary_remote_addr zone=conn_od:10m;

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;

limit_req zone=req_one burst=5 nodelay;
limit_req_status 500;
limit_conn conn_od 2; 
limit_rate 200k;

limit_rate_after 200m;

​        location / {
​                index index.html;

        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
    
               allow 10.0.0.1/32;
               deny all;
    
               auth_basic "ciallo~";
               auth_basic_user_file /etc/nginx/ngx_passwd;
        }
        location /ngx_status {
                    stub_status;
                    allow 127.0.0.1;
                    allow 10.0.0.1/32;
                    deny all;
        }
        #(添加图片压缩的模块)
        location ~ /.(jgp|png|jpeg) {    (匹配jpg,png,jpeg后缀)
                    gzip on;   (开启图片压缩模块)
                    gzip_http_version 1.1;   (gzip压缩版本号)
                    gzip_comp_level 2;    (压缩等级,级别为1-9)
                    gzip_min_length 10k;  (图片小于10k不压缩)
                    gzip_types image/jpeg image/gif image/png image/svg+xml image/tiff image/webp;    (压缩哪些格式的图片,类型可添加)
                    gzip_vary on;    (添加 Vary: Accept-Encoding)
            }

}
文件压缩:
limit_req_zone \$binary_remote_addr zone=req_one:10m rate=1r/s;

limit_conn_zone $binary_remote_addr zone=conn_od:10m;

server {
        listen 80;
        server_name mirrors.zjh.net;
        charset utf8,gbk;
        root /repo;

limit_req zone=req_one burst=5 nodelay;
limit_req_status 500;
limit_conn conn_od 2; 
limit_rate 200k;

limit_rate_after 200m;

​        location / {
​                index index.html;

        }
    
        location /data {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
    
               allow 10.0.0.1/32;
               deny all;
    
               auth_basic "ciallo~";
               auth_basic_user_file /etc/nginx/ngx_passwd;
        }
        location /ngx_status {
                    stub_status;
                    allow 127.0.0.1;
                    allow 10.0.0.1/32;
                    deny all;
        }
        #(添加图片压缩的模块)
        location ~ /.(jgp|png|jpeg) {    (匹配jpg,png,jpeg后缀)
                    gzip on;   (开启压缩模块)
                    gzip_http_version 1.1;   (gzip压缩版本号)
                    gzip_comp_level 2;    (压缩等级,级别为1-9)
                    gzip_min_length 10k;  (图片小于10k不压缩)
                    gzip_types image/jpeg image/gif image/png image/svg+xml image/tiff image/webp;    (压缩哪些格式的图片,类型可添加)
                    gzip_vary on;    (添加 Vary: Accept-Encoding)
            }
            #(文件压缩)
            location ~ \.(txt|pdf)$ {   (匹配txt,pdf后缀)
                    gzip on;
                    gzip_http_version 1.1;
                    gzip_comp_level 2;
                    gzip_min_length 1k;
                    gzip_types text/plain application/pdf;     (压缩哪些格式的文件)
                    gzip_vary on;
            }

}

Location(控制访问网站的uri路径)

location = (精确匹配,优先级最高)

location ^~ (以某个字符串开头,优先级为2)

location ~ (区分大小写的正则匹配,优先级为3)

location ~* (不区分大小写的正则匹配,优先级为4)

location / (通用匹配,任何请求都会匹配到,优先级为5)

实例:
server {

​	listen 80;

​	server_name location2.oldxu.net;

\# 通用匹配,任何请求都会匹配到

​	location / {

​		root html;

​		index index.html;

​		}

\# 精准匹配,必须请求的uri是/nginx_status

​	location = /nginx_status { 

​		stub_status;

​		}

\# 严格区分大小写,匹配以.php结尾的都走这个location     info.php 

​	location ~ \.php$ { 

​		default_type text/html; return 200 'php访问成功'; 

​		}

 \# 严格区分大小写,匹配以.jsp结尾的都走这个location  

​	location ~ \.jsp$ { 

​		default_type text/html; 

​		return 200 'jsp访问成功'; 	

​		}

 \# 不区分大小写匹配,只要用户访 问.jpg,gif,png,js,css 都走这条location 

​	location ~* \.(jpg|gif|png|js|css)$ { 

​		return 403; 

​		expires 3d; 

​		}

 \# 不区分大小写匹配 

​	location ~* \. (sql|bak|tgz|tar.gz|.git)$ { 

​		deny all; 

​		} 

}

Location @重定向

server {

​	listen 80;

​	server_name location3.oldxu.net; root /code;

​	location / {

​		index index.html;

​		}

 

\#如果出现异常,则重新定向到@error_404这个 location上

error_page 404 @error_404; 

​	location @error_404 {

​		default_type text/html;

​		return 302 http://location3.oldxu.net;   (若出现异常则跳转回主页)

​	}

}

Nginx日志模块

$remote_addr:获取客户端的ip地址,中间经过代理则获取代理服务器的ip地址

$http_x_forwarded_for:获取客户端真实的ip地址

$http_referer:获取用户来源页面的url,记录用户是从哪个页面跳转到当前页面的

默认Nginx日志语法

vim /etc/nginx/nginx.conf

access_log /var/log/nginx/access.log main;

log_format main '\$remote_addr -\$remote_user [\$time_local] "$request" '

'\$status\$body_bytes_sent "$http_referer" '

'"\$http_user_agent" "$http_x_forwarded_for" ';

vim /etc/nginx/nginx.conf

access_log /var/log/nginx/access_test.log test

log_format test '\$remote_addr -\$remote_user [\$time_local] "$request" '

'$status';

Nginx access日志

最好给每个不同域名的server层定义access日志,做日志隔离

server {
        listen 80;
        server_name game.zjh.net;
        access_log /var/log/nginx/game.zjh.net.log main;

        location / {
                root /code;
                index index.html;
        }
}

Nginx error日志

一般定义在全局,级别有debug | info | notice | warn | error | crit | alert | emerg,默认级别为warn

error_log /var/log/nginx/game.zjh.net.log warn;

关闭错误日志

error_log /dev/null;

Nginx日志过滤

#请求favicon.ico时,不记录日志

location /favicon.ico {

​					access_log off;

​					return 200;

}

#当有人访问gif,png等静态资源时,将日志丢进黑洞

location ~* .*\\.(gif|png|jpg|css|js)$ 

{

access_log /dev/null;

}