35、基础设施解耦:弹性负载均衡与简单队列服务

基础设施解耦:弹性负载均衡与简单队列服务

1. 解耦概念引入

假设你想从我们这里获取关于使用 AWS 的建议,因此我们计划在一家咖啡馆见面。为了使这次会面成功,我们必须满足以下条件:
- 同一时间有空
- 在同一地点
- 在咖啡馆找到彼此

但这次会面存在一个问题,它与地点紧密耦合。我们住在德国,而你可能不在。我们可以通过将会面与地点解耦来解决这个问题,于是我们更改计划,安排了一次 Google Hangout 会话。现在我们只需要:
- 同一时间有空
- 在 Google Hangouts 中找到彼此

Google Hangouts(以及其他视频/语音聊天服务)实现了同步解耦,它消除了在同一地点的需求,但仍要求我们在同一时间见面。我们甚至可以通过使用电子邮件来实现与时间的解耦,此时我们只需要:
- 通过电子邮件找到彼此

电子邮件实现了异步解耦,你可以在收件人睡觉时发送电子邮件,他们可以在醒来后回复。

到目前为止,我们了解了三种解耦会面的方式:
| 解耦方式 | 特点 |
| ---- | ---- |
| 无耦合 | 必须在同一地点(咖啡馆)、同一时间(下午 3 点),并找到彼此(我有黑色头发,穿着白色衬衫) |
| 同步解耦 | 可以在不同地点,但仍需找到共同时间(下午 3 点),并找到彼此(交换 Skype ID) |
| 异步解耦 | 可以在不同地点,且无需找到共同时间,只需找到彼此(交换电子邮件地址) |

在软件系统中,也有很多紧密耦合的组件。例如,公共 IP 地址就像我们会面的地点,要向 Web 服务器发出请求,你必须知道其公共 IP 地址,并且虚拟机必须连接到该地址。如果你想更改公共 IP 地址,双方都需要进行相应的更改。

2. 同步解耦:负载均衡器
2.1 负载均衡器的必要性

将运行 Web 服务器的单个 EC2 实例暴露给外界会引入依赖关系,用户现在依赖于 EC2 实例的公共 IP 地址。一旦你将公共 IP 地址分发给用户,就无法再更改它,会面临以下问题:
- 由于许多客户端依赖该公共 IP 地址,更改它变得不再可能。
- 如果你添加额外的 EC2 实例(和 IP 地址)来处理不断增加的负载,当前所有客户端都会忽略这些新实例,它们仍然会将所有请求发送到第一台服务器的公共 IP 地址。

虽然可以使用指向服务器的 DNS 名称来解决这些问题,但 DNS 并不完全受你控制。DNS 解析器会缓存响应,DNS 服务器会缓存条目,有时它们不会遵守你的生存时间(TTL)设置。因此,更好的解决方案是使用负载均衡器。

2.2 负载均衡器的工作原理

负载均衡器可以帮助解耦需要立即响应的系统。它位于 EC2 实例和客户端之间,将请求同步解耦。请求者(如 Web 浏览器)向负载均衡器发送 HTTP 请求,负载均衡器选择一个 EC2 实例,并将原始 HTTP 请求复制发送给该实例。EC2 实例处理请求并发送响应,负载均衡器接收响应并将其发送回原始请求者。

AWS 通过弹性负载均衡(ELB)服务提供不同类型的负载均衡器,所有类型的负载均衡器都具有容错和可扩展性,它们的主要区别在于支持的协议:
| 负载均衡器类型 | 支持协议 |
| ---- | ---- |
| 应用程序负载均衡器(ALB) | HTTP、HTTPS |
| 网络负载均衡器(NLB) | TCP |
| 经典负载均衡器(CLB) | HTTP、HTTPS、TCP、TCP + TLS |

经典负载均衡器是最古老的负载均衡器。如果开始一个新项目,建议使用 ALB 或 NLB,因为它们在大多数情况下更具成本效益且功能更丰富。需要注意的是,ELB 服务没有独立的管理控制台,它集成在 EC2 管理控制台中。负载均衡器不仅可以用于 Web 服务器,只要协议基于 TCP,就可以用于任何处理请求/响应式通信的系统。

2.3 使用虚拟机设置负载均衡器

我们可以将 ALB 放在自动扩展组前面,以解耦到 Web 服务器的流量,消除用户与 EC2 实例公共 IP 地址之间的依赖关系。自动扩展组将确保始终有两个 Web 服务器运行,以防止因硬件故障导致的停机。在自动扩展组中启动的服务器将自动向 ALB 注册。

