ITPub博客

首页 > 数据库 > 数据库开发技术 > 打造云上应用的最佳实践:云原生架构的经典模式实践指南

打造云上应用的最佳实践:云原生架构的经典模式实践指南

原创 数据库开发技术 作者:灸哥漫谈 时间:2024-02-09 08:57:39 0 删除 编辑

点击上方“灸哥漫谈”,关注灸哥更多精彩




01



前言



在编写代码的过程中,我们常常运用各种设计模式来优化代码结构和提高代码效率。此前,我已经用灸哥特有的风格对三大类的设计模式进行了详尽的阐述,并通过福利放送的形式将相关电子合集分享给了各位读者。领取方式请参见文章底部。

值得注意的是,在云原生架构中,同样存在一系列典型的设计模式,例如服务化架构模式等。本文将和大家一起深入探讨这些在云原生架构中常用的设计模式,助力大家提升设计灵活、高效、可扩展解决方案的能力。同时,我们还将分析一些典型的反模式,以帮助大家规避潜在的陷阱和误区。


02



 服务化模式



服务化架构通常也被称为面向服务的架构 SOA,在通信双方之间约定好服务规约,然后基于规约发布和调用服务,服务化架构模式的核心价值主要体现在:

  • 更好地面向业务:通信双方是基于自己的实际业务需求设计接口(服务规约)

  • 松耦合和灵活性:在约定好服务规约之后只要遵循规约即可

  • 服务共享和复用:服务通常是可共享的,多个服务消费者可以同时调用共享服务

在实际服务化架构模式实践过程中,具体可用于实现服务规约的技术方案主要有三种:服务接口定义、IDL、OpenAPI。


1
服务规约

服务规约,简单说就是双方定义好的接口,一般由以下三种实现方案:


服务规约技术实现方案一:服务接口定义

服务接口定义是指对应的编程语言对服务接口的描述。比如 Dubbo 是通过 Java 接口来实现的。比如:


public interface ItemService {
   Item findById(Integer id);
   Boolean createItem(Item item);
}


基于编程语言提供的特性可以帮助我们很好地实现服务规约,但是这种实现方式有利有弊。利好是能够很好地支持某种支持的编程语言,比如 Java,但是并不是每一种编程语言都支持接口定义的,比如 JavaScript。


服务规约技术实现方案二:IDL

IDL 是指通过 IDL(Interface Definition Language,接口定义语言)对服务进行规约的定义,比如 gRPC、Thrift 等。使用步骤:

  • 基于 IDL 定义对应的服务接口

  • 基于 IDL 文件生成与编程语言对应的代码

  • 实现对应的服务接口或者调用对应的服务

以 gRPC 为例,首先要基于 Protocol Buffers 编写 IDL 文件


service ItemService {
 rpc FindItem (GetItemRequest) returns (ItemResponse);
 rpc FindById (google.protobuf.Int32Value) returns (ItemResponse);
}

message GetItemRequest {
 int32 id = 1;
}

message ItemResponse {
 int32 id = 1;
 string name = “”;
}


接口定义之后,根据 protoc 命令行为不同的编程语言生成对应的代码,可支持面向 C++、Go、Java、Node.js 等编程语言。


服务规约技术实现方案三:OpenAPI

OpenAPI 是基于 HTTP REST 通信的接口规范,它本身与具体的编程语言无关,任何语言都可以基于 OpenAPI 规范发布和调用服务。


2
服务分组

服务分组的目的是为了满足不同的地理空间和服务等级需求。比如在不同的数据中心,即使是相同的服务,也要通过不同的集群部署方式来区分。此外,如果你的场景需要考虑到服务等级要求,像 VIP 的服务,也会涉及到同样的服务在不同分组中的不同要求。


3
服务版本

服务发布后,随着需求的变更,需要在原有的服务规约上提供更多的服务接口,可能会涉及到具体的逻辑变更。这样在考虑兼容性的时候,需要用服务版本来区分前后服务的接口规约。


4
服务元信息

当服务数量超级多的时候,为了便于查找接口方便,是需要给服务添加一些元信息,比如服务描述、提供者信息、Tag 等,便于对服务的管理。


5
服务注册与发现

这里的内容就不多做介绍了,前面已经讲了好多了,放一张图,不熟悉的去翻阅我之前关于服务注册与发现的内容。



