快速了解Nginx
- 一、代理
- 1.1 正向代理
- 1.2 反向代理
- 1.3 正向代理和反向代理的区别
- 二、Nginx负载均衡策略
- 2.1 轮询(Round Robin)
- 2.2 加权轮询(Weighted Round Robin)
- 2.3 IP 哈希(IP Hash)
- 2.4 最少连接(Least Connections)
- 2.5 随机(Random)
- 三、动静分离
- 四、配置文件解析
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的。
特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。
Nginx 是一个安装非常的简单、配置文件非常简洁(还能够支持perl语法)、Bug非常少的服务。Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够不间断服务的情况下进行软件版本的升级。
Nginx代码完全用C语言从头写成。官方数据测试表明能够支持高达 50,000 个并发连接数的响应。
一、代理
1.1 正向代理
正向代理是一种网络代理模式,代理服务器位于客户端和目标服务器之间。它的主要功能是接受客户端请求,并将这些请求转发到目标服务器,然后将响应返回给客户端。正向代理通常用于实现访问控制、隐私保护、缓存等功能。
工作原理:
- 客户端请求:客户端(例如浏览器)向正向代理服务器发送请求,而不是直接请求目标服务器。
- 代理处理请求:正向代理接收到请求后,会将其转发到目标服务器。这时,目标服务器并不知道是哪个客户端在请求。
- 目标服务器响应:目标服务器将响应发送回正向代理服务器。
- 代理服务器返回响应:正向代理接收到从目标服务器返回的响应,并将其转发给客户端。
应用场景:
- 访问控制,通过设置代理服务器规则实现外来请求是否能够访问目标服务器。
- 匿名访问,代理服务器作为访问中介,双方都只知道代理服务器的 ip 信息。
- 加速访问,代理服务器能够缓存常见请求的响应,减少通信延迟,提高访问速度。
- 跨地域访问,有些内容会因为地域限制而无法访问,用户可以通过正向代理伪装成其他地区的用户来访问被限制的内容。
1.2 反向代理
反向代理是一种服务器配置,它可以接收客户端的请求,并将这些请求转发到后端的一个或多个服务器上。反向代理通常用于负载均衡、安全性、缓存等目的。
工作原理:
- 客户端请求:客户端(如用户的浏览器)发送一个HTTP请求,请求的数据可能是网页、图像或其他资源。
- 到达反向代理服务器:请求首先到达反向代理服务器,而不是直接到达后端应用服务器。
- 请求转发:反向代理服务器根据配置的规则,决定将请求转发到哪一台后端服务器。这些规则可以基于URL路径、负载均衡策略等。
- 后端处理:被选中的后端服务器接收到请求并进行处理。这可能涉及查询数据库、计算、调用其他服务等。
- 返回响应:后端服务器完成请求处理后,将相应的数据(如HTML页面、JSON 数据、文件等)返回给反向代理服务器。
- 响应转发给客户端:反向代理服务器接收到后端服务器的响应后,可能会对其进行缓存、修改或记录日志,然后再将响应发送回客户端。
- 客户端接收响应:客户端最终收到来自反向代理服务器的响应,呈现给用户。
应用场景:
- 负载均衡,反向代理可以将客户端请求分发到多个后端服务器,从而实现负载均衡。这种方法可以提高系统的可用性和性能,确保没有单一服务器过载。
- SSL/TLS终止,反向代理可以处理HTTPS请求,为后端服务器减轻了SSL/TLS加密和解密的负担。通过集中管理证书,使得更新和维护变得更加简单。
- 安全防护,使用反向代理可以隐藏后端服务器的真实地址,提供额外的安全层。它可以过滤恶意请求、进行身份验证或防止DDoS攻击等。
- 跨跨域资源共享(CORS),在某些情况下,反向代理可以用于解决跨域请求的问题。通过设置适当的HTTP头,允许特定源访问后端资源。
- 微服务架构,在微服务架构中,反向代理可以帮助路由请求到不同的服务。它也可以充当API网关,统一管理所有的API请求。
1.3 正向代理和反向代理的区别
正向代理是客户端与互联网之间的中介。客户端通过正向代理访问其他网站或服务,而不是直接访问目标服务器。
客户端在访问互联网时,使用正向代理服务器作为请求的发起端,这样目标服务器就无法识别到客户端的真实IP信息,对客户端的身份起到一定的保护作用。
反向代理是位于客户端和一组后端服务器之间的中间层。客户端向反向代理发送请求,而反向代理将请求转发给适当的后端服务器。
客户端在访问后端服务器时,访问的并不是真实的后端服务器地址,而是反向代理服务器,所有的服务访问都通过反向代理服务进行范围,由其进行转发。这样后端服务器架构就能够被很好的保护起来。
反向代理和正向代理的主要区别在于它们的工作方向及其角色定位,而不是仅仅依赖于请求的发起者(客户端或后端服务器)。
正向代理代理的是客户端,反向代理代理的是服务器端。
二、Nginx负载均衡策略
为了让资源更多的服务器接收到更多的访问请求,让每台服务器能够利用好自身的资源。 Nginx 提供了多种负载均衡策略,可以根据不同的需求和场景选择合适的策略。
2.1 轮询(Round Robin)
这是 Nginx 的默认负载均衡方法。请求按照顺序分配给后端服务器,即第一个请求发送给第一台服务器,第二个请求发送给第二台,以此类推。如果有多个请求并发到达,则会循环遍历后端服务器。
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
适用于无状态的访问请求,即没有保留相关数据在目标服务器上的访问请求,如果请求存在状态保存在目标服务器,那么下次访问时可能相应的不是上次的服务器,导致状态丢失。
2.2 加权轮询(Weighted Round Robin)
与简单的轮询类似,指定轮询几率,weight和访问比率成正比,但每台后端服务器可以被分配不同的权重。权重越高,被分配到请求的概率就越大。这对于性能差异较大的服务器特别有效。
upstream backend {
server backend1.example.com weight=3 down; # 权重为3
server backend2.example.com weight=2 backup; # 权重为2
server backend3.example.com weight=1; # 权重为1
}
down:表示当前的server暂时不参与负载
weight:默认为1.weight越大,负载的权重就越大。
backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。
2.3 IP 哈希(IP Hash)
这种方法使用客户端的 IP 地址计算哈希值,将请求总是分配给同一台后端服务器。这样可以保证相同用户的请求始终落在同一服务器上,可以解决session不共享的问题,适合需要会话保持的场景(如购物车应用)。
IPHash的轮询方式确实能解决Session问题,但是考虑到服务器可能存在宕掉的风险导致数据丢失,因此一般采用Redis对Session进行共享。
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
2.4 最少连接(Least Connections)
策略将请求路由到当前连接数最少的后端服务器。这对于处理长连接或高延迟请求非常有效,因为它可以确保负载在所有服务器之间尽可能均匀分配。
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
2.5 随机(Random)
这个策略随机选择一台后端服务器来处理请求。这种方式可以在负载相对均衡的情况下减轻某些特定服务器的压力。
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
# 配置随机负载均衡
# 注意:Nginx 默认没有提供随机算法,需要使用第三方模块
}
三、动静分离
动静分离,在我们的软件开发中,有些请求是需要后台处理的,有些请求是不需要经过后台处理的(如:css、html、jpg、js等等文件),这些不需要经过后台处理的文件称为静态文件。
让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作。提高资源响应的速度。
静态内容:如 HTML 文件、CSS 文件、JavaScript 文件、图片等,这些资源不需要服务器端处理,可以直接由 Nginx 提供。
动态内容:如 PHP、Python、Node.js 等,通过后端应用程序生成的内容,这些内容通常需要 web 应用服务器进行处理。
文件配置:
server {
# 静态文件配置
当URL为/时,提供静态文件/var/www/html/index.html供访问
location / {
root /var/www/html; # 指向静态文件目录
index index.html index.htm;
try_files $uri $uri/ =404; # 如果文件不存在,返回 404
}
# 针对特定目录的静态文件处理
当访问URL为/static/XX时,根据下边配置的静态资源文件夹中的文件提供访问
location /static/ {
alias /var/www/static/; # 指向静态资源文件夹
}
# 动态内容处理(例如 PHP)
location ~ \.php$ { #此处是可以使用正则表达式的
include snippets/fastcgi-php.conf; # 引入 FastCGI 配置
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # PHP-FPM 的 socket 地址
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; # 包含 FastCGI 参数
}
}
静态内容处理:
/ 路径下的请求会被直接处理为静态文件。如果请求的文件存在,则返回该文件;否则返回 404 错误。
/static/ 路径用于处理静态文件,使用 alias 指令将 URI 映射到实际文件系统的位置。
动态内容处理:
使用正则表达式匹配以 .php 结尾的请求,并通过 fastcgi_pass 将请求转发给 PHP-FPM(FastCGI Process Manager),以便处理 PHP 文件。
对于其他动态请求(如 API 请求),我们通过 proxy_pass 将请求代理到 Node.js 应用程序或其他后端服务。
具体可以看下边的配置文件解析哈
四、配置文件解析
#全局配置
user www-data; #指定运行 Nginx 工作进程的用户和组,通常选择一个权限较低的用户(如 www-data)以增强安全性。
worker_processes auto; #设置工作进程的数量。使用 auto 可以根据系统的 CPU 核心数自动调整,通常建议设置为 CPU 核心数,以提高性能。
#错误日志配置 #
error_log /var/log/nginx/error.log warn; #配置错误日志的路径及其日志级别,级别包括 debug, info, notice, warn, error, crit, alert, emerg
pid /var/run/nginx.pid; #指定存放 Nginx 主进程 PID(进程标识符)的文件路径。
#处理事件配置
events {
worker_connections 1024; #表示每个工作进程能够同时处理的最大连接数
}
#定义上游服务器,用于负载均衡
upstream backend { #此处的backend名称可用于下边的server调用
# 定义后端服务器
server backend1.example.com; # 服务器 1
server backend2.example.com; # 服务器 2
server 192.168.1.100:8080; # 服务器 3(IP 地址)
# 可以指定权重,数字越大表示优先级越高
server backend3.example.com weight=3; # 权重为 3
}
#网络请求配置
http {
include mime.types; t-Type。
default_type application/octet-stream; #未明确指定类型时使用的默认 MIME 类型。
#访问日志的格式
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; #设置访问日志的存放路径和使用的日志格式。此处使用前面定义的 main 格式。
sendfile on; # 启用高效的文件传输方式,将文件从磁盘直接发送到网络,而无需经过用户空间,减少 CPU 占用率,提高性能。
tcp_nopush on; # 在发送大文件时,尽可能将数据一起发送,减少 TCP 分段,提高效率。
tcp_nodelay on; # 禁用 Nagle 算法,以便尽快发送小的数据包,适用于交互型应用。
keepalive_timeout 65; # 设置 HTTP Keep-Alive 连接的超时时间,单位为秒。即在这段时间内,如果没有新的请求,则连接会被关闭。
#GZip压缩设置
gzip on; #开启 Gzip 压缩功能,可以减小传输的数据量,提高加载速度。
gzip_types text/plain application/json application/javascript text/css application/xml text/xml application/xhtml+xml; #指定哪些 MIME 类型的响应内容应进行 Gzip 压缩。
gzip_min_length 1000; #指定 Gzip 压缩的最小响应体长度,只有当响应体长度超过该值时,才会进行压缩。
#服务器访问设置
server {
listen 80; #指定Nginx监听的 IP 地址和端口号,80 表示监听 HTTP 请求。
server_name localhost; #定义服务器的名称,通常是域名或 IP 地址。当多个虚拟主机存在时,用于匹配请求的主机名。
#用于定义如何处理特定 URI 的请求,可以根据请求的 URI 路径进行不同的处理。
location / {
root /var/www/html; #定义文档根目录,Nginx 将从该目录提供静态文件。
index index.html index.htm; #定义默认的索引文件,例如 index.html 或 index.htm,当请求目录时会返回这些文件(/var/www/html/index.html)。
try_files $uri $uri/ =404; #如果文件不存在,返回 404
}
#提供静态文件配置
location /static/ {
alias /var/www/static/; #将 URI 映射到实际文件系统的位置。
}
error_page 404 /404.html; #定义特定错误代码(如 404)的定制错误页面,可用于改善用户体验。
#当访问URL等于/404.html时,internal用于标记该位置块为内部重定向使用。
location = /404.html {
internal; #它不能直接通过 HTTP 请求访问。例如,如果用户在浏览器中直接访问 /404.html,Nginx 将返回 404 错误,而不是显示该页面。
}
#指定以 /api/ 开头的请求的处理方式,这里使用了反向代理。
location /api/ { #当URL为 Nginx服务器:80/api 时触发反向代理
proxy_pass http://127.0.0.1:3000; #将请求转发到指定的后端服务器,通常用于将负载分发到应用程序服务器。
proxy_set_header Host $host; #设置代理请求中的 HTTP 头部信息,用于传递原始请求的信息,例如请求头部的 Host 和用户的真实 IP 地址。
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
#指定以 /server/ 开头的请求的处理方式。
location /server/ { #当URL为 Nginx服务器:80/server 时触发负载均衡
proxy_pass http://backend; # 将请求转发到定义的 upstream, 即按照预定的规则(轮询,权重,随机等)转发到定义的集群中的对应节点
proxy_set_header Host $host; # 传递主机头信息
proxy_set_header X-Real-IP $remote_addr; # 传递真实用户 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递 X-Forwarded-For 头
}
}
}