nginx --- 反向代理|负载均衡 | 动静分离

目录

反向代理如何配置

1、反向代理实例一

2、反向代理实例二

ocation 指令说明

 Nginx 负载均衡 

负载均衡常用算法

应用场景

总结

Nginx实现动静分离 

一、什么是动静分离

二、实现方案

三、配置Nginx动静分离

四、验证测试


反向代理如何配置

1、反向代理实例一

实现效果:使用 Nginx 反向代理,访问 http://localhost:8080/  直接跳转到 http://192.168.1.130:9090

配置代码

  server {
    listen 8080;
    server_name localhost;

    location / {
      root html;
      index index.html index.htm;
      try_files $uri $uri/ /index.html; # 解决刷新404
      proxy_pass http://192.168.1.130:9090;
    }
}

如上配置,我们监听 8080 端口,访问域名为  http://localhost:8080/,故访问该域名时会跳转到 http://192.168.1.130:9090 路径上(不加端口号时默认为 80 端口)。

此处的意思为:nginx 反向代理服务监听 http://localhost/的8080端口,如果有请求过来,则转到proxy_pass配置的对应服务器上,仅此而已。

实验结果:

 

2、反向代理实例二

实现效果:使用 Nginx 反向代理,根据访问的路径跳转到不同端口的服务中,Nginx 监听端口为 9001。

  • 访问 http://192.168.1.130:8080/edu/ 直接跳转到 http://192.168.1.130:9091/;
  • 访问 http://192.168.1.130:8080/vod/ 直接跳转到 http://192.168.1.130:9092;

第一步,需要准备两个服务器,一个 9091 端口,一个 9092 端口,并准备好测试的页面

第二步,修改 nginx 的配置文件,在 http 块中配置 server

  server {
    listen 8080;
    server_name localhost;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;




    location / {
      root html;
      index index.html index.htm;
      try_files $uri $uri/ /index.html; # 解决刷新404
      proxy_pass http://192.168.1.130:9090;
    }

    location /edu/ {
      proxy_pass http://192.168.1.130:9091/;
    }

    location /vod/ {
      proxy_pass http://192.168.1.130:9092/;
    }
}

根据上面的配置,当请求到达 Nginx 反向代理服务器时,会根据请求进行分发到不同的服务上。

实验结果


在 Nginx 配置文件中,location 指令用于定义请求的处理规则。当指定一个 location 时,如果路径后面加上斜杠 /,表示匹配该路径及其所有子路径。如果不加斜杠,则只匹配精确的路径。

例如:

  • location /edu 会匹配任何以 /edu 开头的请求,但不会匹配 /edu/
  • location /edu/ 会匹配以 /edu/ 开头的请求,包括 /edu/ 本身及其所有子路径。

在代理配置中,proxy_pass 指令用于指定请求应该被转发到哪个上游服务器。当你在 location 后面加上 / 时,Nginx 会将请求转发到指定的上游服务器,并且保持原始请求的路径不变。

ocation 指令说明

该指令用于匹配 URL, 语法如下:

location [ = | ~ | ~* | ^~] uri {

}
  • = :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配, 如果匹配成功,就停止继续向下搜索并立即处理该请求。
  • ~:用于表示 uri 包含正则表达式,并且区分大小写。
  • ~*:用于表示 uri 包含正则表达式,并且不区分大小写。
  • ^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求

字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location块中的正则 uri 和请求字符串做匹配。

注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识

 Nginx 负载均衡 

负载均衡(Load Balance),它在网络现有结构之上可以提供一种廉价、有效、透明的方法来扩展网络设备和服务器的带宽,并可以在一定程度上增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性等。用官网的话说,它充当着网络流中“交通指挥官”的角色,“站在”服务器前处理所有服务器端和客户端之间的请求,从而最大程度地提高响应速率和容量利用率,同时确保任何服务器都没有超负荷工作。如果单个服务器出现故障,负载均衡的方法会将流量重定向到其余的集群服务器,以保证服务的稳定性。当新的服务器添加到服务器组后,也可通过负载均衡的方法使其开始自动处理客户端发来的请求。(详情可参考:What Is Load Balancing?)

简言之,负载均衡实际上就是将大量请求进行分布式处理的策略。

负载均衡常用算法

1. 轮询 (round-robin)