6
其他
  • 服务健康检查

  • 服务优雅上下线

  • 服务调用负载均衡

  • 服务接口隔离

03



Service Mesh 化模式




Service Mesh 是在服务化架构的基础上,引入了一个专门的网络代理层,负责处理服务间的通信。这减轻了应用程序的负担,提供了更好的可观测性、安全性和流量管理。

Service Mesh,服务网格,是专用的基础结构层,主要用于保障服务之间安全、快速和可靠的通信。

  • Service Mesh 是基础设施层,在某些场景下可能要与其他基础设施交互,比如基础网络、PaaS 平台、运维系统等

  • Service Mesh 可用于解决个服务之间的通信问题,服务之间通信机制比较复杂,包括通信协议、负载均衡等,因此 Service Mesh 是能够支持多种协议的适配,同时能够支持相关的特性,比如负载均衡等

  • Service Mesh 是安全、快速和可靠的


Service Mesh 包括三种模式:


1
模式一:Sidecar 模式


 

核心流程

  • Service A 要与 Service B 通信, Sidecar 要求双方首先与应用侧的 Envoy 连接

  • 在发起服务间调用时,服务消费者 Service A 首先将服务调用请求发送给自己的 Envoy 代理人

  • Service B 的 Envoy 代理人再将请求转发给正式服务提供者 Service B,完成服务的调用

  • 服务调用的响应结果顺着原路返回


优势

  • 服务路由和可靠性:应用不再需要关心网络细节,比如目标 IP、端口或者网络变更相关的

  • 隔离性和安全性:代理处理连接池、超时和安全问题,比如用户名、密码和密钥管理,从而提高应用的安全性

  • 为应用减负:代理可以处理协议转换等任务,减轻应用的负担

  • 服务调研的可观测性:通过代理,可以更容易地收集日志、跟踪链路和 Metrics,从而提高系统的可观测性


问题和挑战

  • 对 Kubernetes 的依赖:在非 Kubernetes 系统上开发和运维成本高,如果基础设施层没有使用 Kubernetes 则不建议使用该模式

  • 性能损失和资源浪费:代理的引入可能会增加网络延迟和资源消耗,在大规模系统中是一个问题

  • 开发成本增加:代理的存在可能增加系统的复杂性,需要额外的工具和管理系统来支持开发和测试


Service Mesh 架构典型的技术方案基本还是基于 Istio + Envoy 的 Sidecar 模式,随着 K8S 在基础设施层的日益普及,已经逐渐接受和采纳该模式。当前各大云厂商都提供了基于 K8S 一键初始化 Istio 服务的能力,降低了使用的门槛。


2
模式二:服务注册和发现模式

在微服务架构中,服务注册与发现模式是一种核心架构模式,它使得微服务能够动态地找到并调用其他服务。这一模式在 Spring Cloud 等框架中得到了广泛应用,但其实质并不仅限于特定的技术栈或平台。



服务注册

每个微服务实例在启动时,都会将自己的网络地址、端口号、健康检查URL等信息注册到一个中央服务注册中心。这个过程通常对开发者是透明的,只需要通过简单的配置或注解就能完成。在 Spring Cloud 中,Eureka、Consul 和 Etcd 等都是常用的服务注册中心产品。服务注册中心负责维护一个实时的服务实例列表,包括每个服务实例的网络地址、端口号、健康状态等信息。当服务实例发生变化时(如新增、下线、宕机等),服务注册中心会及时更新这个列表,以确保其准确性。

服务发现

在微服务架构中,服务之间的调用是动态的,因此需要一种机制来发现目标服务的位置。这就是服务发现的作用。当一个微服务需要调用另一个微服务时,它会向服务注册中心查询目标服务的实例列表,然后选择一个合适的实例进行调用。在 Spring Cloud 中,这个过程也是透明的。开发者只需要通过注解或配置启用服务发现功能,然后像调用本地方法一样调用远程服务即可。Spring Cloud 会自动处理服务发现、负载均衡等底层细节。

服务调用的透明性

Spring Cloud 等框架通过注解、配置和代码生成等技术,实现了服务调用的透明性。开发者只需要关注业务逻辑,而不需要关心底层的服务发现、负载均衡等细节。这使得微服务架构更加易于使用和维护。

服务治理

除了基本的服务注册与发现功能外,Spring Cloud 等框架还提供了丰富的服务治理功能,如断路器、限流、熔断、重试等。这些功能可以帮助开发者更好地管理和维护微服务架构,确保其稳定性和可用性。