ALB 由三个必需部分和一个可选部分组成:
- 负载均衡器:定义一些核心配置,如负载均衡器运行的子网、是否获取公共 IP 地址、使用 IPv4 还是同时使用 IPv4 和 IPv6 以及其他属性。
- 监听器:定义可用于向负载均衡器发出请求的端口和协议。监听器还可以为你终止 TLS,并链接到一个目标组,该目标组在没有其他监听器规则匹配请求时用作默认目标。
- 目标组:定义后端组,负责通过定期发送运行状况检查来检查后端。后端通常是 EC2 实例,但也可以是在 EC2 容器服务上运行的 Docker 容器或与你的 VPC 配对的数据中心中的机器。
- 监听器规则(可选):可以根据 HTTP 路径或主机选择不同的目标组,否则请求将转发到监听器中定义的默认目标组。

以下是一个用于创建 ALB 并将其与自动扩展组连接的 CloudFormation 模板片段:

# [...]
LoadBalancerSecurityGroup:
  Type: 'AWS::EC2::SecurityGroup'
  Properties:
    GroupDescription: 'alb-sg'
    VpcId: !Ref VPC
    SecurityGroupIngress:
      - CidrIp: '0.0.0.0/0'
        FromPort: 80
        IpProtocol: tcp
        ToPort: 80

LoadBalancer:
  Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
  Properties:
    SecurityGroups:
      - !Ref LoadBalancerSecurityGroup
    Scheme: 'internet-facing'
    Subnets:
      - !Ref SubnetA
      - !Ref SubnetB
    Type: application
    DependsOn: 'VPCGatewayAttachment'

Listener:
  Type: 'AWS::ElasticLoadBalancingV2::Listener'
  Properties:
    LoadBalancerArn: !Ref LoadBalancer
    Port: 80
    Protocol: HTTP
    DefaultActions:
      - TargetGroupArn: !Ref TargetGroup
        Type: forward

TargetGroup:
  Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
  Properties:
    HealthCheckIntervalSeconds: 10
    HealthCheckProtocol: HTTP
    HealthCheckPath: '/index.html'
    HealthCheckTimeoutSeconds: 5
    HealthyThresholdCount: 3
    UnhealthyThresholdCount: 2
    Matcher:
      HttpCode: '200-299'
    Port: 80
    Protocol: HTTP
    VpcId: !Ref VPC

LaunchConfiguration:
  Type: 'AWS::AutoScaling::LaunchConfiguration'
  Properties:
    # [...]

AutoScalingGroup:
  Type: 'AWS::AutoScaling::AutoScalingGroup'
  Properties:
    LaunchConfigurationName: !Ref LaunchConfiguration
    TargetGroupARNs:
      - !Ref TargetGroup
    MinSize: 2
    MaxSize: 2
    DesiredCapacity: 2
    VPCZoneIdentifier:
      - !Ref SubnetA
      - !Ref SubnetB
    DependsOn: 'VPCGatewayAttachment'

你可以通过点击 http://mng.bz/lbG4 上的快速创建链接,基于该模板创建一个堆栈,然后使用浏览器访问堆栈的输出。每次重新加载页面时,你应该会看到一个后端 Web 服务器的私有 IP 地址。要在图形用户界面中查看负载均衡器的详细信息,导航到 EC2 管理控制台,在左侧的子导航菜单中有一个“负载均衡”部分,你可以在其中找到负载均衡器的链接,选择负载均衡器后,页面底部将显示详细信息,其中包含一个“监控”选项卡,你可以在其中找到有关延迟、请求数量等的图表。需要注意的是,这些图表会有一分钟的延迟,所以你可能需要等待一段时间才能看到你对负载均衡器发出的请求。

3. 异步解耦:消息队列
3.1 消息队列的优势

使用 ELB 进行同步解耦很容易,无需更改代码。但对于异步解耦,你必须调整代码以使用消息队列。消息队列有一个头部和一个尾部,你可以在尾部添加新消息,同时从头部读取消息,这允许你解耦消息的生产和消费。将生产者/请求者与消费者/接收者解耦带来了以下好处:
- 队列充当缓冲区:生产者和消费者不必以相同的速度运行。例如,你可以在一分钟内添加一批 1000 条消息,而你的消费者始终每秒处理 10 条消息。迟早,消费者会赶上,队列将再次为空。
- 队列隐藏后端:与负载均衡器类似,消息生产者对消费者一无所知。你甚至可以停止所有消费者,仍然可以生产消息,这在对消费者进行维护时非常方便。

生产者和消费者彼此不了解,他们都只知道消息队列。

3.2 简单队列服务(SQS)

简单队列服务(SQS)是一项完全托管的 AWS 服务,SQS 提供的消息队列保证消息至少传递一次:
- 在极少数情况下,单个消息可能会被消费两次。这与其他消息队列相比可能看起来很奇怪,但后面会介绍如何处理这个问题。
- SQS 不保证消息的顺序,因此你可能会以与生产顺序不同的顺序读取消息。

