网络隔离
将 ALB 或 API Gateway 部署在公共子网(public subnet)中,并将后端应用服务部署在私有子网(private subnet)中,是一种常见的网络架构设计。这种设计的主要目的是实现网络隔离,从而提高安全性和可管理性。以下是这种网络隔离设计的主要好处:
网络隔离的好处
-
提高安全性:
- 限制直接访问:将后端应用服务部署在私有子网中,可以防止外部互联网直接访问这些服务。只有通过 ALB 或 API Gateway 的流量才能访问后端服务,从而减少了攻击面。
- 保护敏感数据:私有子网中的资源通常包含敏感数据或关键业务逻辑。通过网络隔离,可以更好地保护这些资源免受外部威胁。
-
简化安全管理:
- 集中控制访问:通过 ALB 或 API Gateway 集中控制对后端服务的访问,可以更容易地实施和管理安全策略,如身份验证、授权和流量限制。
- 使用安全组和网络ACL:可以为公共子网和私有子网配置不同的安全组和网络访问控制列表(ACL),以实现更细粒度的访问控制。
-
提高可用性和弹性:
- 负载均衡:ALB 提供了强大的负载均衡功能,可以将流量分配到多个后端实例,提高应用的可用性和弹性。
- 自动扩展:API Gateway 和 ALB 都支持自动扩展,可以根据流量需求自动调整资源,确保应用在高负载下仍能正常运行。
-
简化网络架构:
- 分离公共和私有流量:将公共流量和私有流量分离,可以简化网络架构和流量管理。公共子网处理来自互联网的流量,而私有子网处理内部流量。
- 更好的网络性能:通过网络隔离,可以减少网络拥塞和冲突,提高网络性能和稳定性。
-
合规性和审计:
- 满足合规要求:许多行业和法规要求对敏感数据和关键系统进行网络隔离。通过将后端服务部署在私有子网中,可以更好地满足这些合规要求。
- 审计和监控:通过集中控制访问,可以更容易地实施审计和监控,跟踪和记录对后端服务的访问和操作。
总结
将 ALB 或 API Gateway 部署在公共子网中,并将后端应用服务部署在私有子网中,可以实现网络隔离,从而提高安全性、简化安全管理、提高可用性和弹性、简化网络架构,并满足合规性和审计要求。通过这种设计,可以更好地保护后端服务和敏感数据,确保应用的安全性和稳定性。
AWS API Gateway 和 AWS ALB
使用 AWS Application Load Balancer (ALB) 和 API Gateway 各有其优缺点和适用场景。以下是两者的主要区别和各自的优缺点:
AWS Application Load Balancer (ALB)
优点
-
负载均衡:
- ALB 提供了强大的负载均衡功能,可以将流量分配到多个后端实例(如 EC2 实例、容器等),提高应用的可用性和扩展性。
-
支持多种协议:
- ALB 支持 HTTP、HTTPS 和 WebSocket 协议,适用于多种应用场景。
-
灵活的路由规则:
- ALB 支持基于路径、主机名、HTTP 头和查询字符串参数的路由规则,可以实现复杂的流量管理。
-
集成 WAF:
- ALB 可以与 AWS Web Application Firewall (WAF) 集成,提供额外的安全保护。
-
支持容器和微服务架构:
- ALB 可以与 Amazon ECS、EKS 和 Kubernetes 集成,适用于容器化和微服务架构。
缺点
-
管理复杂性:
- 需要管理和维护后端实例(如 EC2 实例或容器),增加了运维复杂性。
-
成本:
- 需要支付 ALB 和后端实例的费用,成本可能较高。
AWS API Gateway
优点
-
无服务器架构:
- API Gateway 是一种完全托管的无服务器服务,不需要管理和维护服务器,减少了运维负担。
-
集成 Lambda:
- API Gateway 可以与 AWS Lambda 无缝集成,适用于无服务器架构和事件驱动的应用。
-
内置安全功能:
- API Gateway 提供内置的身份验证和授权功能(如 IAM、Cognito 和 Lambda Authorizer),简化了安全管理。
-
流量管理:
- API Gateway 支持流量限制、缓存和监控功能,可以更好地管理 API 流量和性能。
-
自动扩展:
- API Gateway 可以自动扩展以处理高并发请求,适用于高流量应用。
缺点
-
成本:
- 对于高流量应用,API Gateway 的请求费用可能较高。
-
延迟:
- API Gateway 引入的额外延迟可能不适用于对延迟敏感的应用。
-
功能限制:
- API Gateway 主要用于处理 API 请求,可能不适用于需要复杂负载均衡和路由规则的应用。
使用 AWS ALB + Spring Cloud Gateway on EC2 的原因
-
灵活性和控制:
- 使用 ALB 和 Spring Cloud Gateway on EC2 提供了更大的灵活性和控制,可以根据具体需求自定义路由规则、负载均衡策略和安全配置。
-
现有架构:
- 如果你的应用已经使用了 Spring Cloud Gateway 和 EC2 实例,迁移到 API Gateway 可能需要较大的改动和重构。
-
成本考虑:
- 对于某些应用,使用 ALB 和 EC2 实例可能比 API Gateway 更具成本效益,特别是对于高流量应用。
-
复杂路由需求:
- Spring Cloud Gateway 提供了强大的路由和过滤功能,适用于需要复杂路由和流量管理的应用。
何时使用 AWS API Gateway
-
无服务器架构:
- 如果你希望构建无服务器架构,减少运维负担,API Gateway 是一个很好的选择。
-
事件驱动应用:
- 如果你的应用是事件驱动的,并且可以与 AWS Lambda 集成,API Gateway 提供了无缝的集成和管理。
-
快速开发和部署:
- API Gateway 提供了快速开发和部署 API 的能力,适用于需要快速迭代和发布的应用。
总结
使用 AWS ALB 和 API Gateway 各有其优缺点和适用场景。你可以根据具体需求和应用架构选择合适的解决方案。使用 ALB 和 Spring Cloud Gateway on EC2 提供了更大的灵活性和控制,而使用 API Gateway 则简化了运维和管理,适用于无服务器架构和事件驱动的应用。通过权衡这些因素,你可以选择最适合你的应用的解决方案。
API Gateway 直接连接 ALB
优点
-
负载均衡:
- ALB 提供了强大的负载均衡功能,可以将流量均匀分配到多个 EC2 实例,提高应用的可用性和性能。
-
灵活的路由规则:
- ALB 支持基于路径、主机名、HTTP 头和查询字符串参数的路由规则,可以实现复杂的流量管理。
-
健康检查:
- ALB 提供健康检查功能,可以自动检测和移除不健康的实例,确保只有健康的实例接收流量。
-
自动扩展:
- ALB 可以与 Auto Scaling Group (ASG) 集成,自动扩展和缩减 EC2 实例的数量,以应对流量变化。
-
集成 WAF:
- ALB 可以与 AWS Web Application Firewall (WAF) 集成,提供额外的安全保护。
-
简化管理:
- 使用 ALB 可以简化流量管理和负载均衡配置,减少应用程序的复杂性。
缺点
-
额外成本:
- 使用 ALB 会产生额外的成本,包括 ALB 的使用费用和数据传输费用。
-
额外的网络跳跃:
- 请求需要经过 API Gateway 和 ALB 两个层次,可能会增加一些网络延迟。
API Gateway 直接连接 EC2
优点
-
简化架构:
- 直接连接 EC2 实例可以简化架构,减少中间层,降低复杂性。
-
降低成本:
- 不使用 ALB 可以减少额外的成本,特别是对于小规模应用或预算有限的项目。
-
减少网络延迟:
- 直接连接 EC2 实例可以减少网络跳跃,降低请求的延迟。
缺点
-
缺乏负载均衡:
- 直接连接 EC2 实例缺乏负载均衡功能,无法自动将流量均匀分配到多个实例。
-
缺乏健康检查:
- API Gateway 不提供与 ALB 相同的健康检查功能,无法自动检测和移除不健康的实例。
-
手动管理扩展:
- 需要手动管理 EC2 实例的扩展和缩减,增加了运维复杂性。
-
缺乏灵活的路由规则:
- 直接连接 EC2 实例无法利用 ALB 提供的灵活路由规则,可能限制了流量管理的能力。
适用场景
使用 API Gateway 直接连接 ALB
-
高可用性和高性能:
- 需要高可用性和高性能的应用,利用 ALB 的负载均衡和健康检查功能。
-
复杂流量管理:
- 需要基于路径、主机名、HTTP 头和查询字符串参数的复杂路由规则。
-
自动扩展:
- 需要自动扩展和缩减 EC2 实例的数量,以应对流量变化。
-
安全性:
- 需要集成 AWS WAF 提供额外的安全保护。
使用 API Gateway 直接连接 EC2
-
简化架构:
- 需要简化架构,减少中间层,降低复杂性。
-
降低成本:
- 预算有限的项目,减少额外的成本。
-
低延迟:
- 需要减少网络跳跃,降低请求的延迟。
-
小规模应用:
- 小规模应用或负载较低的应用,不需要复杂的负载均衡和流量管理功能。
总结
选择将 AWS API Gateway 直接连接到 ALB 还是直接连接到 EC2 实例取决于你的具体需求和应用场景:
- API Gateway 直接连接 ALB:适用于需要高可用性、高性能、复杂流量管理、自动扩展和额外安全保护的应用。虽然会增加一些成本和网络延迟,但提供了更强大的功能和灵活性。
- API Gateway 直接连接 EC2:适用于需要简化架构、降低成本、减少网络延迟的小规模应用或负载较低的应用。虽然缺乏负载均衡和健康检查功能,但可以减少复杂性和成本。
架构设计
微服务架构
- 描述:将应用程序拆分为多个独立的服务,每个服务负责特定的功能。
- 优点:提高系统的可扩展性和可维护性,允许独立部署和扩展各个服务。
这里对于 Web 应用服务器采用 CQRS 模式,命令查询责任分离(CQRS)是一种强大的架构模式,它将软件系统中处理命令和查询的责任分开。通过划分这些关注点,CQRS 可提高可扩展性、可维护性和灵活性。
CQRS 是 "命令查询责任隔离"(Command Query Responsibility Segregation)的缩写。这是一种将读取数据(查询)和写入数据(命令)的操作分开的模式。
这里分为三个类型的服务,cmd wkr 和 qry。
- cmd: 接受请求,并将请求 ID 写入 sqs,将请求的具体信息写入 DynamoDB 并生成一个 request 记录和一个标记为 PENDING 的状态记录。
- wkr: 处理具体请求。接收到请求就把状态标记为 INPROGRESS,处理成功则更改为 SUCCESS,失败为 ERROR,并把相应的 response 写入 dynamodb.
- qry: 从 DynamoDB 中查询 response.
架构解释
-
cmd(Command Service) :
-
功能:接受请求,并将请求 ID 写入 Amazon SQS(Simple Queue Service),将请求的具体信息写入 Amazon DynamoDB,并生成一个请求记录和一个标记为
PENDING的状态记录。 -
步骤:
- 接受客户端请求。
- 生成一个唯一的请求 ID。
- 将请求 ID 写入 SQS 队列。
- 将请求的详细信息和状态(
PENDING)写入 DynamoDB。
-
-
wkr(Worker Service) :
-
功能:处理具体请求。接收到请求后,将状态标记为
INPROGRESS,处理成功则更改为SUCCESS,失败则更改为ERROR,并将相应的响应写入 DynamoDB。 -
步骤:
- 从 SQS 队列中读取请求 ID。
- 根据请求 ID 从 DynamoDB 中获取请求的详细信息。
- 将请求的状态更新为
INPROGRESS。 - 处理请求。
- 根据处理结果,将状态更新为
SUCCESS或ERROR,并将响应写入 DynamoDB。
-
-
qry(Query Service) :
-
功能:从 DynamoDB 中查询响应。
-
步骤:
- 接受客户端查询请求。
- 根据请求 ID 从 DynamoDB 中查询请求的状态和响应。
- 返回查询结果给客户端。
-
架构的好处
-
异步处理:
- 通过使用 SQS 队列,cmd 和 wkr 服务之间实现了异步处理。cmd 服务可以快速响应客户端请求,而不需要等待请求处理完成。这提高了系统的响应速度和吞吐量。
-
解耦:
- cmd、wkr 和 qry 服务之间通过 SQS 和 DynamoDB 进行通信,实现了解耦。每个服务可以独立开发、部署和扩展,减少了系统的耦合度。
-
可扩展性:
- 由于使用了 SQS 队列和 DynamoDB,系统具有良好的可扩展性。可以根据负载情况水平扩展 wkr 服务实例,以处理更多的请求。
-
可靠性:
- SQS 提供了消息持久化和重试机制,确保请求不会丢失。DynamoDB 提供了高可用性和持久化存储,确保数据的可靠性。
-
状态管理:
- 通过在 DynamoDB 中记录请求的状态(
PENDING、INPROGRESS、SUCCESS、ERROR),可以方便地跟踪请求的处理进度和结果。这有助于监控和调试系统。
- 通过在 DynamoDB 中记录请求的状态(
-
灵活性:
- 由于系统是基于消息队列和状态管理的,可以灵活地处理各种类型的请求和响应。可以根据需要添加新的处理逻辑或扩展现有功能。
基于消息队列和状态管理的异步处理系统。通过使用 SQS 和 DynamoDB,实现了异步处理、解耦、可扩展性、可靠性和灵活性。cmd 服务负责接受请求并记录状态,wkr 服务负责处理请求并更新状态,qry 服务负责查询请求结果。通过这种架构,可以构建高性能、高可用性和易于扩展的系统。
和传统同步服务相比
使用传统的同步服务和异步处理架构各有其优缺点,具体选择取决于你的应用需求、性能要求和架构设计。以下是对这两种架构的详细比较,以及它们在不同场景下的适用性。
传统的同步服务架构
工作原理
-
接收请求:
- 客户端发送请求到服务。
-
处理请求:
- 服务接收请求并立即处理。
-
返回响应:
- 服务处理完成后,立即返回响应给客户端。
优点
-
简单性:
- 架构简单,易于理解和实现。所有处理逻辑都在一个服务中完成。
-
实时性:
- 请求处理和响应是同步的,客户端可以立即获得处理结果。
缺点
-
可扩展性:
- 难以处理高并发请求。服务需要在处理请求时保持连接,可能导致资源耗尽。
-
性能瓶颈:
- 如果请求处理时间较长,客户端需要等待,可能导致较高的延迟。
-
可靠性:
- 如果服务出现故障,所有请求都会受到影响。
异步处理架构
工作原理
-
接收请求:
- 客户端发送请求到 cmd 服务。
-
记录请求:
- cmd 服务将请求 ID 写入 SQS,将请求详细信息和状态写入 DynamoDB。
-
处理请求:
- wkr 服务从 SQS 读取请求,处理请求并更新状态。
-
查询结果:
- 客户端通过 qry 服务查询处理结果。
优点
-
可扩展性:
- 通过使用消息队列和分布式处理,可以轻松扩展以处理高并发请求。
-
性能优化:
- cmd 服务可以快速响应客户端请求,而不需要等待请求处理完成。wkr 服务可以独立处理请求,提高系统的整体吞吐量。
-
可靠性:
- 使用消息队列和分布式处理,提高了系统的容错能力和可靠性。即使某个 wkr 服务实例出现故障,其他实例仍然可以继续处理请求。
-
解耦:
- 各个服务之间通过消息队列和数据库进行通信,实现了解耦。每个服务可以独立开发、部署和扩展。
缺点
-
复杂性:
- 架构复杂度增加,需要处理消息队列、状态管理和数据一致性等问题。
-
延迟:
- 由于请求处理是异步的,客户端需要通过查询来获取处理结果,可能会增加一些延迟。
性能比较
-
同步服务:
- 对于简单、快速的请求处理,同步服务可能更快,因为它避免了消息队列和状态管理的开销。
- 适用于低并发、低延迟的场景。
-
异步处理:
- 对于复杂、耗时的请求处理,异步处理架构可以更好地分担负载,提高系统的整体吞吐量。
- 适用于高并发、高可用性和需要解耦的场景。
适用场景
传统的同步服务架构
-
简单的 CRUD 应用:
- 请求处理时间短,系统负载较低。
-
实时性要求高的应用:
- 客户端需要立即获得处理结果。
异步处理架构
-
高并发应用:
- 系统需要处理大量并发请求,且请求处理时间较长。
-
分布式系统:
- 系统需要解耦各个组件,提高可扩展性和容错能力。
-
任务队列:
- 需要处理后台任务或批处理任务。
总结
选择使用传统的同步服务架构还是异步处理架构取决于你的具体需求和应用场景。同步服务架构简单、实时性高,适用于低并发、低延迟的场景。异步处理架构具有更高的可扩展性和可靠性,适用于高并发、高可用性和需要解耦的场景。通过权衡这些因素,你可以选择最适合你的应用的架构。
无服务架构
选择使用 EC2 还是 Lambda 取决于你的应用需求、架构设计、成本考虑和运维要求。以下是一些关键因素和场景,帮助你决定何时使用 EC2 和何时使用 Lambda。
使用 EC2 的场景
-
长时间运行的任务:
- 如果你的应用需要长时间运行的任务或持续的后台处理,EC2 是一个更好的选择。Lambda 函数有最大执行时间限制(15 分钟),不适合长时间运行的任务。
-
需要完全控制底层环境:
- 如果你需要完全控制操作系统、网络配置、存储和其他底层环境,EC2 提供了更大的灵活性和控制。你可以安装任何软件、配置任何服务,并根据需要进行自定义。
-
复杂的依赖关系:
- 如果你的应用有复杂的依赖关系或需要特定的硬件资源(如 GPU),EC2 提供了更多的选择和配置选项。
-
状态持久化:
- 如果你的应用需要持久化状态或在多个请求之间共享状态,EC2 提供了持久存储选项(如 EBS 卷)和内存存储。
-
传统应用:
- 如果你有现有的传统应用或需要迁移现有的服务器工作负载,EC2 是一个更自然的选择。
-
高并发和高吞吐量:
- 如果你的应用需要处理高并发和高吞吐量的请求,EC2 提供了更高的可扩展性和性能。
使用 Lambda 的场景
-
无服务器架构:
- 如果你希望构建无服务器架构,减少运维负担,Lambda 是一个很好的选择。你只需编写代码并部署函数,AWS 会自动处理底层基础设施的管理和扩展。
-
事件驱动应用:
- 如果你的应用是事件驱动的,并且可以与 AWS 服务(如 S3、DynamoDB、Kinesis 等)集成,Lambda 提供了无缝的集成和管理。
-
短时间运行的任务:
- 如果你的任务是短时间运行的(如处理 HTTP 请求、文件处理、数据转换等),Lambda 是一个理想的选择。Lambda 函数按需执行,并且只为实际使用的计算时间付费。
-
自动扩展:
- Lambda 函数会根据请求量自动扩展,无需手动配置或管理服务器实例。适用于需要快速扩展和缩减的应用。
-
成本效益:
- 对于低流量或间歇性工作负载,Lambda 提供了更高的成本效益。你只需为实际使用的计算时间付费,而不需要为闲置的服务器资源付费。
-
快速开发和部署:
- Lambda 提供了快速开发和部署 API 的能力,适用于需要快速迭代和发布的应用。
示例场景
使用 EC2 的示例
-
Web 应用服务器:
- 运行一个需要持续运行的 Web 应用服务器,处理高并发请求,并需要持久化存储和复杂的依赖关系。
-
大数据处理:
- 运行一个大数据处理集群,使用 Hadoop 或 Spark 进行长时间的数据分析和处理。
-
机器学习训练:
- 运行一个需要 GPU 资源的机器学习模型训练任务,持续数小时或数天。
使用 Lambda 的示例
-
图像处理:
- 处理上传到 S3 的图像文件,进行缩放、裁剪和格式转换。每个图像处理任务只需几秒钟。
-
API 网关后端:
- 使用 API Gateway 和 Lambda 构建无服务器 API,处理 HTTP 请求并返回响应。
-
事件驱动的自动化任务:
- 监控 DynamoDB 表的变化,并在数据变化时触发 Lambda 函数进行数据处理和通知。
总结
选择使用 EC2 还是 Lambda 取决于你的应用需求和架构设计。EC2 提供了更大的灵活性和控制,适用于长时间运行的任务、复杂的依赖关系和高并发的应用。Lambda 提供了无服务器架构、自动扩展和按需计费,适用于事件驱动、短时间运行的任务和快速开发部署的应用。通过权衡这些因素,你可以选择最适合你的应用的解决方案。
数据库设计
选择 Amazon DynamoDB 而不是 Amazon RDS(关系数据库服务)取决于你的应用需求和特定的使用场景。以下是一些关键因素和场景,帮助你理解为什么在某些情况下选择 DynamoDB 而不是 RDS。
DynamoDB 的特点和优势
-
无服务器架构:
- DynamoDB 是一种完全托管的 NoSQL 数据库服务,不需要管理底层基础设施。AWS 负责自动扩展、备份和维护。
-
高性能和低延迟:
- DynamoDB 提供单毫秒级的响应时间,适用于需要高性能和低延迟的应用。
-
自动扩展:
- DynamoDB 可以根据流量自动扩展和缩减容量,适用于需要处理不规则流量和高并发请求的应用。
-
灵活的数据模型:
- DynamoDB 使用键值和文档数据模型,支持灵活的数据结构和动态模式。适用于需要频繁更改数据结构的应用。
-
内置高可用性和持久性:
- DynamoDB 在多个可用区自动复制数据,提供高可用性和数据持久性。
-
细粒度的访问控制:
- DynamoDB 集成了 AWS Identity and Access Management (IAM),提供细粒度的访问控制和安全管理。
-
事件驱动架构:
- DynamoDB 支持 DynamoDB Streams,可以实现事件驱动架构,方便与其他 AWS 服务集成。
RDS 的特点和优势
-
关系数据模型:
- RDS 提供关系数据库服务,支持复杂的 SQL 查询、事务和关系数据模型。适用于需要强一致性和复杂查询的应用。
-
多种数据库引擎:
- RDS 支持多种数据库引擎,如 MySQL、PostgreSQL、MariaDB、Oracle 和 SQL Server。适用于需要特定数据库功能和兼容性的应用。
-
事务支持:
- RDS 支持 ACID 事务,适用于需要强一致性和事务处理的应用。
-
复杂查询和分析:
- RDS 支持复杂的 SQL 查询、联接和分析功能,适用于需要复杂数据处理和分析的应用。
-
备份和恢复:
- RDS 提供自动备份、快照和恢复功能,确保数据的安全性和持久性。
选择 DynamoDB 的场景
-
高并发和高吞吐量:
- 如果你的应用需要处理高并发请求和高吞吐量,DynamoDB 提供了自动扩展和低延迟的优势。
-
无服务器架构:
- 如果你希望构建无服务器架构,减少运维负担,DynamoDB 是一个理想的选择。
-
灵活的数据结构:
- 如果你的数据结构频繁变化或不固定,DynamoDB 的键值和文档数据模型提供了更大的灵活性。
-
事件驱动应用:
- 如果你需要实现事件驱动架构,DynamoDB Streams 提供了无缝的集成和事件处理能力。
-
简单的查询需求:
- 如果你的应用主要是简单的读写操作和查询,DynamoDB 提供了高性能和低延迟的优势。
选择 RDS 的场景
-
复杂的关系数据:
- 如果你的应用需要处理复杂的关系数据和联接操作,RDS 提供了关系数据库的优势。
-
事务处理:
- 如果你的应用需要强一致性和事务处理,RDS 提供了 ACID 事务支持。
-
复杂查询和分析:
- 如果你的应用需要复杂的 SQL 查询、联接和分析功能,RDS 提供了强大的查询和分析能力。
-
现有的关系数据库应用:
- 如果你有现有的关系数据库应用或需要迁移现有的数据库工作负载,RDS 提供了兼容性和易于迁移的优势。
总结
选择 DynamoDB 还是 RDS 取决于你的具体需求和应用场景。DynamoDB 提供了高性能、低延迟、自动扩展和灵活的数据模型,适用于高并发、无服务器架构和简单查询需求的应用。RDS 提供了关系数据模型、复杂查询、事务支持和多种数据库引擎,适用于需要强一致性、复杂查询和事务处理的应用。通过权衡这些因素,你可以选择最适合你的应用的数据库服务。
DynamoDB 的访问控制
DynamoDB 使用 AWS Identity and Access Management (IAM) 来控制对表和索引的访问。你可以使用 IAM 角色、用户和策略来管理对 DynamoDB 资源的访问权限。
主要机制
-
IAM 用户和角色:
- 你可以为 IAM 用户和角色分配策略,以控制他们对 DynamoDB 资源的访问权限。
-
IAM 策略:
- IAM 策略是 JSON 文档,定义了允许或拒绝的操作。你可以使用策略来控制对 DynamoDB 表的读写权限。
-
条件语句:
- 你可以在 IAM 策略中使用条件语句,根据特定条件(如 IP 地址、请求时间等)控制访问权限。
RDS 的访问控制
对于 Amazon RDS,访问控制主要通过以下几种机制实现:
-
IAM 数据库身份验证:
- RDS 支持使用 IAM 用户和角色进行数据库身份验证。你可以为 IAM 用户和角色分配策略,以控制他们对 RDS 数据库实例的访问权限。
-
数据库用户和权限:
- 你可以在数据库内部创建用户,并分配适当的权限(如 SELECT、INSERT、UPDATE 等)。这些权限控制了数据库用户对数据库对象(如表、视图等)的访问。
-
安全组:
- RDS 实例使用 Amazon VPC 安全组来控制网络级别的访问。你可以配置安全组规则,允许或拒绝特定 IP 地址或子网对 RDS 实例的访问。
Amazon RDS(关系数据库服务)不支持像 Amazon DynamoDB 那样的自动扩展,但它提供了一些功能和策略,可以帮助你管理和扩展数据库实例的容量。以下是一些与 RDS 扩展相关的功能和策略:
RDS 扩展选项
-
手动扩展:
- 你可以手动调整 RDS 实例的计算和存储容量。这包括增加实例的大小(例如,从
db.m5.large升级到db.m5.xlarge)和增加存储空间。
- 你可以手动调整 RDS 实例的计算和存储容量。这包括增加实例的大小(例如,从
-
自动存储扩展:
- RDS 支持自动存储扩展功能,可以根据需要自动增加存储空间。这对于处理不断增长的数据量非常有用。
-
读副本:
- 你可以创建一个或多个读副本(Read Replica),以分担读取负载。读副本可以在不同的区域中创建,以提高读取性能和可用性。
-
Aurora 自动扩展:
- 如果你使用的是 Amazon Aurora(RDS 的一种兼容 MySQL 和 PostgreSQL 的数据库引擎),Aurora 提供了一些自动扩展功能,包括 Aurora Serverless 和 Aurora 自动存储扩展。
DynamoDB 的分库分表
分库分表(Sharding)
DynamoDB 本身是一个分布式 NoSQL 数据库,内置了分片(Sharding)机制。DynamoDB 自动将数据分布在多个分区(Partition)上,以实现高可用性和可扩展性。
-
分区键(Partition Key) :
- 在创建 DynamoDB 表时,你需要指定一个分区键。DynamoDB 使用分区键将数据分布到不同的分区上。
- 分区键的选择非常重要,应该尽量保证分区键的值分布均匀,以避免热点问题。
-
分区管理:
- DynamoDB 自动管理分区的创建和扩展。随着数据量和请求量的增加,DynamoDB 会自动增加分区,以保持性能和可用性。
数据同步
DynamoDB 提供了多种数据同步机制,以实现数据的复制和一致性。
-
DynamoDB Streams:
- DynamoDB Streams 记录表中数据的变化(如插入、更新和删除操作),并以事件流的形式提供。
- 你可以使用 AWS Lambda 或其他消费者应用程序处理这些事件,实现数据同步和触发其他操作。
-
跨区域复制(Global Tables) :
- DynamoDB Global Tables 提供了跨区域复制功能,可以在多个 AWS 区域之间自动同步数据。
- Global Tables 确保在不同区域的表之间保持数据一致性,适用于需要高可用性和低延迟的全球分布式应用。
RDS 的分库分表
分库分表(Sharding)
对于 Amazon RDS,分库分表通常需要手动实现。以下是一些常见的分库分表策略:
-
水平分片(Horizontal Sharding) :
- 将数据按某个分片键(如用户 ID)分布到多个数据库实例上。每个实例存储一部分数据。
- 应用程序需要根据分片键路由请求到相应的数据库实例。
-
垂直分片(Vertical Sharding) :
- 将不同的表或数据集分布到不同的数据库实例上。每个实例存储不同类型的数据。
- 适用于数据之间关联较少的场景。
数据同步
RDS 提供了多种数据同步和复制机制,以实现数据的高可用性和一致性。
-
读副本(Read Replicas) :
- 你可以创建一个或多个读副本,以分担读取负载。读副本会异步复制主实例的数据。
- 适用于需要高读取性能和可用性的场景。
-
跨区域读副本(Cross-Region Read Replicas) :
- 你可以在不同的 AWS 区域创建读副本,实现跨区域数据复制和高可用性。
- 适用于全球分布式应用。
-
多可用区部署(Multi-AZ Deployment) :
- RDS 支持多可用区部署,提供同步复制和自动故障转移功能。主实例的数据会同步复制到备用实例。
- 适用于需要高可用性和数据持久性的场景。
可扩展性
EC2 扩缩容
对于 EC2 实例,扩缩容通常是通过 Auto Scaling Group (ASG) 和 Amazon CloudWatch 监控指标来实现的。以下是如何使用 CloudWatch 指标来自动扩缩容 EC2 实例的详细步骤:
使用 CloudWatch 指标进行 EC2 扩缩容
-
创建 Auto Scaling Group (ASG) :
- 在 EC2 控制台中,创建一个 Auto Scaling Group,并配置启动模板或启动配置。
-
配置 CloudWatch 警报:
- 在 CloudWatch 控制台中,创建一个警报,基于特定的指标(如 CPU 使用率、网络流量等)。
- 例如,创建一个警报,当 CPU 使用率超过 70% 时触发扩展操作。
-
配置扩展策略:
- 在 Auto Scaling Group 中,配置扩展策略,指定在警报触发时执行的操作。
- 例如,当 CPU 使用率超过 70% 时,增加一个或多个 EC2 实例。
-
配置缩减策略:
- 同样地,配置缩减策略,指定在警报触发时执行的操作。
- 例如,当 CPU 使用率低于 30% 时,减少一个或多个 EC2 实例。
Lambda 扩缩容
对于 AWS Lambda,扩缩容是自动管理的。Lambda 函数会根据传入请求的数量自动扩展,无需手动配置或管理服务器实例。以下是 Lambda 的扩缩容机制:
Lambda 自动扩展
-
按需扩展:
- Lambda 函数会根据传入请求的数量自动扩展。每个请求都会触发一个新的 Lambda 实例,Lambda 可以同时处理多个请求。
-
无服务器架构:
- Lambda 是一种无服务器计算服务,AWS 负责底层基础设施的管理和扩展。你只需编写代码并部署函数,AWS 会自动处理扩展和缩减。
-
并发限制:
- 你可以设置 Lambda 函数的并发限制,以控制最大并发执行数。默认情况下,每个账户在每个区域的并发执行数限制为 1000。
-
监控和警报:
- 你可以使用 CloudWatch 监控 Lambda 函数的执行情况,并设置警报来监控错误率、延迟等指标。
总结
- EC2 扩缩容:通过 Auto Scaling Group (ASG) 和 CloudWatch 指标(如 CPU 使用率)来实现。你需要配置扩展和缩减策略,根据监控指标自动调整 EC2 实例的数量。
- Lambda 扩缩容:自动管理,无需手动配置。Lambda 函数会根据传入请求的数量自动扩展,AWS 负责底层基础设施的管理和扩展。
安全性
Consumer Token
OIDC(OpenID Connect)是一个基于 OAuth 2.0 协议的身份验证协议。它允许客户端应用程序(例如 Web 应用、移动应用)通过授权服务器验证用户身份,并获取用户的基本信息(如用户名、电子邮件等)。
主要概念
- OAuth 2.0: 一个授权框架,允许第三方应用程序在资源所有者的许可下访问资源服务器上的资源。OAuth 2.0 主要用于授权,而不是身份验证。
- OpenID Connect: 在 OAuth 2.0 之上构建的身份验证层,提供了用户身份验证和用户信息获取的标准化方法。
主要组件
- End-User(终端用户): 需要进行身份验证的用户。
- Relying Party (RP)(依赖方): 需要验证用户身份的客户端应用程序。
- OpenID Provider (OP)(OpenID 提供者): 提供身份验证服务的服务器。
工作流程
- 用户身份验证: 用户通过客户端应用程序(RP)发起身份验证请求。
- 授权请求: 客户端应用程序将用户重定向到 OpenID 提供者(OP),请求用户授权。
- 用户授权: 用户在 OpenID 提供者(OP)上进行身份验证并授权客户端应用程序。
- 授权码: OpenID 提供者(OP)返回一个授权码给客户端应用程序。
- 令牌交换: 客户端应用程序使用授权码向 OpenID 提供者(OP)请求访问令牌和 ID 令牌。
- 获取用户信息: 客户端应用程序使用访问令牌向用户信息端点请求用户信息。
主要令牌
- ID Token: 一个 JWT(JSON Web Token),包含用户的身份信息(如用户 ID、用户名、电子邮件等)。客户端应用程序使用 ID 令牌来验证用户身份。
- Access Token: 用于访问受保护资源的令牌。
- Refresh Token: 用于获取新的访问令牌的令牌。
总结
- OAuth 2.0: 授权框架,允许第三方应用程序在资源所有者的许可下访问资源服务器上的资源。
- OpenID Connect: 在 OAuth 2.0 之上构建的身份验证层,提供了用户身份验证和用户信息获取的标准化方法。
- 主要组件: 终端用户、依赖方(客户端应用程序)和 OpenID 提供者(身份验证服务器)。
- 工作流程: 用户身份验证、授权请求、用户授权、授权码、令牌交换和获取用户信息。
- 主要令牌: ID 令牌、访问令牌和刷新令牌。
Server To Server Token
OAuth 2.0 是 OAuth 1.0 的继任者,旨在简化授权流程并提供更灵活的授权机制。OAuth 2.0 是一个授权框架,允许第三方应用程序在资源所有者的许可下访问资源服务器上的资源。
主要概念
- 资源所有者(Resource Owner): 拥有资源的用户。
- 客户端(Client): 需要访问资源的第三方应用程序。
- 资源服务器(Resource Server): 存储资源的服务器。
- 授权服务器(Authorization Server): 负责验证资源所有者身份并颁发访问令牌的服务器。
授权类型
OAuth 2.0 提供了多种授权类型,以适应不同的应用场景:
- 授权码授权(Authorization Code Grant): 适用于 Web 应用程序,客户端通过授权码获取访问令牌。
- 隐式授权(Implicit Grant): 适用于单页应用程序(SPA),客户端直接获取访问令牌。
- 资源所有者密码凭证授权(Resource Owner Password Credentials Grant): 适用于受信任的客户端,客户端使用资源所有者的用户名和密码获取访问令牌。
- 客户端凭证授权(Client Credentials Grant): 适用于服务器到服务器的通信,客户端使用自己的凭证获取访问令牌。
工作流程
以下是授权码授权的工作流程:
- 用户授权: 客户端将用户重定向到授权服务器,用户在授权服务器上进行身份验证并授权客户端。
- 获取授权码: 授权服务器返回一个授权码给客户端。
- 获取访问令牌: 客户端使用授权码向授权服务器请求访问令牌。
- 访问资源: 客户端使用访问令牌向资源服务器请求访问资源。
OAuth 2.0 和 OpenID Connect (OIDC) 是两个相关但不同的协议,常用于身份验证和授权。以下是 OAuth 2.0 授权码授权和 OpenID Connect (OIDC) 的详细解释,以及它们之间的区别。
OAuth 2.0 授权码授权
OAuth 2.0 是一个授权框架,允许第三方应用程序在资源所有者的授权下,访问资源服务器上的受保护资源。授权码授权(Authorization Code Grant)是 OAuth 2.0 中最常用的授权类型之一。
工作流程
-
用户授权:
- 用户在浏览器中访问客户端应用程序,并被重定向到授权服务器进行身份验证和授权。
-
获取授权码:
- 用户授权后,授权服务器将用户重定向回客户端应用程序,并附带一个授权码。
-
交换授权码:
- 客户端应用程序使用授权码向授权服务器请求访问令牌(Access Token)。
-
获取访问令牌:
- 授权服务器验证授权码,并返回访问令牌和可选的刷新令牌(Refresh Token)。
-
访问受保护资源:
- 客户端应用程序使用访问令牌访问资源服务器上的受保护资源。
`1. 用户 -> 客户端应用程序: 请求访问受保护资源`
`2. 客户端应用程序 -> 授权服务器: 请求授权码`
`3. 授权服务器 -> 用户: 请求身份验证和授权`
`4. 用户 -> 授权服务器: 提供身份验证和授权`
`5. 授权服务器 -> 客户端应用程序: 返回授权码`
`6. 客户端应用程序 -> 授权服务器: 请求访问令牌`
`7. 授权服务器 -> 客户端应用程序: 返回访问令牌`
`8. 客户端应用程序 -> 资源服务器: 使用访问令牌访问受保护资源`
OpenID Connect (OIDC)
OpenID Connect (OIDC) 是一个基于 OAuth 2.0 的身份验证协议,扩展了 OAuth 2.0 的功能,提供了用户身份验证和身份信息的获取。OIDC 在 OAuth 2.0 的基础上增加了 ID 令牌(ID Token)和用户信息端点(UserInfo Endpoint)。
工作流程
-
用户授权:
- 用户在浏览器中访问客户端应用程序,并被重定向到授权服务器进行身份验证和授权。
-
获取授权码:
- 用户授权后,授权服务器将用户重定向回客户端应用程序,并附带一个授权码。
-
交换授权码:
- 客户端应用程序使用授权码向授权服务器请求访问令牌和 ID 令牌。
-
获取访问令牌和 ID 令牌:
- 授权服务器验证授权码,并返回访问令牌、ID 令牌和可选的刷新令牌。
-
验证 ID 令牌:
- 客户端应用程序验证 ID 令牌,获取用户的身份信息。
-
访问受保护资源:
- 客户端应用程序使用访问令牌访问资源服务器上的受保护资源。
`1. 用户 -> 客户端应用程序: 请求访问受保护资源`
`2. 客户端应用程序 -> 授权服务器: 请求授权码`
`3. 授权服务器 -> 用户: 请求身份验证和授权`
`4. 用户 -> 授权服务器: 提供身份验证和授权`
`5. 授权服务器 -> 客户端应用程序: 返回授权码`
`6. 客户端应用程序 -> 授权服务器: 请求访问令牌和 ID 令牌`
`7. 授权服务器 -> 客户端应用程序: 返回访问令牌和 ID 令牌`
`8. 客户端应用程序 -> 资源服务器: 使用访问令牌访问受保护资源`
`9. 客户端应用程序 -> 用户: 验证 ID 令牌并获取用户身份信息`
区别
-
目的:
- OAuth 2.0:主要用于授权,允许第三方应用程序在资源所有者的授权下访问受保护资源。
- OIDC:在 OAuth 2.0 的基础上增加了身份验证功能,提供用户身份信息的获取。
-
ID 令牌:
- OAuth 2.0:没有 ID 令牌,只有访问令牌和可选的刷新令牌。
- OIDC:增加了 ID 令牌,用于携带用户身份信息。
-
用户信息端点:
- OAuth 2.0:没有用户信息端点。
- OIDC:增加了用户信息端点,客户端应用程序可以使用访问令牌请求用户的详细信息。
-
标准化的身份验证:
- OAuth 2.0:没有标准化的身份验证机制。
- OIDC:提供了标准化的身份验证流程和协议,确保不同实现之间的互操作性。
总结
- OAuth 2.0 授权码授权:主要用于授权,允许第三方应用程序在资源所有者的授权下访问受保护资源。没有 ID 令牌和用户信息端点。
- OpenID Connect (OIDC) :在 OAuth 2.0 的基础上增加了身份验证功能,提供用户身份信息的获取。增加了 ID 令牌和用户信息端点,提供标准化的身份验证机制。
监控和日志
AWS Target Group 的健康检查(Health Check)用于监控和管理目标(如 EC2 实例、IP 地址或 Lambda 函数)的健康状态。健康检查可以帮助确保只有健康的目标接收流量,从而提高应用的可用性和可靠性。
健康检查的工作原理
-
配置健康检查:
- 在创建或编辑 Target Group 时,你可以配置健康检查的参数,如协议、路径、端口、间隔时间、超时时间、健康阈值和不健康阈值。
-
执行健康检查:
- 负载均衡器会定期向目标发送健康检查请求,根据目标的响应来确定其健康状态。
-
健康状态评估:
- 如果目标在指定的健康检查间隔内连续通过健康检查请求,目标被标记为健康(Healthy)。
- 如果目标在指定的不健康阈值内连续未通过健康检查请求,目标被标记为不健康(Unhealthy)。
-
流量管理:
- 负载均衡器只会将流量路由到健康的目标。不健康的目标不会接收流量,直到它们恢复健康状态。
配置健康检查
以下是配置健康检查的步骤:
-
打开 EC2 控制台。
-
在左侧导航栏中,选择 "Target Groups" 。
-
选择一个 Target Group,然后点击 "Actions" > "Edit health checks"。
-
配置健康检查参数:
- 协议:选择 HTTP 或 HTTPS。
- 路径:输入健康检查请求的路径(例如
/health)。 - 端口:选择健康检查请求的端口。
- 健康检查间隔:设置健康检查请求之间的时间间隔(秒)。
- 超时时间:设置健康检查请求的超时时间(秒)。
- 健康阈值:设置目标被标记为健康所需的连续成功响应次数。
- 不健康阈值:设置目标被标记为不健康所需的连续失败响应次数。
-
点击 "Save" 保存配置。
处理不健康目标
当目标被标记为不健康时,负载均衡器会停止将流量路由到该目标。目标需要通过连续的健康检查请求后,才能恢复接收流量。
设置警报
你可以使用 Amazon CloudWatch 来监控 Target Group 的健康状态,并在目标变为不健康时发送警报。以下是设置警报的步骤:
-
打开 CloudWatch 控制台。
-
在左侧导航栏中,选择 "Alarms" 。
-
点击 "Create alarm" 。
-
选择指标:
- 选择指标类型:选择 "ApplicationELB"。
- 选择指标命名空间:选择 "Target Group Metrics"。
- 选择目标组:选择你要监控的 Target Group。
- 选择指标:选择 "UnHealthyHostCount"。
-
配置警报条件:
- 条件:设置当不健康目标数量超过指定阈值时触发警报。
-
配置警报操作:
- 通知:选择或创建一个 SNS 主题,用于发送警报通知(如电子邮件、短信等)。
-
配置警报名称和描述:
- 名称:输入警报名称。
- 描述:输入警报描述(可选)。
-
点击 "Create alarm" 完成警报创建。
示例
假设你有一个 Target Group,以下是如何配置健康检查和设置警报的示例:
配置健康检查
- 协议:HTTP
- 路径:
/health - 端口:80
- 健康检查间隔:30 秒
- 超时时间:5 秒
- 健康阈值:3
- 不健康阈值:3
设置警报
- 选择指标:
UnHealthyHostCount - 条件:当不健康目标数量大于或等于 1 时触发警报。
- 通知:选择或创建一个 SNS 主题,用于发送警报通知。
总结
AWS Target Group 的健康检查用于监控和管理目标的健康状态,确保只有健康的目标接收流量。你可以配置健康检查参数,并使用 CloudWatch 设置警报,当目标变为不健康时发送通知。通过这些步骤,你可以提高应用的可用性和可靠性,及时响应不健康目标的情况。
在配置健康检查时,健康阈值和不健康阈值的设置决定了目标被标记为健康或不健康所需的连续成功或失败的健康检查次数。以下是对健康阈值和不健康阈值的详细解释,以及为什么在示例中都设置为 3 的原因。
健康检查参数解释
-
健康阈值(Healthy Threshold) :
- 这是目标被标记为健康所需的连续成功健康检查次数。例如,如果健康阈值设置为 3,则目标需要连续通过 3 次健康检查,才能被标记为健康。
-
不健康阈值(Unhealthy Threshold) :
- 这是目标被标记为不健康所需的连续失败健康检查次数。例如,如果不健康阈值设置为 3,则目标需要连续失败 3 次健康检查,才能被标记为不健康。
示例配置
在示例中,健康阈值和不健康阈值都设置为 3,意味着:
-
健康阈值 = 3:
- 目标需要连续通过 3 次健康检查,才能被标记为健康。
-
不健康阈值 = 3:
- 目标需要连续失败 3 次健康检查,才能被标记为不健康。
为什么选择 3 作为阈值
选择 3 作为健康阈值和不健康阈值的原因通常是为了在健康检查的敏感性和稳定性之间取得平衡:
-
避免短暂故障:
- 设置较高的阈值(如 3)可以避免因短暂的网络波动或临时故障导致目标被错误地标记为不健康。同样,目标需要连续通过多次健康检查,才能被标记为健康,确保目标确实恢复正常。
-
提高稳定性:
- 较高的阈值可以提高健康检查的稳定性,减少频繁的状态切换(健康和不健康之间的切换)。这有助于保持系统的稳定性和可靠性。
-
适应性:
- 3 次连续健康检查或不健康检查通常是一个合理的默认值,适用于大多数应用场景。如果你的应用对健康检查的敏感性要求更高或更低,可以根据具体需求调整阈值。
Zipkin 的原理
Zipkin 的核心概念包括以下几个部分:
-
追踪(Trace) :
- 一个追踪表示一个请求在分布式系统中的完整生命周期。一个追踪由多个跨度(Span)组成,每个跨度表示请求在一个服务中的处理过程。
-
跨度(Span) :
- 一个跨度表示请求在一个服务中的处理过程。跨度包含开始时间、结束时间、服务名称、操作名称和其他元数据。
-
注释(Annotations) :
- 注释是附加在跨度上的时间戳,用于记录特定事件(如请求发送、请求接收等)。
-
标签(Tags) :
- 标签是附加在跨度上的键值对,用于记录额外的元数据(如 HTTP 状态码、错误信息等)。
Zipkin 的架构
Zipkin 的架构通常包括以下组件:
-
追踪器(Tracer) :
- 追踪器是集成在应用程序中的库,用于捕获和发送追踪数据。常见的追踪器库包括 Brave(Java)、zipkin-go(Go)、zipkin-js(JavaScript)等。
-
收集器(Collector) :
- 收集器接收来自追踪器的追踪数据,并将其存储在后端存储中。Zipkin 支持多种后端存储,如 Elasticsearch、Cassandra、MySQL 等。
-
存储(Storage) :
- 存储用于保存追踪数据,支持多种后端存储选项。
-
查询服务(Query Service) :
- 查询服务提供 API,用于查询和检索追踪数据。
-
用户界面(UI) :
- 用户界面提供可视化工具,用于展示和分析追踪数据。
总结
Zipkin 是一个分布式追踪系统,用于收集和分析分布式系统中的请求数据,帮助开发者和运维人员了解请求在系统中的流转过程,识别性能瓶颈和故障点。Zipkin 的核心概念包括追踪、跨度、注释和标签,其架构包括追踪器、收集器、存储、查询服务和用户界面。
TraceId 的生成和传播
在分布式系统中,Zipkin 使用 traceId 来唯一标识一个请求的整个生命周期。为了在各个服务之间传递 traceId,Zipkin 依赖于分布式追踪的上下文传播机制。以下是详细的解释,包括 traceId 的生成、传播和使用。
-
生成 TraceId:
- 当一个请求进入系统时(通常是由第一个服务接收到请求),如果没有现有的
traceId,Zipkin 追踪器会生成一个新的traceId。这个traceId将用于标识整个请求的生命周期。
- 当一个请求进入系统时(通常是由第一个服务接收到请求),如果没有现有的
-
传播 TraceId:
- 在请求从一个服务传递到另一个服务时,
traceId需要在服务之间传播。Zipkin 使用 HTTP 请求头或其他传输机制来传递追踪上下文,包括traceId、spanId和其他相关信息。
- 在请求从一个服务传递到另一个服务时,
-
使用 TraceId:
- 每个服务在处理请求时,会从传入的请求中提取
traceId并将其包含在新的请求中,以确保traceId在整个请求链中保持一致。
- 每个服务在处理请求时,会从传入的请求中提取
传播机制
Zipkin 使用 HTTP 请求头来传播追踪上下文。以下是常见的 HTTP 请求头:
X-B3-TraceId:唯一标识整个请求链的traceId。X-B3-SpanId:唯一标识当前请求的spanId。X-B3-ParentSpanId:标识当前span的父spanId(如果有)。X-B3-Sampled:指示是否对请求进行采样(值为1表示采样,0表示不采样)。X-B3-Flags:用于传递调试标志。
总结
Zipkin 使用 traceId 来唯一标识一个请求的整个生命周期,并通过 HTTP 请求头或其他传输机制在分布式系统的各个服务之间传播 traceId。通过集成 Zipkin 追踪器库(如 Brave),你可以自动生成、传播和使用 traceId,确保在整个请求链中保持一致。
上下文传播机制
在多线程环境中,保持 traceId 不变是分布式追踪系统的一个重要挑战。为了在多线程环境中正确传播和保持 traceId,分布式追踪系统通常使用上下文传播机制。以下是详细的解释,包括如何在多线程环境中保持 traceId 不变的原理和实现方法。
上下文传播机制用于在不同线程之间传递追踪上下文(包括 traceId、spanId 等)。在 Java 中,常见的实现方式是使用 ThreadLocal 变量来存储和传递追踪上下文。
ThreadLocal 变量
ThreadLocal 变量为每个线程提供独立的变量副本,确保每个线程都可以独立访问和修改自己的变量副本,而不会影响其他线程。
总结
在多线程环境中,保持 traceId 不变是分布式追踪系统的一个重要挑战。通过使用上下文传播机制(如 ThreadLocal 变量),可以在不同线程之间传递追踪上下文,确保 traceId 在整个请求链中保持一致。