多语言支持

虽然 Spring Cloud 等框架在Java生态中得到了广泛应用,但它们并不限于 Java 语言。通过跨语言的技术和标准,这些框架也可以支持其他编程语言构建的微服务。当然,对于非 Java 生态的语言,可能需要更多的工作来集成和使用这些框架。


3
模式三:中心化 Broker 模式

中心化 Broker 模式是一种重要的通信模式。该模式通过引入一个中心的 Broker 来协调服务间的通信,从而简化了服务间的交互,提高了系统的可扩展性和可维护性。



中心化 Broker 模式的核心思想是将所有的服务调用请求都通过一个中心的 Broker 进行转发。当服务消费者需要调用一个服务时,它只需将服务请求发送给中心的 Broker,然后 Broker 会从已连接的服务提供者列表中找到能够处理该请求的服务提供者,并将请求转发给它。服务提供者处理完请求后,将结果返回给 Broker,再由 Broker 将结果返回给服务消费者。

优势

  • 无端口监听:在传统的服务提供者模式中,每个服务都需要在本地启动一个监听端口来接收来自其他应用的服务请求。而在中心化 Broker 模式中,服务提供者主动连接到 Broker,无需监听端口,从而提高了系统的安全性

  • 无网络要求:中心化 Broker 模式不要求通信双方网络互通,只要通信各方能够连接到 Broker 即可进行通信。这降低了网络配置的复杂性,使得不同网络环境中的应用可以轻松地互相通信

  • 无底层设施依赖:中心化 Broker 模式对基础设施没有特殊要求,只要有一台能够运行 Broker 的服务器,并且网络可达即可。这使得该模式可以灵活地支持各种基础设施,如经典 VM、Kubernetes 等

  • 无服务注册依赖,无负载均衡要求:在中心化 Broker 模式中,Broker 本身承担了服务注册和负载均衡的功能。服务提供者只需连接到 Broker,无需关心如何注册服务和进行负载均衡。这简化了服务间的交互,降低了系统的复杂性

  • 简化运维:中心化 Broker 模式将大量的终端代理简化为几台高性能的 Broker 服务器,从而简化了系统的运维和管理

此外,中心化 Broker 模式还具有集中权限认证、集中化的安全证书、集中化的流量管控等优势。这些特点使得中心化 Broker 模式在微服务架构中具有广泛的应用前景。

挑战与解决方案

尽管中心化 Broker 模式具有诸多优势,但也面临着一些挑战。其中最主要的挑战是异步化架构和协议适配问题。

  • 异步化架构:为了支持高并发和大规模的服务调用,Broker 必须采用异步化的架构设计。这要求 Broker 能够高效地处理大量的并发请求,而不会因为阻塞而影响系统性能。解决方案是采用事件循环(EventLoop)和 Actor 模式等异步处理技术,以提高系统的吞吐量和响应速度。

  • 协议适配和单点故障:应用之间的通信协议多种多样,Broker 需要适配这些协议以支持不同的服务调用。如果协议处理不当,可能会导致 Broker 不稳定、性能下降甚至单点故障。解决方案是采用可扩展的协议适配机制,如基于插件的协议适配器,以便灵活地支持各种通信协议。同时,通过集群部署和容错机制来提高 Broker 的可用性和可靠性。

RSocket与中心化Broker模式的结合

RSocket 是一种异步二进制消息通信协议,具有连接复用、多种通信模型和扩展性等特点。它与中心化 Broker 模式的结合为微服务架构提供了一种高效、灵活和可靠的通信方案。

在 RSocket Broker 典型的通信场景中,所有微服务都作为 RSocket Client 连接到中心化的 RSocket Broker 集群上。服务调用请求通过 RSocket 协议发送给 Broker,然后 Broker 根据服务路由表将请求转发给相应的服务提供者。处理完毕后,结果再由 Broker 返回给服务调用方。整个过程完全异步化,提高了系统的处理能力和资源利用率。

此外,RSocket 协议还支持多种主流编程语言,使得开发者可以灵活地选择适合自己业务场景的技术栈。同时,RSocket Broker 产品也在不断发展壮大中,为微服务架构提供了更多的选择和支持。