SQS 的这些限制也有好处:
- 你可以向 SQS 中放入任意数量的消息。
- 消息队列会根据你生产和消费的消息数量进行扩展。
- SQS 默认具有高可用性。
- 按消息付费。

SQS 的定价模式也很简单,每次向 SQS 发出请求需支付 0.00000040 美元,即每百万次请求支付 0.4 美元。生产一条消息是一次请求,消费也是一次请求(如果你的有效负载大于 64 KB,每 64 KB 块计为一次请求)。

3.3 将同步过程转换为异步过程

一个典型的同步过程如下:用户向 Web 服务器发出请求,Web 服务器上进行某些操作,然后将结果返回给用户。以创建 URL 预览图像的过程为例:
1. 用户提交一个 URL。
2. Web 服务器下载该 URL 处的内容,截取屏幕截图,并将其渲染为 PNG 图像。
3. Web 服务器将 PNG 图像返回给用户。

通过一个小技巧,可以将这个过程变为异步过程,并在高峰流量时受益于消息队列的弹性:
1. 用户提交一个 URL。
2. Web 服务器将包含随机 ID 和 URL 的消息放入队列。
3. Web 服务器向用户返回一个链接,用户将来可以在该链接处找到 PNG 图像,链接中包含随机 ID(例如 http://$Bucket.s3-website-us-east-1.amazonaws.com/$RandomId.png )。
4. 在后台,一个工作进程从队列中消费消息,下载内容,将内容转换为 PNG 图像,并将图像上传到 S3。
5. 某个时候,用户尝试在已知位置下载 PNG 图像。如果文件未找到,用户应在几秒钟后重新加载页面。

如果你想将一个过程变为异步过程,必须管理过程发起者跟踪过程状态的方式。一种方法是向发起者返回一个 ID,该 ID 可用于查找过程,在过程中,这个 ID 会从一个步骤传递到另一个步骤。

3.4 URL2PNG 应用程序架构

我们将创建一个名为 URL2PNG 的简单但解耦的软件,它可以根据给定的 Web URL 渲染 PNG 图像。我们将使用 Node.js 进行编程,并使用 SQS 作为消息队列实现。

在消息生产者端,一个小的 Node.js 脚本生成一个唯一 ID,将包含 URL 和 ID 的消息发送到队列,并将 ID 返回给用户。用户现在开始使用返回的 ID 作为文件名,检查 S3 存储桶上是否有文件可用。

同时,在消息消费者端,一个小的 Node.js 脚本从队列中读取消息,根据有效负载中的 URL 生成屏幕截图,并使用有效负载中的唯一 ID 作为文件名将生成的图像上传到 S3 存储桶。

4. 清理工作

完成操作后,删除你创建的 CloudFormation 堆栈。

基础设施解耦:弹性负载均衡与简单队列服务(续)

5. 深入理解负载均衡器的同步解耦

负载均衡器在同步解耦中扮演着关键角色,它为系统带来了诸多优势。

5.1 负载均衡器的工作流程可视化

下面通过 mermaid 流程图展示负载均衡器的工作流程:

graph LR
    A[客户端] --> B[负载均衡器]
    B --> C{选择后端实例}
    C -->|实例 1| D[EC2 实例 1]
    C -->|实例 2| E[EC2 实例 2]
    D --> F[处理请求]
    E --> F
    F --> B
    B --> A

从这个流程图可以清晰地看到,客户端的请求首先到达负载均衡器,负载均衡器根据一定的算法选择一个后端 EC2 实例,将请求转发给该实例进行处理,处理完成后结果再通过负载均衡器返回给客户端。

5.2 不同类型负载均衡器的应用场景
负载均衡器类型 应用场景
应用程序负载均衡器(ALB) 适用于基于 HTTP 和 HTTPS 协议的 Web 应用程序,能够根据 URL 路径、主机名等进行更精细的路由,适合微服务架构。
网络负载均衡器(NLB) 对于 TCP 协议的应用,如数据库连接、游戏服务器等,需要高性能和低延迟的场景,NLB 是更好的选择。
经典负载均衡器(CLB) 当你的应用需要兼容旧的架构,或者对协议支持要求较为宽泛(HTTP、HTTPS、TCP、TCP + TLS)时,可以考虑使用 CLB。
6. 消息队列异步解耦的实际应用

消息队列在异步解耦方面有广泛的应用,下面进一步探讨其在实际场景中的应用和操作要点。

6.1 消息队列的使用流程

消息队列的使用可以分为以下几个步骤:
1. 创建消息队列 :在 AWS 控制台中创建 SQS 队列,选择队列类型(标准队列或 FIFO 队列),并配置相关参数,如消息保留时间、可见性超时等。
2. 生产者发送消息 :编写代码,使用 AWS SDK 向 SQS 队列发送消息。消息内容可以是 JSON 格式,包含业务所需的信息,如订单信息、任务参数等。
3. 消费者接收消息 :消费者程序从 SQS 队列中接收消息,处理消息中的业务逻辑。处理完成后,需要向 SQS 确认消息已处理,以便将消息从队列中删除。
4. 错误处理和重试机制 :如果消费者在处理消息时出现错误,需要有相应的错误处理和重试机制。可以将消息重新放回队列,设置重试次数,避免无限重试导致队列积压。

6.2 处理 SQS 消息的顺序和重复问题

由于 SQS 不保证消息的顺序和可能出现消息重复消费的问题,在实际应用中需要进行处理。
- 消息顺序处理 :如果业务要求消息按顺序处理,可以使用 FIFO 队列。FIFO 队列保证消息的先进先出顺序,但吞吐量相对较低。
- 消息重复消费处理 :在消费者端,可以通过消息的唯一 ID 来判断消息是否已经处理过,避免重复处理。例如,使用数据库或缓存记录已处理消息的 ID。

7. 综合应用:构建解耦的系统架构

将负载均衡器和消息队列结合使用,可以构建一个高度解耦的系统架构。

7.1 系统架构设计

以下是一个综合应用的系统架构示例:

graph LR
    A[用户] --> B[负载均衡器]
    B --> C{选择 Web 服务器}
    C -->|Web 服务器 1| D[EC2 实例 - Web 服务器 1]
    C -->|Web 服务器 2| E[EC2 实例 - Web 服务器 2]
    D --> F[消息生产者]
    E --> F
    F --> G[SQS 队列]
    G --> H[消息消费者]
    H --> I[处理任务]
    I --> J[S3 存储桶]
    J --> A

在这个架构中,用户的请求首先通过负载均衡器分发到 Web 服务器,Web 服务器作为消息生产者将任务信息发送到 SQS 队列,消息消费者从队列中获取任务并进行处理,处理结果存储在 S3 存储桶中,最后用户可以从 S3 存储桶获取结果。

7.2 系统的优势和挑战

这种解耦的系统架构带来了以下优势:
- 高可用性 :负载均衡器可以自动将请求分发到多个可用的 Web 服务器,消息队列和 SQS 服务本身具有高可用性,确保系统在部分组件出现故障时仍能正常运行。
- 可扩展性 :可以根据业务需求轻松扩展 Web 服务器和消息消费者的数量,以应对不同的流量和任务负载。
- 灵活性 :各个组件之间相互独立,便于进行升级、维护和替换。

然而,这种架构也面临一些挑战:
- 复杂性增加 :系统涉及多个组件和服务,需要进行更复杂的配置和管理。
- 调试和监控难度加大 :由于组件之间的解耦,故障排查和性能监控需要更细致的工作。

8. 总结与实践建议

通过对负载均衡器和消息队列的学习,我们了解了如何通过同步和异步解耦来构建更健壮、灵活的系统。在实际应用中,建议按照以下步骤进行实践:
1. 规划架构 :根据业务需求和流量特点,选择合适的负载均衡器类型和消息队列服务。
2. 逐步实施 :先在测试环境中搭建系统,进行功能测试和性能测试,确保系统的稳定性和可靠性。
3. 监控和优化 :使用 AWS 提供的监控工具,如 CloudWatch,对系统的性能指标进行监控,及时发现和解决问题。
4. 持续学习 :AWS 服务不断更新和改进,持续学习新的功能和最佳实践,以优化系统架构。

通过以上的实践和优化,你可以构建一个高效、稳定的解耦系统,为业务的发展提供有力支持。

【无人机】基于改进粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)内容概要:本文围绕基于改进粒子群算法的无人机路径规划展开研究,重点探讨了在复杂环境中利用改进粒子群算法(PSO)实现无人机三维路径规划的方法,并将其遗传算法(GA)、标准粒子群算法等传统优化算法进行对比分析。研究内容涵盖路径规划的多目标优化、避障策略、航路点约束以及算法收敛性和寻优能力的评估,所有实验均通过Matlab代码实现,提供了完整的仿真验证流程。文章还提到了多种智能优化算法在无人机路径规划中的应用比较,突出了改进PSO在收敛速度和全局寻优方面的优势。; 适合人群:具备一定Matlab编程基础和优化算法知识的研究生、科研人员及从事无人机路径规划、智能优化算法研究的相关技术人员。; 使用场景及目标:①用于无人机在复杂地形或动态环境下的三维路径规划仿真研究;②比较不同智能优化算法(如PSO、GA、蚁群算法、RRT等)在路径规划中的性能差异;③为多目标优化问题提供算法选型和改进思路。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注算法的参数设置、适应度函数设计及路径约束处理方式,同时可参考文中提到的多种算法对比思路,拓展到其他智能优化算法的研究改进中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值