1. 简介
官网:nginx
Nginx是一个高性能的 HTTP 和反向代理 Web 服务器。它的主要功能包括反向代理、负载均衡和动静分离等。正因为 Nginx的这些功能能够为系统带来性能和安全方面的诸多优势,我们在项目部署时需要引入 Nginx组件。接下来我们会逐一向大家介绍nginx的核心功能。
2. 功能介绍
2.1. 反向代理
要想搞清楚什么是反向代理,就必须先来了解一下什么是正向代理。
正向代理
正向代理通常是指客户端(如浏览器)通过代理服务器来访问互联网上的其他服务器。在这种情况下,客户端配置了代理设置(注意这个代理是在客户端配置的),所有对外的请求都会先发送到代理服务器上,再由代理服务器转发到真正的目标服务器。这样做的好处包括但不限于:
- 隐私保护:客户端的真实IP地址不会直接暴露给外部服务器。
- 缓存:如果代理服务器具有缓存功能,那么对于频繁请求的数据,可以直接从缓存中返回结果,提高响应速度。
- 内容过滤:组织或企业可以使用正向代理对员工的上网行为进行监控或者过滤不合适的网站内容。
正向代理的特点:
- 代理配置的相关设置实在客户端完成的,也就是客户端需要明确配置使用的代理服务器,由代理服务器充当客户端和目标服务器之间的桥梁;
- 正向代理无法隐藏目标服务器的信息,客户端仍能知道访问的目标地址;
- 如果代理服务器被禁用,访问可能无法完成。
反向代理
反向代理则是指客户端直接访问的服务器实际上是一个代理服务器(注意代理服务器在服务器端配置 ),这个代理服务器接收客户端的请求后,会将请求转发给真正的后端服务器。客户端本身是不知道这个代理服务器存在的。反向代理的应用场景包括:
- 负载均衡:通过反向代理可以在多个后端服务器之间分配请求,以分散单个服务器的压力。
- 安全性:隐藏真实的后端服务器地址,增加了一层安全防护。
- 缓存与加速:类似于正向代理,反向代理也可以实现缓存功能,减少后端服务器的负载并加快响应速度。
2.2. 负载均衡
前面提到了nginx的反向代理,这个反向代理和负载均衡是相辅相成的。Server端的代理收到client的请求后,在client无感知的情况下即可根据设定的负载均衡算法,将client的请求分发到不同的server上。
那么,为什么需要负载均衡?这是为了避免单点故障或者现有的请求使服务器压力太大无法承受。所以我们需要搭建一个服务器集群(如上图所示服务端有多个服务器),将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将"负载"均衡的分发到不同的服务器,也就是我们所说的负载均衡。
那假如我们增加了A、B、C、D等等多台服务器,我们需要把请求分给这些服务器,但是每个服务器也有自己的不同,性能也可能不均,所以怎么分?如何分配更好?又是一个问题。nginx提供了几种算法来解决这个问题:
1. 轮询(Round Robin)
- 工作原理:按照顺序将请求分发到每一台服务器,依次循环。
- 特点:简单易用,适用于服务器性能相近的场景。
2. 加权轮询(Weighted Round Robin)
- 工作原理:为每一台服务器设置一个权重(weight),权重越高,分配的请求就越多。
- 特点:适用于服务器性能不均的情况(能者多劳)。
3. 最少连接(Least Connections)
- 工作原理:nginx 会统计每个后端服务器当前的活动连接数,当有新的请求到来时,将请求分配给当前活动连接数最少的服务器。
- 特点:能够根据服务器的实际负载情况动态地分配请求,适用于请求处理时间较长、服务器负载不均的场景。
4. IP哈希(IP Hash)
- 工作原理:根据客户端IP计算哈希值,将请求分配到固定的服务器(每一个访客固定访问一个后端服务器)。
- 特点:适用于需要会话保持的场景,比如用户登录。
2.3. 动静分离
Nginx 的动静分离功能是一种高效的 Web 服务架构,它通过将动态请求和静态请求分离到不同的服务器上处理,提高了服务器性能和资源利用率。
何为动、何为静
- 静态资源(如
.html
,.css
,.js
,.jpg
等)由 Nginx 直接处理或转发到专门的静态资源服务器。 - 动态请求(如
.php
,.asp
,.jsp
等)通过反向代理转发到应用服务器处理,是通过请求服务器获取到的资源。
这些静态资源既然无需服务器处理,则可以由nginx直接来处理无需后端服务器介入。这样可以减轻后端服务器的负载,使其专注于处理动态内容,从而提高整体性能。并且们还可以根据 静态资源 的特点将其做缓存操作,以提高资源的响应速度。如下图所示:动态资源和静态资源的处理是分开的。
动静分离的优点
- 性能提升:Nginx 处理静态资源速度快,减少应用服务器压力。
- 扩展灵活:静态资源和动态请求可独立部署和优化。
- 缓存效率高:为静态资源配置浏览器缓存,提高访问速度。
3. 小总结
在本地开发时,我们通常无需使用nginx。因为本地开发的时候我们专注于业务功能的实现。然而,一旦项目开发完成,并准备部署到服务器上,我们就需要考虑性能、安全等一系列的问题这个时候我们就需要部署nginx,以构建一个完整且稳定的运行环境。
4. Docker安装
这里因为80端口太容易冲突了,所以我对外暴露的端口号修改成了5413
#拉取nginx镜像
docker pull nginx:1.21
#启动nginx容器
docker run --name oj-nginx -d -p 5413:80 nginx:1.21
启动成功后访问nginx首页:http://localhost:5413/,注:向外暴漏的端口号是5413。出现下面的欢迎页说明安装成功了。
5. 配置nginx实现反向代理和负载均衡
5.1. 配置文件介绍
这里我就是用一个简单的Demo服务,来测试一下反向代理和负载均衡的配置。至于不同的不在均衡算法,也只是使用不同的配置。这是的关键问题就是对nginx进行配置,修改nginx的配置文件。
5.1.1. nginx的配置文件在哪里?
- 主配置文件:/etc/nginx/nginx.conf
- 附加配置文件:在 /etc/nginx/conf.d/目录下,已经默认给我们提供了一个附加配置文件:/etc/nginx/conf.d/default.conf,在主配置文件中会引入附加配置文件,如下。
我们可以打开主配置文件来看一下,如下图。在主配置文件中,可以看到这里引入了附加配置文件,这样也就意味着nginx的完整的配置应该是主配置文件+附加配置文件。这样也方便我们对配置进行管理,保持主配置文件的清晰和整洁。
5.1.2. 如何修改nginx的配置文件
- 推荐(不是必须): 应该尽可能使用 /etc/nginx/conf.d/default.conf 或其他在/etc/nginx/conf.d/目录下的附加配置文件来添加或修改你的 Nginx配置,而不是直接编辑 /etc/nginx/nginx.conf 文件。这样做可以保持主配置文件的清晰和整洁,并使得配置更易于管理和维护。
- 注意:修改配置之后,还需要通过重载 Nginx 来应用更改
nginx -s reload
这里我是通过docekr安装的nginx:
docker restart [容器名称或ID]命令
5.2. 配置步骤
-
这里我使用一个简单的测试接口,他自己单独作为一个服务,用于测试nginx的配置。
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test/nginx")
@Slf4j
public class NginxTestController {
@GetMapping("/info")
public String info() {
log.info("负载均衡测试");
return "测试通过...";
}
} -
然后启动两个不同的test服务
这里我已经启动了一个服务,如何不修改代码,直接启动两个不同端口的服务呢?
复制服务后,修改该服务的启动配置即可
然后启动服务,就可以得到两个test服务了
- 修改nginx配置
upstream testServers {
# 轮询(默认方式)
server 192.168.5.1:8123; # 后端服务1
server 192.168.5.1:8124; # 后端服务2
# 加权轮询(如果后端服务性能不同,可以设置权重)
# server 127.0.0.1:8123 weight=3; # 更高权重
# server 127.0.0.1:8124 weight=1; # 更低权重
}
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location /testprefix/ {
proxy_pass http://testServers/;
}
这个配置就会将所有的请求,代理到我们upstream中配置的test_service服务组中。修改完后,重启nginx。
注意这里我的ip环境是,因为我的docekr是在win上启动的可视化。使用的是win的ip。根据自己情况改变。
5.3. 访问接口进行测试
访问:http://localhost:5413/test/nginx/info 进行测试
**为什么访问地址是这个?**原因是我们测试需要通过nginx调用这个接口而不是直接调用,这样才能测试处负载均衡反向代理的效果。加上我们在nginx配置文件中进行了配置以/testPrefix/开头的请求都代理到我们 upstream 中配置的服务器组当中。实际上请求的地址会变成 http://localhost:8123/test/nginx/info 或者 http://localhost:8124/test/nginx/info。
观察结果,如下图。两个端口的服务轮询收到了请求。