总之,中心化 Broker 模式通过引入一个中心的 Broker 来协调服务间的通信,简化了服务间的交互过程并提高了系统的可扩展性和可维护性。而 RSocket 作为一种异步二进制消息通信协议与中心化Broker模式的结合为微服务架构提供了一种高效、灵活和可靠的通信方案。

04



Serverless 模式



Serverless,意为“无服务器”,但实际上并不是没有服务器,而是指开发者在构建和运行应用时无需关心服务器的运维和管理。在 Serverless 架构中,云平台负责提供应用运行所需的所有服务器资源,并根据应用的实际需求动态分配资源。这种模式的定价基于应用的实际资源消耗,为开发者提供了一种高效、灵活且经济的方式来部署和运行应用。


1
 特点
  • 按需付费:开发者只需为实际使用的资源付费,无需提前购买或预留计算资源

  • 自动弹性伸缩:云平台根据应用的负载自动调整资源分配,确保应用在高负载时依然能够稳定运行

  • 简化的运维:开发者无需关心环境配置、容量规划和运维操作等,可以专注于应用的开发

  • 事件驱动:Serverless 应用通常以函数的形式部署,并由事件触发执行


2
  架构组件
  • FaaS(函数即服务):云平台提供的函数执行环境,开发者可以在其中部署和运行自己的函数

  • 存储服务:用于保存应用的状态和数据,通常由云平台提供的 KV 存储、数据库等服务提供

  • API 网关:处理应用的网络请求和响应,将请求路由到相应的函数执行环境

  • 监控和日志:提供应用的性能和故障诊断信息,帮助开发者了解应用的运行状况


3
  部署流程
  • 开发者编写应用代码,包括前端界面和后端逻辑代码

  • 使用云平台提供的命令行工具或控制台将代码部署到FaaS平台

  • 配置应用的网络访问、存储服务等

  • 测试应用的功能和性能

  • 上线应用,并根据实际访问量调整资源配置


4
   优势
  • 降低成本:按需付费和自动弹性伸缩可以显著降低计算资源的浪费和成本

  • 提高效率:简化的运维和事件驱动的开发模式可以提高开发者的效率和应用的响应速度

  • 易于扩展:应用可以轻松应对突发的高负载,而无需进行复杂的容量规划和扩容操作


5
   挑战
  • 冷启动问题:当函数长时间未被调用时,再次调用可能需要较长的启动时间

  • 状态管理:由于函数是无状态的,因此需要考虑如何有效地管理应用的状态和数据

  • 调试和监控:在 Serverless 环境中,应用的调试和监控可能更加复杂和困难


05



 计算存储分离模式



在计算机体系结构中,计算和存储是两大核心组件。但在分布式系统中,为了增强系统的可伸缩性、可用性和容错性,经常需要将这两者进行分离。这种分离主要源于无状态和有状态应用架构的区别。


1
 无状态应用架构

在此架构中,服务请求与特定的服务器无关。即使请求涉及数据处理,数据也是从外部源(如数据库)获取的,而不是存储在处理请求的服务器上。这种架构简化了系统的设计和部署,并增强了系统的可伸缩性。


2
 有状态应用架构

有状态应用架构中的请求与特定的服务器是相关的。例如,用户的会话数据可能存储在服务器的内存中,或者多个相互关联的请求可能依赖于服务器上的中间状态。这种架构增加了系统的复杂性,尤其是在处理分布式存储和高可用性时。


3
 优势
  • 简化系统设计:通过将存储逻辑从应用逻辑中分离出来,可以简化应用的设计和开发

  • 提高可伸缩性:无状态应用可以更容易地在多个服务器上进行水平扩展,而无需担心状态数据的同步问题

  • 增强可用性:在出现故障时,无状态应用可以更快地恢复,因为它们不依赖于特定的服务器或存储在服务器上的状态

  • 快速迁移和恢复:无状态应用架构的新实例可以迅速启动并投入生产,无需长时间的初始化过程


4
  云环境中的计算与存储分离

在云环境中,计算和存储的分离变得尤为重要。云厂商提供了各种存储解决方案,如 KV 存储、分布式缓存、文件存储、文件系统挂载和块服务等。这些解决方案不仅解决了海量存储和数据备份的问题,还帮助实现了无状态应用架构。

虽然无状态应用架构具有许多优势,但有些应用场景仍需要有状态组件。在云原生架构中,应用可以将这些有状态部分(如会话数据、业务基础数据等)委托给云平台来管理,从而使应用本身能够专注于计算。