轮询为负载均衡中较为基础也较为简单的算法,它不需要配置额外参数。假设配置文件中共有 M 台服务器,该算法遍历服务器节点列表,并按节点次序每轮选择一台服务器处理请求。当所有节点均被调用过一次后,该算法将从第一个节点开始重新一轮遍历。

特点:由于该算法中每个请求按时间顺序逐一分配到不同的服务器处理,因此适用于服务器性能相近的集群情况,其中每个服务器承载相同的负载。但对于服务器性能不同的集群而言,该算法容易引发资源分配不合理等问题。

2、加权轮询

为了避免普通轮询带来的弊端,加权轮询应运而生。在加权轮询中,每个服务器会有各自的 weight。一般情况下,weight 的值越大意味着该服务器的性能越好,可以承载更多的请求。该算法中,客户端的请求按权值比例分配,当一个请求到达时,优先为其分配权值最大的服务器。

特点:加权轮询可以应用于服务器性能不等的集群中,使资源分配更加合理化。

Nginx 加权轮询源码可见:ngx_http_upstream_round_robin.c,源码分析可参考:关于轮询策略原理的自我理解。其核心思想是,遍历各服务器节点,并计算节点权值,计算规则为 current_weight 与其对应的 effective_weight 之和,每轮遍历中选出权值最大的节点作为最优服务器节点。其中 effective_weight 会在算法的执行过程中随资源情况和响应情况而改变。较为核心的部分如下:

for (peer = rrp->peers->peer, i = 0;
	peer; 	/* peer 为当前遍历的服务器结点*/
  peer = peer->next, i++)
{
  ...
    
	/* 每轮遍历会更新 peer 当前的权值*/
	peer->current_weight += peer->effective_weight;

  ...
    
	/* best 为当前服务器中的最优节点,即本轮中选中的服务器节点*/
	if (best == NULL || peer->current_weight > best->current_weight) {
		best = peer;
  	p = i;
	}
  
  ...
}


3. IP 哈希(IP hash)

ip_hash 依据发出请求的客户端 IP 的 hash 值来分配服务器,该算法可以保证同 IP 发出的请求映射到同一服务器,或者具有相同 hash 值的不同 IP 映射到同一服务器。

特点:该算法在一定程度上解决了集群部署环境下 Session 不共享的问题。

Session 不共享问题是说,假设用户已经登录过,此时发出的请求被分配到了 A 服务器,但 A 服务器突然宕机,用户的请求则会被转发到 B 服务器。但由于 Session 不共享,B 无法直接读取用户的登录信息来继续执行其他操作。

实际应用中,我们可以利用 ip_hash,将一部分 IP 下的请求转发到运行新版本服务的服务器,另一部分转发到旧版本服务器上,实现灰度发布。再者,如遇到文件过大导致请求超时的情况,也可以利用 ip_hash 进行文件的分片上传,它可以保证同客户端发出的文件切片转发到同一服务器,利于其接收切片以及后续的文件合并操作。

4、其他算法

  • URL hash

    url_hash 是根据请求的 URL 的 hash 值来分配服务器。该算法的特点是,相同 URL 的请求会分配给固定的服务器,当存在缓存的时候,效率一般较高。然而 Nginx 默认不支持这种负载均衡算法,需要依赖第三方库。

  • 最小连接数(Least Connections)

    假设共有 M  台服务器,当有新的请求出现时,遍历服务器节点列表并选取其中连接数最小的一台服务器来响应当前请求。连接数可以理解为当前处理的请求数。

应用场景

说了这么多理论,究竟基于 Nginx 的负载均衡要怎么用呢?接下来,将以加权轮询算法为例,带大家尝试通过自己的一台笔记本 + Nginx + Node 测试一下负载均衡。由于没有多台服务器,于是通过自己笔记本的多个不同端口来模拟不同的服务器。


Step 1:确保自己的电脑中,Nginx 已安装并能够成功启动(以 Mac 为例)

如果你也遇到了像我一样由于端口占用导致 Nginx 启动失败的问题,可以尝试下述步骤修改配置文件中的端口号

  • 相关文件路径

    • /usr/local/etc/nginx/nginx.conf (配置文件路径)
    • /usr/local/var/www (服务器默认路径)
    • /usr/local/Cellar/nginx/1.8.0 (安装路径)
  • 修改 nginx.conf 文件中的端口

