微服务架构设计

Keywords: #技术 #Golang #微服务
Release Date: 2025-03-01

从单体应用架构到微服务架构的演进,以及微服务结构需要解决的问题有哪些?

在微服务架构兴起前,单体架构一度是主流选择。在微服务出现后,通常更适合使用 Golang 和 Java 语言进行开发。

常见的单体应用以如图所示的结构部署,但只能应对 10 - 100 人的应用场景,因系统并发性能不足,一旦用户量增加,系统就可能面临巨大压力。

image.png

此外,单体应用在开发时还面临诸多痛点,特别是代码管理方面问题突出。

如下图示,多组团队对同一单体项目进行功能更新或 BUG 修复时,代码管理复杂度陡增。

image.png

举例来说,程序员 A 和 B 为上线新功能 A 而修改代码,测试通过后,却发现程序员 C 和 D 已对原项目进行修改并上线新功能 B,导致多分支代码难以合并,即使解决了冲突还需回归测试。

同时,单体项目代码不能轻松升级工具版本,新功能加入如网站增小程序,需大量新代码,难复用原有的代码。这是因同步更新需求和功能扩展时,单体架构的代码和数据库设计,无法满足多方面的需求和灵活性。

因此,大型项目的开发应该满足以下需求:

  1. 代码复用:避免重复开发,提高开发效率。
  2. 系统间相互调用便捷:支持不同系统之间的协作和交互。
  3. 内外服务兼备的接口:既能对外提供服务,又可满足内部需求。
  4. 不断增加新功能,数据库性能不被影响:保障业务稳定。
  5. 数据库拆分升级,避免多服务依赖绑定:提高数据管理和升级的灵活性和可靠性。
  6. 服务接口质量保障:防止一个服务的接口问题影响其他服务。
  7. 开发测试部署简便:减少复杂度和提升效率。

针对以上需求,微服务的提出,就可以很好的解决这一系列痛点。


常见项目的架构设计,是将各种服务独立成单独的模块,但是这样依然不够,数据库层面没有被拆分开,各模块依赖了同一个数据库。并且各个服务模块之间相互调用也十分困难。

image.png

为了将数据库服务进一步隔离,可以继续将架构进行拆分,即拆分为微服务架构,每个服务都对应一个数据库和缓存,里面存放着属于该服务的数据,如果其他服务需要该数据,则不是直接连接该数据库,而是通过内部的调用 API 来查询信息,如订单服务通过 API 接口查询商品数据。还可以利用 MQ 消息队列,对服务进行解耦(MQ 是常用的服务解耦工具)。

image.png

这样一来,就可以将每个服务拆分开,每个服务的功能升级或者数据库更新都不会影响到其他服务,只需要保证对其他服务公开的接口不更改,其他服务就不会受影响,他们都是独立运行的。这也可以避免代码管理困难,代码冲突的问题。


这其中还有一个问题,就是各个服务模块暴露出的 API 接口,不仅需要对内部的其他服务提供服务,并且还需要对外部的小程序、网站等系统提供服务。然而外部的系统一般使用 http 协议进行传输和请求,但是 http 协议却不适合作为内部传输的协议,它的性能并不高。

因此,我们希望服务模块暴露的这个接口,对外通过 http 协议提供服务,对内使用其他高性能的协议(TCP)提供服务。这时就可以引入 RPC 了。我们可以根据这也的需求进一步设计一个分层的微服务架构。如下如所示。

image.png

SRV 服务层对内提供各种服务端的 RPC 接口,而 WEB 服务层将内部的 RPC 接口进行整合,对外部提供 http 的 API 接口。

下层(SRV 层)可以通过 RPC 接口互相调用,上层(WEB 层)可以调用下层提供的 RPC 服务,但是下层绝对不可以通过 http 接口去调用上层的服务!

这样分层的微服务架构还提供了一个好处,就是 RPC 服务可以使用不同的编程语言代码完成,这也是使用 RPC 的好处。并且组件可以随意,版本可以不同,体现了微服务的独立性。

我们习惯于将 srv 层的 RPC 接口写得更加通用一些,把开发重点放在 web 层如何对外提供合适的服务。


上面说了这么多微服务架构的优点,实际上,使用微服务同样也存在着很多需要解决的问题。

在大型项目中,如果使用微服务结构,那就可能会存在成百上千个微服务模块,对于大量的微服务,它们甚至有可能部署在不同的服务器中(分布式集群),因此,管理好每个微服务对外的 IP 和端口十分重要,同时也需要关注每个微服务的运行情况是否健康。

image.png

所以,我们需要一个注册中心,当我们每写完一个服务,就要向注册中心完成注册,注册中心会给这些服务分配 IP 和端口,并定时检查这些服务的健康程度。

还需要一个服务发现,当 web 层服务需要查找一个 srv 层商品查询的服务,它会返回给服务对应的 IP 和端口,供 web 层服务调用。

还要有一个配置中心,用于管理大量微服务的配置信息,当一个微服务的配置需要进行修改时,可以统一通过配置中心完成。每个微服务启动时,都会到配置中心中读取对应的配置信息,以完成正确启动。

此外,还有一个链路追踪功能,用于追踪整个服务调用的过程,当服务出现性能问题时,可以通过该功能,查找是哪里出现问题(日志打印),从而解决它。

在对外 http 的 API 接口外,还要有一个微服务网关(nginx 也行)用于统一所有的对外 API 接口,并分配对应的 IP 端口,起到路由功能(根据域名访问端口)。当网站请求一个域名时,微服务网关通过注册中心查找对应的服务,并将请求路由给对应的 API 接口。它还需要有一个鉴权的功能,先拦截一些无效请求,保护后端服务。最后,它还需要有熔断的功能,当后端服务繁忙时,直接取消请求。

以上这些都是微服务结构需要解决的问题。