01.2、分布式系统的复杂性
分布式系统的复杂性
本节将学习:服务间调用的复杂性、故障定位的困难、性能优化的挑战。这些问题在单体架构中可能很简单,但在分布式系统中就变得非常复杂。
服务间调用的复杂性
在单体架构中,所有的模块都在同一个进程中,调用就是函数调用,非常快,非常简单。
但是在微服务架构中,服务间调用就变得复杂了。为什么呢?
第一个问题是调用链深度增加。
一个用户请求,从前端到后端,可能要经过 API Gateway、User Service、Product Service、Order Service、Payment Service,每个服务可能还要调用数据库、缓存、消息队列。一个请求可能经过 10+ 个服务。
这些服务间还有复杂的依赖关系。User Service 依赖数据库,Product Service 依赖缓存和数据库,Order Service 依赖多个服务。这个依赖关系图会变得非常复杂,难以理解。
第二个问题是网络延迟累积。
在单体架构中,模块间调用是进程内的,几乎没延迟。但是在分布式系统中,每个服务调用都有网络延迟。例如,每个服务调用延迟 10ms,10 个服务就是 100ms。如果某个服务延迟更高,整体响应就会变得很慢。而且,很难知道具体是哪个服务慢。
第三个问题是超时和重试。
服务调用可能会超时。网络可能不稳定,服务可能暂时不可用。这时候就需要重试机制。但是重试可能会造成重复请求,例如,一个订单可能被创建两次,这就带来了新的问题。
第四个问题是服务发现和负载均衡。
在分布式系统中,服务可能有很多实例。如何找到这些服务?如何分配负载?这就需要服务发现机制和负载均衡。配置管理就变得非常复杂。
这就是分布式系统带来的复杂性。
故障定位的困难
在单体架构中,如果出了问题,可能只需要查看一个应用的日志,问题相对简单。
但是在分布式系统中,故障定位就变得非常困难。为什么呢?
第一个问题是问题可能发生在任何环节。
用户投诉说订单创建失败,问题可能在哪里呢?可能是前端有问题,可能是后端 API 有问题,可能是数据库有问题,可能是网络有问题。任何服务都可能出问题,而且问题可能涉及多个服务。
例如,如果 User Service 调用超时,可能是因为 User Service 本身慢,也可能是因为数据库慢,也可能是因为网络慢。很难知道到底是哪里出了问题。
第二个问题是调试信息分散。
每个服务都有自己的日志。需要登录多个服务器,查看多个日志文件,手动拼凑出问题的图景。这个过程非常耗时,而且容易出错。
而且,不同服务的日志格式可能不统一。有些服务用 JSON 格式,有些服务用文本格式。很难统一处理这些日志。
第三个问题是时间同步问题。
不同服务器的时钟可能不同步。看到的日志时间戳可能不准确。这就难以确定事件的先后顺序,难以关联相关事件。
第四个问题是上下文信息丢失。
请求在各个服务间传递,上下文信息可能丢失。例如,用户 ID、订单 ID、Trace ID 这些信息,如果不在每个服务间传递,就会丢失。就难以追踪完整的请求路径。
这就是为什么在分布式系统中,故障定位这么困难。
性能优化的挑战
在单体架构中,可以直接看到代码的执行路径。知道哪个函数慢,可以直接优化。
但是在分布式系统中,性能优化就变得非常困难。为什么呢?
第一个挑战是无法直观看到完整调用链。
不知道请求经过了哪些服务,不知道每个服务耗时多少,不知道哪个服务是瓶颈。就像盲人摸象一样,只能看到一部分,看不到全貌。
例如,用户投诉说 API 响应慢,响应时间是 2 秒。但是不知道这 2 秒花在哪里了。
是前端渲染慢?是 API Gateway 慢?是某个服务慢?是数据库查询慢?不知道。
第二个挑战是瓶颈点难以识别。
性能问题可能出现在任何服务。需要分析大量的性能数据,从 Metrics、Traces、Logs 中找出问题。这个过程非常耗时,而且容易出错。
而且,即使找到了问题,也难以确定优化方向。例如,发现数据库查询慢,但是不知道是查询语句的问题,还是索引的问题,还是数据量的问题。
第三个挑战是优化效果难以量化。
不知道优化前的性能基线,不知道优化后的性能提升是多少。就难以证明优化的价值,难以说服老板投入资源去优化。
这就是为什么在分布式系统中,性能优化这么困难。
本节小结
在本节中,我们学习了分布式系统带来的三个主要复杂性:
第一个是服务间调用的复杂性。 调用链深度增加,网络延迟累积,超时和重试,服务发现和负载均衡。这些问题在单体架构中不存在,但在分布式系统中就变得非常复杂。
第二个是故障定位的困难。 问题可能发生在任何环节,调试信息分散,时间同步问题,上下文信息丢失。传统的方法很难快速定位问题。
第三个是性能优化的挑战。 无法直观看到完整调用链,瓶颈点难以识别,优化效果难以量化。优化变得盲目,效果不明显。
这些复杂性是分布式系统固有的,无法避免。但是,可以通过可观察性来解决这些问题。
在下一节,我们将看看可观察性如何解决这些复杂性,以及它带来的实际价值。