server {
  # listen       8080;
  listen       8086;
  server_name  localhost;
}
  • Nginx 配置文件 nginx.conf 中主要包含以下几个部分:

    • server:主机服务相关设置,主要用于指定虚拟主机域名、IP 和端口
    • location:URL 匹配特定位置后的设置,反向代理设置
    • upstream:负载均衡相关配置
  • 暂停 Nginx 并重启

// 暂停 Nginx 服务
sudo nginx -s stop
// 启动 Nginx 服务
nginx

打开 http://localhost:8086/ 测试是否成功,如果显示下图,则证明启动成功~


 

Step 2:基于 Node + Express 框架来搭建简单的服务器

Express 是一个简洁而灵活的轻量级 node.js Web 应用框架(详情可了解 Express),如果第一次使用,请先安装。

  • 安装 Express

    npm i express

  • 新建 index.js 文件,并写入代码 
const express = require('express');
const app = express();

// 定义要监听的端口号
const listenedPort = '8087';

app.get('/', (req, res) => res.send(`Hello World! I am port ${listenedPort}~`));

// 监听端口
app.listen(listenedPort, () => console.log(`success: ${listenedPort}`));
 
  • 启动服务器

    node index.js

此处可以多起几个服务,分别让 Node 监听 8087,8088,8089 端口,每个服务中通过 send 不同的文案用以区分不同的 Server。

Step 3:在 nginx.conf 文件中配置好需要轮询的服务器和代理

  • 轮询的服务器,写在 http 中的 upstream 对象里:
upstream testServer {
  server localhost:8087 weight=10;
  server localhost:8088 weight=2;
  server localhost:8089;
}
  • 代理地址,写在 http 中的 server 对象里:
location / {
  root   html;
  index  index.html index.htm;
  proxy_pass http://testServer; // testServer 为自己定义的服务器集群
}	

Step 4:查看结果

  • 重启 Nginx 服务

  • 再次打开 http://localhost:8086/

通过多次刷新可以发现,由于设置了不同的 weight,端口号为 8087 的服务器出现的次数最多,同时证实了权值越高,服务器处理请求几率越大的规则。

总结

Nginx 作为一款优秀的反向代理服务器,可以通过不同的负载均衡算法来解决请求量过大情况下的服务器资源分配问题。较为常见的负载均衡算法有轮询、加权轮询、IP 哈希等等,可分别应对不同的请求场景

Nginx实现动静分离 

简介: 前面介绍了Nginx的负载均衡,一般来说,都需要将动态资源和静态资源分开,这样可以很大程度的提升静态资源的访问速度,同时在开过程中也可以让前后端开发并行可以有效的提高开发时间,也可以有些的减少联调时间 。接下来介绍什么是动静分离以及如何使用Nginx实现动静分离。

前面介绍了Nginx的负载均衡,一般来说,都需要将动态资源和静态资源分开,这样可以很大程度的提升静态资源的访问速度,同时在开过程中也可以让前后端开发并行可以有效的提高开发时间,也可以有些的减少联调时间 。接下来介绍什么是动静分离以及如何使用Nginx实现动静分离。

一、什么是动静分离

在Web开发中,通常来说,动态资源其实就是指那些后台资源,而静态资源就是指HTML,JavaScript,CSS,img等文件。

动静分离,说白了,就是将网站静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用服务器的请求。后台应用服务器只负责动态数据请求。

优势:分担负载,减轻web服务器的压力,适用于大负载。静态资源放置cdn,同时还可以通过配置缓存到客户浏览器中,这样极大减轻web服务器的压力。

劣势:网络环境不佳时,ajax回应很慢,导致页面出现空白,出错处理会不好看。不利于网站SEO(搜索引擎优化),增加了开发复杂度。

二、实现方案

动静分离就是根据一定规则静态资源的请求全部请求Nginx服务器,后台数据请求转发到Web应用服务器上。从而达到动静分离的目的。目前比较流行的做法是将静态资源部署在Nginx上,而Web应用服务器只处理动态数据请求。这样减少Web应用服务器的并发压力。具体如下图所示:

三、配置Nginx动静分离

