背景分析
正向代理
正向代理类似一个跳板机,通过这个代理来访问外部资源,比如我们国内访问谷歌,直接访问访问不到,我们可以通过一个正向代理服务器,请求发到代理服务器,代理服务器能够访问谷歌,这样由代理去访问谷歌取到数据,再返回给我们,这样我们就能访问谷歌了。
暂时无法在飞书文档外展示此内容
特点说明:正向代理服务器一般都是客户端代理,代理客户端执行业务,例如VPN,这样的软件是安装在自己电脑上的
反向代理
反向代理服务器位于用户与目标服务器之间,对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。如图所示:
暂时无法在飞书文档外展示此内容
反向代理服务器通常可用来作为Web加速,即使用反向代理作为Web服务器的前置机来降低网络和服务器的负载,提高访问效率。
特点说明:反向代理服务器一般都是服务器端代理.安装在服务端电脑上,用户无需关心真实的服务器是谁.
Nginx简介
概述
Nginx是一款轻量级的HTTP服务器/反向代理服务器,其特点是占有内存少,并发**能力强**,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
特点总结:占用内存小(不到3M C语言开发),并发能力强(5万/秒)
体系结构分析
Nginx是一种基于多进程架构,它包含一个Master进程和多个Work进程,Master进程是Nginx的主进程,它用于监听并接受来自客户端的连接,并将连接请求分发给多个Work进程。这里的Worker进程是Nginx的工作进程,这些进程才是真正处理客户端请求的进程(包括请求的连接,请求的解析,请求的处理,生成具体的响应),它们彼此独立,底层会采用一种多路复用(异步、非阻塞的模式)的方式同时处理多个连接,以提高并发处理能力。如图所示:
Ngnix的优点:
1.可以充分利用多核机器,增强并发处理能力。
2.多 worker 间可以实现负载均衡。
3.Master 监控并统一管理 worker 行为。在 worker 异常后,可以主动拉起 worker 进程,从而提升了系统的可靠性。并且由 Master 进程控制服务运行中的程序升级、配置项修改等操作,从而增强了整体的动态可扩展与热更的能力。
Nginx服务安装
windows平台(了解)
本小节以Window下的安装及配置为例进行实践。(此部分内容了解即可,很少在window平台部署nginx)
下载nginx后进入nginx根目录,然后通过如下指令操作nginx服务。
启动nginx服务(启动后可以在浏览器输入http://localhost然后检测是否可以看到nginx欢迎页面)
./nginx
查看nginx版本
./nginx -v
重新载入
./nginx -s reload
快速停止nginx服务
nginx -s stop
正常停止并退出nginx服务
nginx -s quit
Linux平台(掌握)
准备工作
第一步:安装gcc
安装 nginx 需要先将官网下载的源码进行编译,编译过程依赖 gcc 环境,如果没有 gcc 环境,则需要安装:
yum install -y gcc-c++
第二步:PCRE pcre-devel 安装
PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。命令:
yum install -y pcre pcre-devel
第三步: zlib zlib-devel 安装(可选,假如已安装则无需安装)
zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。
yum install -y zlib zlib-devel
第四步:OpenSSL 安装
OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。nginx 不仅支持 http 协议,还支持 https(即在ssl协议上传输http),所以需要在 Centos 安装 OpenSSL 库。
yum install -y openssl openssl-devel
-
openssl
:它是OpenSSL的运行时库。OpenSSL是一个开源的加密库,提供了一组用于进行安全通信的加密算法和协议。openssl
包提供了在运行时使用OpenSSL库所需的文件和库文件。 -
openssl-devel
:它是OpenSSL的开发包。openssl-devel
包含了用于开发和构建使用OpenSSL的应用程序和软件包所需的头文件、静态库和链接文件。如果你需要编译、链接或开发与OpenSSL相关的软件,你需要安装openssl-devel
包。
第五步:进入/usr/local目录
cd /usr/local
第六步:执行wget指令下载nginx
wget http://nginx.org/download/nginx-1.25.2.tar.gz
第七步:解压nginx
tar xzf nginx-1.25.2.tar.gz
安装Nginx
第八步:进入nginx 根目录
cd nginx-1.25.2
第九步:执行初始化配置
./configure --prefix=/usr/local/nginx --with-http_ssl_module # 这里表示在/usr/local/nginx目录下安装Nginx,并启用HTTP SSL模块来支持HTTPS协议。
第十步:执行make编译操作(make 是一个命令工具,它解释 Makefile 中的指令(应该说是规则)。在 Makefile文件中描述了整个工程所有文件的编译顺序、编译规则)
make
第十一步:执行make install安装操作
make install
第十二步:查看验证
[root@som ~]# ls /usr/local/nginx/
-
conf: 专门用于存放NGINX配置文件
-
sbin:专门用于存放程序文件
-
html:专门用于存放网页文件
-
logs:专门用于存放日志
启动nginx
启动服务
#启动服务 /usr/local/nginx/sbin/nginx #查看七版本 /usr/local/nginx/sbin/nginx -V
验证启动是否ok
ps -ef | grep nginx
打开浏览器访问nginx服务(访问时需要先把防火墙关闭)
http://自己的ip:80
重启nginx服务
/usr/local/nginx/sbin/nginx -s reload
停止nginx服务
/usr/local/nginx/sbin/nginx -s stop
卸载nginx服务
假如需要重新安装nginx可以执行如下过程:
第一步:停止nginx服务
/usr/local/nginx/sbin/nginx -s stop
如果不知道nginx安装路径,可以通过执行ps命令找到nginx程序的PID,然后kill其PID
第二步:查找根下所有名字包含nginx的文件
find / -name nginx
第三步:执行命令 rm -rf 删除nignx安装的相关文件
说明:全局查找往往会查出很多相关文件,但是前缀基本都是相同,后面不同的部分可以用代替,以便快速删除。
[root@qll251 ~]# rm -rf /usr/local/sbin/nginx [root@qll251 ~]# rm -rf /usr/local/nginx [root@qll251 ~]# rm -rf /usr/src/nginx-1.11.1 [root@qll251 ~]# rm -rf /var/spool/mail/nginx
第四步:其他设置
如果设置了Nginx开机自启动的话,可能还需要下面两步
chkconfig nginx off rm -rf /etc/init.d/nginx
删除之后,便可重新安装nginx了
配置文件说明
Nginx的核心配置为conf目录下的nginx.conf,其初始默认配置如下:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server{
......
}
......
}
其中,nginx的配置有三部分构成,例如:
第一部分:全局块:(配置文件开始到events中间的部分内容,主要是结合硬件资源进行配置)
全局块主要设置一些影响 Nginx 服务器整体运行的参数,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数、进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等,例如worker_processes 1 表示Nginx 服务器并发处理的值,worker_processes 值越大,可以支持的并发处理数量越多。
第二部分:events块:这块主要是网络配置相关内容,硬件性能好,连接数可以配置更多。
events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,比如 worker_connections 1024; 表示 Nginx 支持的最大连接数为 1024
events { worker_connections 1024; }
第三部分:http块:nginx配置中最核心部分,可以配置请求转发,负载均衡等。
http 块也可以包括 http 部分和server部分,http 全局部分包括文件引入、MIME-TYPE 类型、日志自定义、连接超时时间、单链接请求数上限等
server部分虚拟主机有密切联系,每个 http 块可以包括多个 server块,每个 server 块就相当于一个虚拟主机,每个 server 块也分为全局 server 块和多个 location 块。
示例分析:
main段配置信息
user nginx; # 运行用户,默认即是nginx,可以不进行设置
worker_processes auto; # Nginx 进程数,一般设置为和 CPU 核数一样
error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录
pid /var/run/nginx.pid; # Nginx 服务启动时的 pid 存放位置
events段配置信息
events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
worker_connections 1024; # 每个进程允许最大并发数
}
http段配置信息
# 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
http {
# 设置日志模式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # Nginx访问日志存放位置
sendfile on; # 开启高效传输模式
tcp_nopush on; # 减少网络报文段的数量
tcp_nodelay on;
keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒
types_hash_max_size 2048;
include /etc/nginx/mime.types; # 文件扩展名与类型映射表
default_type application/octet-stream; # 默认文件类型
......
server段配置信息
server {
listen 80; # 配置监听的端口
server_name localhost; # 配置的域名
# location段配置信息
location / {
root /usr/share/nginx/html; # 网站根目录
index index.html index.htm; # 默认首页文件
deny 172.168.22.11; # 禁止访问的ip地址,可以为all
allow 172.168.33.44; # 允许访问的ip地址,可以为all
}
error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面
error_page 400 404 error.html; # 同上
}
}
Nginx配置入门
-
*入门案例**
第一步:准备web服务。
直接启动你准备好的web服务,服务地址为http://192.168.237.128:8081;
第二步:配置请求转发。
配置nginx实现请求的转换,可以直接编辑nginx.conf文件即可,例如:
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://192.168.237.128:8081;
#root /usr/share/nginx/html;
#index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
第三步:配置完以后重新启动nginx。
/usr/local/nginx/sbin/nginx -s reload
第四步:对资源进行访问检测请求转发实现。
http://192.168.237.128/index.html
实现动静分离
在前后端分离的项目架构中,Nginx可以通过配置实现动静分离,即将动态请求和静态请求分别转发给不同的后端服务器或处理方式。以下是一种常见的配置方法:
首先,需要在 Nginx 的配置文件中定义两个 location块,分别用于处理动态请求和静态请求。下面是一个简单示例:
http {
server {
listen 80;
server_name example.com;
location / {
# 静态文件处理逻辑
root /path/to/static/files;
}
location /dynamic { # dynamic是自己定义的
# 动态请求处理逻辑
proxy_pass http://backend_server; #nginx代理的服务
}
#这里还可以配置更多的location
}
upstream backend_server { #backend_server为我们自己起的名字,应用于location 对象中的proxy_pass属性。
server backend_ip:port;
}
}
上述配置中,location /
配置块用于处理静态请求,指定了静态文件存放的路径,当访问的 URL 匹配到该 location 时,Nginx 会直接返回该静态文件。
而 location /dynamic
配置块用于处理动态请求,通过 proxy_pass
指令将动态请求转发给后端服务器(backend_server
)处理。可以将后端服务器的 IP 地址和端口号配置在 upstream
块中。
使用上述配置后,当用户访问 example.com
时,若 URL 不匹配 /dynamic
,Nginx 会直接返回静态文件;若 URL 匹配 /dynamic
,Nginx 会将请求转发到后端服务器进行动态处理。
需要根据实际情况进行配置,比如根据 URL 的后缀或特定路径进行动态请求和静态请求的区分,并将它们分别转发给不同的后端服务器或处理方式。
Nginx 配置进阶
负载均衡实现
业务说明
需要搭建tomcat服务器集群(应用集群),共同抗击高并发.这时需要使用反向代理服务器.同时配置负载均衡.
集群搭建
说明:准备3台tomcat服务器.端口号分别为8001/8002/8003.
负载均衡策略
轮询策略
说明:根据配置文件的顺序,依次访问服务器.
配置服务集群(默认是轮询策略)
#配置服务列表,服务的ip地址为自己服务器的真实ip
upstream gateways{
server 192.168.1.130:8001;
server 192.168.1.130:8002;
server 192.168.1.130:8003;
}
#配置后台管理服务器
server {
listen 80;
server_name localhost;
location / {
#实现http请求的转发
proxy_pass http://gateways;
}
}
权重策略
说明:可以为某些服务器添加权重,让该服务器处理能力更强的,可以处理更多的请求。
配置应用服务列表,本次配置采用默认是轮循策略,再给一个权重值;(让能者多劳)
upstream gateways{
server 192.168.227.131:10001 weight=3;
server 192.168.227.131:10002 weight=2;
server 192.168.227.131:10003 weight=1;
}
备注,一但修改了配置文件(nginx.conf),要重新加载配置文件.(/usr/local/nginx/sbin/nginx -s reload)
IPHASH策略
问题说明:如果采用集群的部署,假如要做敏感操作,要求用户必须登录.但是由于nginx实现了负载均衡的操作,导致用户的Session数据不同共享.从而导致用户频繁登录.用户体验较差.
问题: nginx实现了tomcat负载均衡. 导致用户每次访问都是不同的服务器,但是用户的登录信息是存储在一台应用服务器上的,其它服务器没有这个登录信息,所以在访问到其它服务器时还需要重新登录。
解决方案: 能否让用户每次访问同一台服务器?答案是可以的,我们可以采用IPHASH策略,对请求进行负载均衡。
这样,同一个IP执行hash操作的结果肯定是相同。
IPHASH调用原理 如图所示:
IPHASH的配置如下:
#配置服务应用列表
upstream geteways { ip_hash; server 192.168.227.131:10001 weight=6; server 192.168.227.131:10002 weight=3; server 192.168.227.131:10003 weight=1; }
-
IPHASH存在的问题
-
IPHASH如果一旦服务器出现异常,导致业务请求失效.
-
可能会出现负载不均的现象.负载有高有低(可在测试中试用).
一般不会使用IPHASH,有时只是在测试中使用一下。
NGINX常用属性
Down属性
说明:如果服务器宕机,可以在配置文件中标识为down.这样以后不会再访问故障机.
upstream geteways { #ip_hash; server 192.168.227.131:10001 down; server 192.168.227.131:10002; server 192.168.227.131:10003; }
BACKUP设计
说明:备用机设置,正常情况下该服务器不会被访问.当主机全部宕机或者主机非常忙时,该服务器才会访问.
upstream geteways { #ip_hash; server 192.168.227.131:10001 down; server 192.168.227.131:10002:8082; server 192.168.227.131:10003 backup; }
宕机服务器高可用实现
说明:当服务器宕机时,如果访问的失败次数达到最大失败次数,则标识为down.自动完成.在一定的周期之内,如果服务器恢复正常,则还会尝试访问故障机.
max_fails=1 最大的失败次数
fail_timeout=60s; 设定周期为60秒
upstream geteways { #ip_hash; server 192.168.227.131:10001 max_fails=1 fail_timeout=60s; server 192.168.227.131:10002 max_fails=1 fail_timeout=60s; server 192.168.227.131:10003 max_fails=1 fail_timeout=60s; }
总结(Summary)
重难点分析
-
nginx体系结构(多进程架构,一个master多个worker)
-
nginx动静分离配置(服务于前后端分离结构)
-
nginx负载均衡配置(轮询,轮询+权重,ip_hash)
FAQ分析
-
防火墙问题
在 windows 系统中访问 linux 中 nginx,默认不能访问的,因为防火墙问题 (1)关闭防火墙 (2)开放访问的端口号,80 端口
查看开放的端口号
firewall-cmd --list-all
设置开放的端口号
firewall-cmd --add-service=http –permanent firewall-cmd --add-port=80/tcp --permanent
重启防火墙
firewall-cmd –reload
-
为什么不采用多线程模型管理连接?
Nginx之所以选择了多进程模型而不是多线程模型来管理连接,是因为多进程模型在处理并发连接时具有一些优势,并且能够更好地应对高负载的情况。以下是一些原因:
-
高效的事件驱动机制:Nginx使用了高效的事件驱动模型,即使用一个主进程来监听网络事件,而不是每个连接都创建一个线程。这样可以极大地减少线程的创建和销毁开销,提高系统的性能和资源利用率。
-
内存消耗低:相比于多线程模型,多进程模型在一定程度上减少了内存的消耗。每个 Nginx worker 进程只需加载相应的代码和数据,而不需要像多线程模型那样为每个连接分配栈空间。
-
可靠性和稳定性:由于每个 Nginx worker 进程都是独立的,一个进程的崩溃或异常不会影响其他进程的正常运行,从而提高了系统的可靠性和稳定性。
-
可扩展性:多进程模型使得 Nginx 能够进行水平扩展,即通过增加额外的 worker 进程来处理更多的并发连接,从而满足高负载的需求。
需要注意的是,虽然多线程模型在某些情况下可能具有一定的优势,但由于线程间共享资源的复杂性和线程安全性的考虑,针对高并发和高负载情况,Nginx选择了多进程模型来更好地适应这些需求。
-
为什么不采用多线程处理逻辑业务?
Nginx不采用多线程来处理逻辑业务的原因主要有以下几点:
-
线程安全问题:在多线程环境下,多个线程同时访问共享数据可能会导致数据竞争和不一致的状态。为了保证线程安全,需要使用锁或其他同步机制,这会增加复杂度并且可能造成性能损失。
-
内存消耗:每个线程需要独立的栈空间,以及用于存储线程相关的数据结构和上下文等。对于管理大量连接的服务器来说,创建和销毁大量的线程会消耗大量的内存。
-
上下文切换开销:在多线程模型下,线程的调度和切换会增加额外的开销,包括保存和恢复线程的寄存器状态、切换内核栈等。对于高并发的场景,这些开销可能会显著影响系统的性能和响应速度。
-
可伸缩性限制:尽管多线程模型在某些情况下可以提供更高的并发能力,但是线程数量的增加也会带来一些问题。比如,为了避免线程过多导致调度和资源消耗过大,需要进行线程池管理。而线程池的管理也需要考虑线程的创建和回收、工作调度等问题,增加了系统复杂性。
相比之下,Nginx选择了多进程模型来处理逻辑业务。多进程模型在一定程度上解决了上述问题,每个进程独立处理连接而不共享资源,进程间的通信可以使用更简单高效的机制(如共享内存),同时提供更好的稳定性和可靠性。此外,Nginx通过事件驱动的方式来处理请求,避免了线程切换和锁竞争等开销,提高了系统的性能和并发能力。