AWS 消息服务(九)
松耦合架构
概述
- 使用独立的组件设计架构,降低相互依赖,当一个组件出现故障时,其他不受影响
- 利用ELB和SQS来打破传统服务器各层的关联,成为各层之间的中介,各层的故障和扩展均由中介自助处理
- 系统的耦合程度越低,系统的扩展就越轻松,容错能力越高
托管的无服务架构
- 设计服务,而不是设计服务器
- 通过托管服务和无服务器架构可以提高环境的可靠性和效率
- 在需要时优先考虑无服务器解决方案
- 使用消息队列处理应用程序之间的通信
- 在静态资产存储在外部 , 如S3
- 使用IAM处理用户身份验证和用户状态存储
面向服务的架构(SOA)
- 服务是独立的功能单元
- 应用程序通过通信协议为其他组件提供服务
微服务架构
概念
- SOA中的小型、独立进程
- 每个进程专注于执行一个小型任务
- 不同进程之间通过与语言无关的API进行通信
- 微服务可以独立扩展,可以轻松的扩展或收缩组件而其他组件保持不变。
- 微服务还可以轻松应对故障,因为不会出现级联故障而提高容错能力,所以可以将系统可用性适当降低。
- 微服务是易于交换的,只需要用一个组件替换另一个组件就可以完成升级
将功能拆分成不同组件
- 迭代小型部件
- 缩小测试界面区
- 受益于更低的变更风险
- 使用水平扩展的各个组件
- 意味着成本、规模和更改风险均降低,从而提高效率
微服务边界上下文
- 每个业务域都分为多个上下文,业务域可是任何完整的业务流程,他是被多个数据块结合构建
- 每个数据块就是一个微服务的上下文,他具有特定的功能、对象和语言,每个上下文之间有清晰的边界和接口。
最佳实践
- 在不损害功能的前提下更改组件,接口是一份合同,而功能修改不应该影响客户
- 使用简单API降低服务费用、降低复杂性和阻力、减少共享组件、满足信息隐藏需求
- 尽量使用简单的API,API应使用统一的解决方案,避免与智能、控制性强的复杂中间件集成,避免耦合度提高
- 允许你灵活选择技术,随时准备使用新技术
- 不仅仅监控基础设施,还需要从服务收集相关数据
【案例】DynamoDB 与松耦合结合的解决方案
- DynamoDB 是存储和检索处理输出数据的解决方案,高吞吐量,高可用,高容错,完全托管
- 松耦合系统可以与托管的NoSQL数据库良好的协作
Amazon Simple Queue Service (SQS)
概念
- SQS是完全托管的消息队列服务,可以传输任意规模的消息,使用任意级别的吞吐量,且不会丢失消息,业务其他服务要求。
- 主要用于应用程序之间缓冲数据,以及作为他们处理数据的组件
- 轻松将SQS插入紧耦合系统中实现各子系统之间的解耦。
- SQS是云原生的队列技术,如果只是使用云作为消息代理其余组件都在AWS外,建议使用Amazon MQ托管消息代理服务
- 在单区域的多个可用区高可用
- 单个队列可以被多个分布式应用程序同时使用而不需要他们互相协调来共享队列
- SQS队列虽然通常只会传送一次消息,但依旧有可能被多次处理,所以应用程序设计依旧应该是幂等的。
- 消息大小 256KB
- 队列链模式可以支持异步通信,解决标准SQS无法实现FIFO的问题
- 队列中最大支持120000条消息等待处理,FIFO最多支持20000条
- 一般来说,单台EC2每秒可以处理50个API请求,所以如果横向扩展的EC2数量越多,总体队列吞吐量就越高
- 通过EC2 实现松耦合构造系统
- 仅仅通过增加和减少EC2就实现性能服务的动态满足
- 即使EC2发生故障,消息也会保留在队列中等待EC2恢复后继续处理,从而实现故障抵御。
消息生命周期
- 使用异步处理快速返回响应
- 队列消息默认保留时间4天,最大保留14天
延迟处理
- 延迟队列是事先隐藏延迟,可见性超时是事后隐藏延迟
- 若消息既没有在延迟也没有在可见性超时状态,则称为in fight
- 延迟队列
- 推迟队列中传递新消息
- 在延迟期间,应用程序看不到有新消息发送到该队列
- 延迟时间可以设置为0-900秒,默认为0
- 可见性超时
- 为了避免多个组件处理同一消息
- 当组件收到消息后会将消息锁定(hidden),直至处理完成或超时
- 处理完成后消息会被删除,超时后消息可以重新被处理
- 可见性超时默认30秒,最长可设置为12小时
分布式队列
- 消息顺序
- SQS只能尽量按顺序发送消息但无法保证,建议在程序设计时每条消息进行排序
- 至少一次分发
- SQS会在多台服务器上缓存消息副本,以实现冗余和高可用,可能会多次分发消息,所以应用程序应是幂等设计的, 即即便多次处理同一条消息而不应受到影响
- 消息示例
- 消息队列检索为短轮询,采用加权随机分布进行消息子集采样,在某些情况下(如消息队列小于1000)时可能会有某些特殊请求无法被获取,只能通过再次轮询才能接收到所有消息。
- 队列操作
- 包括CreateQueue ,ListQueues , DeleteQueue , SendMessage , SendMessageBatch , ReceiveMessage , DeleteMessage , DeleteMessageBatch , PurgeQueue , ChangeMes sageVisibility , ChangeMessageVisibilityBatch , SetQueueAttributes , GetQueueAttributes , GetQueueUrl , ListDeadLetterSourceQueues , AddPermission 和 RemovePermission。
- AWS账户所有者授予不同的权限的AWS身份不同的执行权限。
FIFO 队列
- 在某些区域可以提供FIFO队列
- 最多支持300TPS操作,最多支持3000条消息/秒。
- 队列中的消息会严格保证发送和接受顺序,且被不多不少的处理一次
- 在 FIFO 队列中,消息被组合成有序的不同“捆绑包”。对于每一个消息组 ID,所有消息的发送和接收均严格遵循一定的顺序。您必须将消息组 ID 与消息关联。如果不提供消息组 ID,操作就会失败。
- 如果多个主机 (或同一主机上的不同线程) 向 FIFO 队列中发送了具有相同消息组 ID 的消息,则 Amazon SQS 按照它们到达的顺序来传送消息。为确保 Amazon SQS 在发送和接收消息时保持相同顺序,请确保多个发送者发送每一条消息时均具有唯一的消息组 ID。
- 设计时FIFO队列不能将消息提供给多个使用者,但是可以通过不同消息组将消息提供给不同使用者
- FIFO有专用的DLQ
SQS属性
- 消息结构
- 消息标识符
- 队列URL
- 创建队列时需要指定的队列唯一名称
- 队列URL
- 消息ID
- SQS消息在队列中传递和返回时通过Unique ID进行标记
- Unique ID对操作不是必须的,但是对追踪是必须的。
- 消息ID最大长度100个字符
- Receipt handles
- 返回消息中的必要字段用于删除消息。
- 最大长度1024个字符
- 正文
- 基于Name/value 对的无结构的内容
- 消息标识符
- 消息属性
- 提供有关消息的结构化元数据,包括时间戳,地理数据,签名,标识符等
- 每条消息最多10条元数据属性
- 消息属性是可选的,与消息主体分离但与它一起发送
- 消息处理者可以基于消息属性直接处理消息,而不用关心消息正文
- 长轮询
- 默认短轮询是每次查询队列时,即使没有消息队列也会相应,如果周期性调用receiveMessage而又没有新消息时可能会导致进程被长期占用
- 使用长轮询的WaitTimeSeconds 等待1-20秒在轮询 ReceiveMessage,若有消息来到则立即触发,若无则超时触发,一定程度上减少SQS花销
- 长轮询 通过消除空响应的数量 (ReceiveMessage 请求时没有消息可用时) 并消除假的空响应 (消息可用但未包含在响应中) 来帮助降低使用 Amazon SQS 的成本。
- 长轮询具有以下好处:
- 在发送响应之前,允许 Amazon SQS 等到队列中的消息可用为止,从而消除空响应。除非连接超时,否则对 ReceiveMessage 请求的响应将至少包含一条可用的消息,并且最多包含 ReceiveMessage 操作中指定的最大数量的消息。
- 通过查询所有 — 服务器而不是服务器子集来消除假的空响应—Amazon SQS。
- 在消息可用时立即返回消息。
- 死信队列 DLQ
- 由无法处理的消息组成的队列,可以搁置和隔离未处理成功的消息
- 当消息达到最高尝试次数后,将被放入DLQ进行旁路和隔离以执行带外分析
- DLQ实际上与其他SQS队列没有区别,可以进行相同的处理
- 安全访问控制
- SQS的通常有跨账户访问的需求,所以IAM控制不适用
- 通过SQS访问控制,将策略分配给允许与其他账户进行交互的特定队列
- SQS 访问控制使用JSON语言。
- 共享队列
- 可以与其他AWS账户匿名共享队列
- 可以为不同的使用者设置权限和策略管理共享队列
- 队列拥有者负责支付所有访问费用
- 消息无法跨区域共享
SQS的优势
- 极高的可扩展性 - 数百万条消息,透明的处理各种缓冲请求和负载
- 极其可靠和持久 - 所有消息均以冗余方式存储在多个数据中心
- 简单易用 - 先接收消息再发送消息
- 同步读取写入
- 安全API凭证
- SQS 可以提供每月100w个免费的队列请求
SQS常见使用场景
- 工作队列 - 在解耦的分布式应用程序中处理无法同时处理同等工作量的组件
- 缓冲批量操作 - 提供可扩展性和可靠性,消除临时峰值而不丢失消息或增加延迟
- 请求卸载 - 通过让请求进入队列,将速度较慢的操作从交互式请求路径中移除
- 扇出 - SQS和SNS结合使用,将某条消息的副本并行发送到多个队列以便于同时处理
- AutoScaling - 利用SQS来确定应用程序的负载执行扩展或收缩的工作
SQS 安全性
- 通过AWS账户或IAM创建和管理队列
- 利用SSE服务器端加密
- 默认情况下每个队列仅限于创建它的账户访问,但是可以使用策略来允许其他账户访问
- SQS需要使用SSL进行加密访问
AWS Simple Workflow (SWF)
概念
- 由应用程序组件组成的逻辑工作单元
- 协调任务执行锁设计的逻辑流程、依赖、调度和并发性
- 在流程执行中可能会任务失败、超时或者需要重启,建议监控每个任务的执行状态并且安排人员执行各种修复和后续任务。
- 适用于异步、分布式处理的流程工具
- SWF任务最长可以保存1年,最多有25000个事件
工作流程
- 将分布式异步应用程序实现工作流程,以协调逻辑确定活动的执行顺序。
- 可以协调和管理可以跨多个设备异步执行,支持顺序和并行处理。
- 工作流注册
- 注册是为各种不同类型的工作流和活动执行的一次性步骤。
- 注册时,您需要为每种活动和工作流类型提供唯一类型的 ID。还要提供运行工作流时使用的默认信息,例如超时值和任务分配参数。
- 工作域 Domain
- 域提供了对SWF资源进行范围划分
- 所有的工作流组件必须指定一个域
- 域只能在 AWS 账户级别创建,不能嵌套。
- 域可以使用用户定义的任何名称。
- 每个应用程序资源(例如,工作流类型、活动类型或执行任务)只属于一个域。注册时,您需要指定在哪个域下注册工作流或活动类型。开始执行任务时,将自动在与其工作流类型相同的域中进创建任务。资源标识符的唯一性(如类型 ID、执行 ID)范围限于域内,即您可以在不同的域中重复使用标识符。
- 一个域可以有多个工作流,不同域的工作流不能交互
- 默认最多有100个域,每个域最多有10000个工作流,可以申请提高限制
- 工作流历史
- 记录自工作流开始以来发生的每个事件的记录
- 每一个工作流都只会被执行一次
角色
- SWF有许多不同类型的可编程角色,包括发起者,决策者和执行者。
- 不同角色之间采用API进行通信,支持各种编程语言。
- Starter(发起者)- 可以启动工作流的应用程序
- Decider(决策者) - 协调工作流任务的逻辑,包括并行、同步或异步等,决策者为执行者提供活动输入。
- Activity Worker (执行者) - 执行某项任务的进程。 Worker 可以不断向SWF轮询是否有需要执行的任务。
任务
- 活动任务
- 告诉执行者执行某个功能,包含所有该执行必须的信息
- Lambda 任务
- 与活动任务类似,但是通过Lambda直接执行
- 决策任务
- 告诉决策者工作流执行状态已经改变,包含工作流历史记录。
- 每个决策任务都包含整个工作流的历史分页视图,通过分析历史操作来决定下一个任务。
- 每一个活动任务都只能被执行一次
任务列表
- 一种组织工作流相关任务的方法,类似于动态队列
- 当SWF计划任务时,指定一个队列将任务放入其中
- 这是个动态的列表,无需提前注册任务列表,可以根据需要灵活地将任务发送给执行者即可调度创建任务列表
- SWF轮询可以确定从哪个队列中获取任务
长轮询
- 决策者和执行者定期启动与SWF的通信,通知其可接受新的任务并且从任务列表接收新的任务
- 适用于大批量任务处理
Objective Identifier对象标识符
- SWF对象由工作流类型,活动类型,决策和活动任务以及工作流执行标识组成。
- 工作流类型包括 域、名称和版本标识
- 活动类型包括 域、名称和版本标识
- 决策和活动任务 包括 唯一的任务令牌,任务令牌由SWF生成并返回给任务
- 这个令牌在任务执行完成后会将其成败信息一起传递给下一个流程
AWS Flow Framework
- 一种编程框架,让您可以快速、轻松开发基于 Amazon SWF 的应用程序。
- 它会提取任务级协调的细节,并与简单的编程结构异步交互。Amazon SWF 中的工作流协调包含启动需要不同时间完成的远程操作(例如,活动任务)及正确实施各任务之间的依赖性。
工作流关闭
- 当工作执行后,其完成、取消、失败或超时都会关闭工作流
- 决策者、人工或SWF都可以关闭工作流
Amazon Simple Notification Service (SNS)
概念
- 适用于移动端和企业消息传递的web服务
- SNS可以设置、操作并发送通知至订阅服务客户或其他应用程序
- SNS策略可以限制发布和定于主题的用户
- HTTPS加密传输可以作为传输可选项
- 默认情况下,SNS仅能被创建它的用户访问,但可以通过设置策略允许其他用户访问
- 基于区域的跨可用区高可用
角色
- 发布者
- 通过发送消息给Topic来异步通知订阅者
- Topic可以看做一组逻辑的沟通渠道的接入点,包含了所有的订阅者的列表以及通知的方式
- 支持多个发布者向一个主题发布消息
- Topic
- 发布者将Topic作为目标,Topic再将消息传递给每一个订阅者
- 每条64KB,最大256KB
- 创建主题后,Amazon SNS 将为该主题分配唯一的 ARN(Amazon 资源名称),其中包括服务名称 (SNS)、区域、用户的 AWS ID 和主题名称
- 每个Topic都有唯一的名称用于发布者和订阅者注册的端点
- Topic命名是全局唯一的,但是可以再删除30-60秒后重新使用
- 发送到终端节点附带的令牌有效期为3天,即3天内需要确认消息,否则消息失效
- 每个账户最多100000个主题,每个主题最多1000万个订阅,可申请提高上限
- 订阅者
- Topic接收了消息后会自动分发给订阅者们
- SNS需要定义策略来指定哪些发布者或者订阅者可以与Topic进行通信
- 订阅程序类型包括 电子邮件(文本或JSON),HTTP/HTTPS,短信SMS、SQS标准队列,API移动推送,Lambda函数
- 订阅者可以通过筛选策略只接受一部分感兴趣的消息
SNS特征
- 单条已发布消息
- 不保证顺序
- 无法撤销
- HTTP/HTTPS 重试
- 消息是非持久的,被动的推送,通过发布/订阅方式传递
Worldwide SMS
- 您可以使用 Amazon SNS 将 SMS(文本)消息发送至 200 多个国家/地区,并且无需像从前那样需要收件人明确订阅
- 不支持SMS双向交互
SNS场景
- Fanout
- SNS发送消息到Topic,Topic再将消息推送到多个SQS队列、HTTP端点等进行处理
- 典型应用是将生产环境数据与开发环境集成,通过SNS将生产环境的真实数据推送到生产环境来以便于改进和测试
- 系统告警
- 有应用程序或系统的预定义阈值触发SNS消息,并通过SMS或电子邮件通知到管理员
- 推送电子邮件和文本消息
- 通知移动端用户