1. 修改nginx.conf配置,其中第一个location负责处理后台请求,第二个负责处理静态资源, nginx 的其他配置,请参考前之前的文章。 具体如下所示:

            #拦截静态资源
      location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css)$ {
        root static;
        expires      30d;  
       }          
       

 

上面的示例,主要是配置image、js、css等资源文件的路径和地址。然后设置缓存失效的时间。

完成的Nginx配置如下所示:

worker_processes  1;

events {
    worker_connections  1024;
}

http {

   server {
       listen       80;
       server_name  localhost;
      
      #拦截后台请求
      location / {
        proxy_pass http://localhost:81;
        proxy_set_header X-Real-IP $remote_addr;
      }

      #拦截静态资源
      location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css)$ {
        root static;
        expires      30d;  
       }

    }

}

2. 在Nginx 下 创建 static 目录,将图片,js, css 等文件 拷贝到该目录下

1633744420(1).png

3. 重启Nginx,使用命令: ./nginx -s reload 重新启动Nginx。

四、验证测试

Nginx 配置完成之后,在浏览器中访问:http://localhost/ 查看页面的请求效果。

通过浏览器的调试工具,通过图中红框内容都可以看出来引用静态资源成功了。动态请求转发到了81端口的web应用服务器,而静态的资源文件,访问的是80端口。说明Nginx的动静分离配置成功。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/683130.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

css文字超出元素省略,单行、多行省略

通用CSS .box {width: 500px;border: 1px solid red;padding: 10px;line-height: 24px;} 1.单行省略 .singe-line {text-overflow: ellipsis;overflow: hidden;word-break: break-all;white-space: nowrap;}<p>单行省略</p><div class"singe-line box&qu…

tomcat8w.exe指向了别的tomcat

这种情况通常发生是因为Tomcat服务在注册表中的配置指向了错误的可执行文件路径。tomcat8w.exe是一个Windows服务配置工具&#xff0c;它用于管理Tomcat服务&#xff0c;包括设置Path to executable&#xff0c;即指向Tomcat服务实际启动的.exe文件的路径。如果Path to executa…

【LeetCode】40. 组合总和 II

组合总和 II 题目描述&#xff1a; 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意&#xff1a;解集不能包含重复的组合。 示例…

HTML静态网页成品作业(HTML+CSS+JS)—— 明星EXO介绍网页(5个页面)(table布局)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;使用Javacsript代码实现首页图片轮播切换&#xff0c;table 切换&…

更新关于其宠物产品质量的电子学习课程

​我们受托更新关于其宠物产品质量的电子学习课程。我们决定采用流行的“Corporate Memphis”风格设计插图&#xff0c;这是一种适用于商业的友好卡通风格&#xff08;该名称来源于80年代因其亮丽的色彩和独特的项目方法而闻名的设计团体“Memphis”&#xff09;。我们选择“Co…

使用迁移助手 (SSMA for Oracle) 将Oracle19c数据库迁移到SQL Server2022

如何使用适用于 Oracle 的 SQL Server 迁移助手Microsoft SQL Server Migration Assistant for Oracle (SSMA for Oracle) 将 Oracle 数据库迁移到 SQL Server Microsoft SQL Server Migration Assistant (SSMA) for Oracle is a tool to automate migration from Oracle data…

python写脚本的时候获取设备,没有端口(COM3)

首先python 可以用一下代码 测试端口是不是存在 import serial.tools.list_portsports list(serial.tools.list_ports.comports()) if not ports:print("没有检测到可用的串口设备。") else:for port in ports:print(f"可用串口: {port.device}")如果提示…

C语言 | Leetcode C语言题解之第133题克隆图

题目&#xff1a; 题解&#xff1a; struct Node** visited; int* state; //数组存放结点状态 0&#xff1a;结点未创建 1&#xff1a;仅创建结点 2&#xff1a;结点已创建并已填入所有内容void bfs(struct Node* s) {if (visited[s->val] && state[s->val] 2…

【亚马逊云科技 CSDN 联合巨献】 「对话AI 构建者:从基础到应用的 LLM 全景培训」 限时免费!

&#x1f680;&#x1f31f;【亚马逊云科技 & CSDN 联合巨献】 &#x1f4da;「对话AI 构建者&#xff1a;从基础到应用的 LLM 全景培训」&#x1f525; 限时免费&#xff01; &#x1f4c6; 抓紧时间&#xff01;6月7日前注册&#xff0c;原价 399&#xff0c;现在仅需 0…