05



 分布式事务模式



在采用微服务架构的场景中,我们面临着如何确保跨越多个微服务的数据一致性的问题。由于每个微服务通常使用独立的数据库,传统的事务管理机制不再适用。因此,我们需要采用分布式事务来确保数据在多个服务之间保持一致。以下是几种主要的分布式事务模式:


1
 2PC
  • 这是一种经典的分布式事务协议,其中事务的提交分为两个阶段

  • 它依赖于一个全局事务管理器来协调所有参与者

  • 优点:简单、直观

  • 缺点:同步阻塞、单点故障、潜在的数据不一致风险


2
 BASE
  • BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)的缩写

  • 它强调即使无法做到强一致性,系统也应根据业务特点达到最终一致性

  • 优点:提高系统的可用性和响应速度

  • 缺点:需要业务层面的妥协和权衡


3
 TCC
  • TCC 将事务的提交过程分为 Try、Confirm 和 Cancel 三个阶段

  • 它要求参与者实现这三个接口的相应逻辑

  • 优点:避免了资源长时间锁定,提高了并发性能

  • 缺点:编程复杂度高,需要业务层面的支持和配合


4
 Saga                        
  • Saga 是一种补偿协议,通过一系列正向服务和逆向回滚服务来保证事务的一致性

  • 它基于事件驱动,服务间异步通信

  • 优点:高性能、灵活、适用于长事务

  • 缺点:缺乏隔离性,可能导致数据覆盖问题


5
 AT
  • AT 是阿里巴巴提出的一种无侵入的分布式事务模式

  • 它利用本地事务的 ACID 特性和 Undo Log 机制来实现分布式事务

  • 优点:简单易用、高性能、广泛适用

  • 缺点:需要中间件框架的支持,可能存在时序问题

06



 可观测模式



在现代的分布式系统和微服务架构中,了解系统的内部运行状态和性能至关重要。这就是可观测性(Observability)的核心所在。可观测性赋予了我们深入洞察系统运行情况的能力,尤其在系统出现错误或异常时,我们能够迅速收集到相关数据来进行故障诊断和性能优化。这种能力类似于飞机上的黑匣子(Flight Recorder),即使在飞机失事的情况下,也能记录并保存关键数据以供后续分析。

为了实现可观测性,我们主要依赖于三种技术手段:日志(Logging)、度量(Metrics)和追踪(Tracing)。


1
 日志

日志是记录系统运行状态和事件的最基本方式。通过日志,我们可以了解系统在特定时间点的详细操作和信息。为了有效管理日志,我们通常会设置不同的日志级别(如debug、error、info等),并根据开发、测试和生产等环境的需求开启相应的日志级别。此外,现代的日志处理系统(如ElasticStack)和云服务商提供的日志服务使得日志的采集、存储和分析变得更加简便。


2
 度量

度量是对系统性能和业务状态的量化表示。它不仅包括技术指标(如CPU负载、内存使用量),还包括业务度量(如每分钟的交易额、每分钟会员登录数等)。度量数据通常以聚合的形式展现,如平均值、累计值等,这有助于我们了解系统的整体性能和趋势。与日志不同,度量数据更关注于某一时间窗口内的统计信息,因此更适合用于性能监控和预警。

在设计度量系统时,我们需要考虑度量指标的命名、采集时间点、数值类型、标签等因素。同时,利用云服务商提供的度量服务(如阿里云的Prometheus服务),我们可以轻松地实现度量数据的采集、存储、监控和告警等功能。


3
 追踪

在分布式系统中,一个请求可能涉及多个服务和组件。为了了解请求在整个系统中的处理过程和性能瓶颈,我们需要使用追踪技术。追踪系统通过生成唯一的追踪链(TraceId)和区间(SpanId),将请求在不同服务和系统中的操作信息串联起来。这样,我们就可以根据追踪链的详细信息,定位问题所在并进行优化。

为了实现追踪,我们需要在应用中进行适当的埋点,以记录关键操作的信息。同时,利用追踪系统(如Zipkin)和相应的SDK(如Brave SDK),我们可以实现追踪数据的采集和展示。追踪数据的异步上报和事件流订阅等机制可以确保数据采集的实时性和高效性。


4
 事件流订阅

