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; # 解决刷新404proxy_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; # 解决刷新404proxy_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的动静分离配置成功。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频怎么压缩变小?推荐三个压缩方法

视频怎么压缩变小?在数字时代,视频已成为我们日常生活和工作中不可或缺的一部分。然而,随着视频质量的提升,视频文件的大小也随之增加,这给存储和分享带来了不小的挑战。幸运的是,市面上有许多视频压缩软件…

2024首发!会声会影2024旗舰版,专业编辑新体验!

会声会影2024最新旗舰版是一款专业的视频编辑软件,它集成了多种高级功能,为用户带来极致的视频编辑体验。在这篇文章中,我们将详细介绍该软件的功能和特色,帮助用户更好地了解和使用它。 会声会影全版本绿色安装包获取链接&#…

【简单理解化】 内存函数及它的模拟实现

本文章谈论memcpy,memcmp,memmove,memset函数 目录 1.memcpy的使用和模拟实现 2.memmove的使用和模拟实现 3.memset的使用 4.memcmp函数的使用 1.memcpy的使用和模拟实现 该函数用于从源内存块复制指定数量的字节到目标内存块 1 void * memcpy ( void * destination, const voi…

【机器学习基础】Python编程01:五个实用练习题的解析与总结

Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面: 简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。 丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些…

C++ | Leetcode C++题解之第134题加油站

题目&#xff1a; 题解&#xff1a; class Solution { public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int n gas.size();int i 0;while (i < n) {int sumOfGas 0, sumOfCost 0;int cnt 0;while (cnt < n) {int j (i …

2.1.3 采用接口方式使用MyBatis

实战概述&#xff1a;使用MyBatis的接口方式进行数据库操作 环境准备 确保项目中已经集成了MyBatis框架。 创建用户映射器接口 在net.huawei.mybatis.mapper包中创建UserMapper接口。定义方法findById(int id)用于按编号查询用户。定义方法findAll()用于查询全部用户。定义方法…

嵌入式Linux系统中GPIO应用控制详解

大家好,今天主要和大家分享一下,如何在linux系统上,实现GPIO口的控制,其中GPIO在内核端基本操作如下。 第一:Linux系统中GPIO介绍 GPIO(General-Purpose IO Ports),即通用I0接口.GPIO的使用较为简单,主要分为输入和输出两种功能.GPIO主要用于实现一些简单设备的控制.…

3. 使用tcpdump抓取rdma数据包

系列文章 第1章 多机多卡运行nccl-tests 和channel获取第2章 多机多卡nccl-tests 对比分析第3章 使用tcpdump抓取rdma数据包 目录 系列文章一、准备工作1. 源码编译tcpdump2. 安装wireshark 二、Tcpdump抓包三、Wireshark分析 一、准备工作 1. 源码编译tcpdump 使用 tcpdump…

判断经纬度是否在某个城市内

一、从高德获取指定城市边界经纬度信息 通过apifox操作&#xff1a; 二、引入第三方jar包&#xff1a; maven地址&#xff1a;https://mvnrepository.com/ maven依赖&#xff1a; <dependency><groupId>org.locationtech.jts</groupId><artifactId>…

Xcode中给UIView在xib中添加可视化的属性

给UIView在xib中添加可视化的属性 效果如下图&#xff1a; 可以直接设置view 的 borderColor 、borderWidth、cornerRadius&#xff0c;也可以单独指定view的某个角是圆角。减少了代码中的属性。 完整代码&#xff1a; UIViewBorder.h #import <UIKit/UIKit.h>inter…

NLP(1)-TF-IDF算法介绍

一、TF-IDF算法介绍 TF-IDF&#xff08;term frequency–inverse document frequency&#xff0c;词频-逆向文件频率&#xff09;是一种用于信息检索&#xff08;information retrieval&#xff09;与文本挖掘&#xff08;text mining&#xff09;的常用加权技术。 TF-IDF是一…

(十六)统计学基础练习题十(选择题T451-478)

本文整理了统计学基础知识相关的练习题&#xff0c;共50道&#xff0c;适用于想巩固统计学基础或备考的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-统计学三&#xff09;。序号之前的题请看往期文章。 451&#xff09; 452&#xff09; 453&#xff09; 4…

Ubuntu安装cuda

文章目录 前言一、安装NVIDIA驱动1.1 过程中的问题1.2 解决方法1.3 重启后出现 perform MOK management 二、安装Cuda2.1 检查是否安装显卡驱动2.2 安装Cuda2.3 验证CUDA是否安装成功 三、配置环境变量---未完2.4 图片居中加调整大学 总结 #pic_center 前言 只是为方便学习&…

如何将本地项目上传到GitHub

在软件开发过程中&#xff0c;将本地项目上传到GitHub是一个非常重要的步骤。它不仅可以帮助你备份代码&#xff0c;还可以让你与团队成员共享和协作开发。本文将详细介绍如何将本地项目上传到GitHub。 前提条件 已安装Git。如果还没有安装&#xff0c;请参考Git官网进行下载…

机器学习_模型评估与选择

在机器学习中&#xff0c;模型评估与选择是至关重要的步骤。这一过程包括评估模型的性能、选择最适合的模型&#xff0c;以及对模型进行优化&#xff0c;以确保在实际应用中达到最佳效果。以下是详细的讲解&#xff1a; 一、模型评估 模型评估的目的是衡量模型在数据上的表现…

递归书写树形图示例

大叫好&#xff0c;今天书写了一个扁型转换为树型的例子&#xff0c;使用的是递归&#xff0c;请大家食用&#xff0c;无毒 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" conte…

【Python数据类型的奥秘】:构建程序基石,驾驭信息之海

文章目录 &#x1f680;Python数据类型&#x1f308;1. 基本概念⭐2. 转化&#x1f44a;3. 数值运算&#x1f4a5;4. 数值运算扩展(math库常用函数) &#x1f680;Python数据类型 &#x1f308;1. 基本概念 整数&#xff08;int&#xff09;&#xff1a;整数是没有小数部分的数…

MMKV源码详解

文章目录 前言一、MMKV简介1.mmap2.protobuf 二、MMKV 源码详解1.MMKV初始化2.MMKV对象获取3.文件摘要的映射4.loadFromFile 从文件加载数据5.encode 数据写入 总结 前言 谈到轻量级的数据持久化&#xff0c;在 Android 开发过程中&#xff0c;大家首先想到的应该就是 SharedP…

题号:BC19 题目:反向输出一个四位数

题号&#xff1a;BC19 题目&#xff1a;反向输出一个四位数 废话不多说&#xff0c;上题目&#xff1a; 解题思路&#xff1a; 我们发现可以用%和/两个操作符就可以解决。 代码如下: int main() {int a 0;scanf("%d ",& a);while (a){printf("%d "…

【Vue】普通组件的注册使用-全局注册

文章目录 一、使用步骤二、练习 一、使用步骤 步骤 创建.vue组件&#xff08;三个组成部分&#xff09;main.js中进行全局注册 使用方式 当成HTML标签直接使用 <组件名></组件名> 注意 组件名规范 —> 大驼峰命名法&#xff0c; 如 HmHeader 技巧&#xf…