【DevOps】网站安全案例分析:真实事件中的经验与教训

目录 一、常见的网站安全事故案例 1. Equifax 数据泄露事件&#xff08;2017年&#xff09; 2. WannaCry 勒索软件攻击事件&#xff08;2017年&#xff09; 3. GitHub DDoS 攻击事件&#xff08;2018年&#xff09; 二、网站安全事件的一般分析方法 1、事件背景调查 2、…

[WWW2024]轻量数据依赖的异常检测重训练方法LARA

开篇 近日&#xff0c;由阿里云计算平台大数据基础工程技术团队主导&#xff0c;与浙江大学合作的论文《LARA: ALight and Anti-overfitting Retraining Approach for Unsupervised Time Series Anomaly Detection 》被WWW2024收录&#xff0c;该方法解决了云服务正常模式随时…

“网络战时代的国家安全:策略、技术和国际合作“

网络战时代&#xff0c;国家安全面临着前所未有的挑战&#xff0c;这要求国家在策略、技术和国际合作方面采取更为综合和先进的应对措施。以下几点概述了这一领域的关键要素&#xff1a; 策略层面&#xff1a; 1. 建立全面的网络战战略&#xff1a;国家需要一个清晰、前瞻性…

C# 判断字符串不等于空的示例

在C#中&#xff0c;要判断一个字符串是否不等于空&#xff08;即它既不是null也不是空字符串""&#xff09;&#xff0c;方法有如下几种&#xff0c;如下。 方法1 使用逻辑运算符和string.IsNullOrEmpty方法 string myString "123"; // 假设要检查的字…

WPF Treeview控件开虚拟化后定位节点

不开虚拟化&#xff0c;可以用下面的方法直接定位 <Window x:Class"WpfApplication2.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"Title"Main…

电脑在线怎么改图片格式?3步改图片格式的操作步骤

在日常生活和工作中经常会因为不同的用途&#xff0c;需要使用不同格式的图片&#xff0c;那么如果遇到图片格式问题时&#xff0c;有什么方法能够快速在线转图片格式呢&#xff1f; 想要快速将图片格式转换成自己需要使用的格式&#xff0c;比较简单的一种方法可以使用网上的…

使用 Django 和 MQTT 构建实时数据传输应用

文章目录 什么是 MQTT&#xff1f;Django 中的 MQTT结论 在现代的 Web 应用程序开发中&#xff0c;实时数据传输变得越来越重要。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息传输协议&#xff0c;而 Django 是一个流行的 Pyt…

66、API攻防——接口安全阿里云KEYPostmanDVWS

文章目录 一、工具使用——Postman自动化测试二、安全问题——Dvws泄露&鉴权&XXE三、安全问题——阿里KEY信息泄露利用 dvws-node 一、工具使用——Postman自动化测试 二、安全问题——Dvws泄露&鉴权&XXE 路径中出现/api/&#xff0c;一般都是接口。 请求包是…

Jail管理器AppJail的使用@FreeBSD

Jail的简介 Jail是FreeBSD操作系统中一个功能强大的安全机制&#xff0c;自FreeBSD 4.X版本起便投入使用&#xff0c;并且随着系统的发展&#xff0c;其功能、效率、稳定性和安全性得到了持续的强化。 Jail基于chroot的概念&#xff0c;通过更改一系列程序的根目录&#xff0…

【面试题】创建两个线程交替打印100以内数字(一个打印偶数一个打印奇数)

阅读导航 一、问题概述二、解决思路三、代码实现四、代码优化 一、问题概述 面试官&#xff1a;C多线程了解吗&#xff1f;你给我写一下&#xff0c;起两个线程交替打印0~100的奇偶数。就是有两个线程&#xff0c;一个线程打印奇数另一个打印偶数&#xff0c;它们交替输出&…

rust学习(字节数组转string)

最新在写数据传输相关的操作&#xff0c;发现string一个有趣的现象&#xff0c;代码如下&#xff1a; fn main() {let mut data:[u8;32] [0;32];data[0] a as u8;let my_str1 String::from_utf8_lossy(&data);let my_str my_str1.trim();println!("my_str len is…