除了日志、度量和追踪外,事件流订阅是另一种实现可观测性的技术手段。它通过在应用中定义和触发事件,并使用户能够实时订阅这些事件来获取系统的运行状态和性能信息。与日志和度量相比,事件流订阅更加灵活和实时,可以根据用户的需求随时开启和关闭。Java飞行记录器(JFR)就是一种基于事件流订阅的可观测性工具,它提供了丰富的事件类型和实时分析能力,有助于我们更好地了解Java 应用的性能和状态。


06



 事件驱动模式



事件驱动架构模式是一种基于事件进行通信的架构设计模式。在这种模式中,事件的生成、捕获、通信、监听处理以及持久化都是核心的结构组件。与面向对象设计和函数式编程等基于 API 调用的模式相比,事件驱动架构采用了松耦合的方式,事件的生成源并不需要知道哪些系统正在监听这些事件,同时事件本身也不知道自己所产生的结果。尽管事件驱动架构对结果的处理存在不确定性,但它仍然被广泛应用于分布式应用架构中。这主要是因为事件驱动架构提供了松耦合和异步化的能力,使得系统更加灵活和可扩展。


1
 事件

在事件驱动架构中,事件是对发生在过去某一时间点的状态变化的记录。事件是不可改变的,只读的,并包含了发生的时间、类型以及承载的数据信息。为了描述事件,有一些标准的规范,如CloudEvents,它提供了一种统一的格式来描述事件。


2
 事件的生成和消费

事件的生成和消费是事件驱动架构中的关键概念。一旦事件生成,它会被发布出去,供感兴趣的事件消费者订阅和处理。不同的事件消费者可以根据事件的类型和来源来选择性地处理事件。

在事件驱动架构中,事件的异步通信是通过消息系统来实现的。事件本身没有路由信息,而是依赖于消息机制将事件封装起来,并添加路由信息,如目标 Topic 等。通过消息系统的异步通信能力,事件可以可靠地传递给消费者,并实现持久化、推送等功能。


3
 数据变更捕获

数据变更捕获是事件驱动架构中的一个重要应用场景。当数据发生变化时,可以捕获这些变化并触发相应的事件。这些事件可以被不同的订阅方用来触发业务流程节点执行、数据同步等操作。通过数据变更捕获和事件驱动模式,可以实现数据的最终一致性,并解决分布式系统中的数据同步问题。

4
 读写分离

读写分离是事件驱动架构的另一个重要应用场景。通过将读和写的操作分离到不同的服务中,可以提高系统的可用性和扩展性。写服务负责完成数据的持久化,并通过触发事件将变更通知给相关订阅方。读服务则通过订阅这些事件来完成数据的索引化和查询操作。通过读写分离,可以实现读和写操作的解耦,提高系统的整体性能。


07



 网关模式




网关,作为统一接入层,是处理南北流向网络请求的核心组件,它负责将来自浏览器、手机移动端或合作伙伴等的访问流量高效、安全地转发至相应的业务系统。在大型系统或微服务架构中,网关的作用尤为重要,因为它能实现统一入口管理,包括统一域名和安全证书、流量统计、限流和防攻击等功能。倘若这些功能直接由各个微服务应用来承担,不仅会给微服务应用带来沉重的负担,还会显著增加系统的维护复杂性。


网关在应对流量挑战方面也扮演着关键角色。由于所有流量都需经过网关,因此网关必须具备高可靠性、高并发支持能力以及低延迟等特性。多数网关会选择使用 Nginx 这款高性能的 Web 服务器作为 HTTP 网关。值得注意的是,在许多云厂商的服务中,网关并非免费提供,用户需要支付额外的费用以享受这一服务。


此外,网关还具备负载均衡的功能。例如,Spring 云网关通过与 Service Registry 的对接,能够利用服务发现机制自动实现负载均衡。云厂商提供的网关服务通常也内置了自动负载均衡功能,这也是其收费的原因之一。


在进行网关设计时,我们通常会根据实际需求对网关进行分类。例如,HTTP 网关专注于处理来自浏览器的网络请求;API 网关则主要负责 API 调用,包括 HTTP REST 网关和 gRPC 网关;而移动端的 Mobile 网关则专门处理来自手机移动端的请求。这种划分方式有助于使网关的职责更加明确和聚焦,同时也便于针对不同类型的网关进行技术开发、安全管控、扩容和运维等操作。

08



 混沌工程模式



混沌工程是一种旨在通过主动引入故障和不确定性来验证系统弹性的方法。它不同于传统的测试和验证手段,后者往往侧重于在可控环境中模拟正常情况下的系统行为。相反,混沌工程故意在系统中注入故障,以观察系统在异常情况下的响应和恢复能力。

这种方法的核心理念是“预防胜于治疗”。通过主动暴露系统的弱点,混沌工程帮助我们更早地发现潜在问题,并在实际影响用户之前修复它们。这种方法特别适用于复杂系统,如微服务架构和分布式系统,这些系统往往由许多相互依赖的组件组成,任何一个组件的故障都可能对整个系统造成严重影响。

混沌工程的实施通常包括以下几个步骤:

  • 首先,确定要测试的系统组件和场景

  • 其次,设计和执行故障注入实验,以模拟各种异常情况

  • 然后,观察系统的响应,并记录任何异常行为

  • 最后,分析实验结果,确定系统的弱点,并制定相应的修复和改进措施

混沌工程的价值在于它提供了一种更加真实和全面的系统验证方法。通过模拟实际环境中可能发生的各种故障情况,我们可以更准确地评估系统的可靠性和稳定性。此外,混沌工程还有助于培养团队的应急响应能力和协作精神,因为在处理故障时,往往需要多个团队密切合作,共同解决问题。

尽管混沌工程可能会带来一些挑战和风险,但它的好处是显而易见的。通过主动引入故障并验证系统的恢复能力,我们可以更加自信地保证系统在遇到实际问题时能够迅速而有效地恢复正常运行,从而为用户提供更加可靠和稳定的服务。


09



 声明式模式



声明式设计模式,又称为声明式编程范式,是一种编程方法,其核心思想在于描述所需达到的目标状态,而非详细规定达成该状态的具体步骤或过程。这种方法与命令式编程形成鲜明对比,后者关注于明确地指示计算机如何执行每一步操作。声明式设计带来了诸多优势,同时也伴随着一系列挑战。


1
 优势
  • 可读性增强:声明式设计通常采用领域特定语言(DSL),这种语言更接近自然语言的表达方式,使得代码更易于非专业人士阅读和理解

  • 代码简洁性:由于声明式设计聚焦于描述结果状态,而非实现细节,因此代码量通常较小,逻辑也更为清晰简洁

  • 高度复用性:声明式设计的目标是描述所需结果,而非执行流程。这意味着相同的声明可以在不同上下文中重复使用,无需修改,从而提高了代码的复用率

  • 幂等性保障:在声明式设计中,系统负责确保操作的幂等性,即无论操作执行多少次,结果都保持一致。这减轻了开发人员在数据一致性方面的负担

  • 错误恢复机制:声明式设计强调结果的正确性,对于执行过程中出现的异常和错误,系统负责进行恢复和处理,无需开发人员干预

  • 透明性:声明式设计对用户隐藏了底层技术细节,使用户能够专注于业务逻辑,而无需深入了解系统实现。


2
 实际

声明式设计模式在现代软件开发中得到了广泛应用。例如,在 Kubernetes 这样的容器编排系统中,用户通过声明式配置文件(如YAML文件)定义所需的资源状态和配置,而 Kubernetes 负责根据这些声明自动管理和调度容器。类似地,在基础设施即代码(IaC)领域,声明式设计允许开发人员通过代码描述所需的基础设施配置,然后由工具自动部署和管理这些基础设施。


3
 挑战

尽管声明式设计带来了许多好处,但它也面临着一系列挑战:

  • 高度抽象要求:为了提供简洁的声明式接口,系统需要进行高度的抽象,这可能增加系统内部的复杂性和开发难度

  • DSL设计挑战:设计易于理解和使用的DSL是一项复杂的任务,需要平衡表达能力与简洁性

  • 可观测性问题:由于声明式设计对用户隐藏了底层细节,这可能导致在系统出现问题时难以进行调试和排查

  • 服务提供者负担增加:声明式设计将复杂性转移到了服务提供者一方,要求他们处理更多的内部逻辑和异常情况



灸哥送福利

闲暇之余,把之前的设计模式专题的文章整合成了一篇完整的 PDF 文档,免费奉送给大家,方便统一学习和阅读。

【领取方式】

点击上方蓝字关注“灸哥漫谈”,聊天窗口回复“设计模式”,就会获取到具体的下载链接,自行获取哦!






原文作者:灸哥漫谈;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2023-11-26

  • 博文量
    368
  • 访问量
    173351