软市(www.iruanshi.com) - 正版软件商城_企服市场!
产品分类 自营

解决分布式系统中的挑战,从容应对复杂性

解决分布式系统中的挑战,从容应对复杂性

终身学习、乐于分享、共同成长!😀

  • 一、前言
  • 二、服务的高可用场景
  • 三、解决方案
  • 四、总结

前言

你知道构建分布式系统会遇到哪些问题吗?

分布式系统是一种分散在多台计算机上的软件系统,它可以提供更高的可用性、可扩展性和可靠性。它们可以支持大规模的数据处理和分析,并且可以更有效地利用计算资源。然而,分布式系统也存在一些挑战,这些挑战可能会影响系统的可用性、可靠性和性能。

首先,分布式系统中的节点可能会出现故障。这可能是由于硬件故障、软件故障或网络故障引起的。这些故障可能会导致系统不可用,或者会影响系统的性能。因此,系统设计者必须考虑如何有效地处理故障,以确保系统的可用性和可靠性。

其次,分布式系统中的节点可能会出现不一致的状态。这是由于网络延迟、节点故障或其他原因引起的。这种不一致可能会导致系统出现不可预料的行为,从而影响系统的可靠性。因此,系统设计者必须考虑如何有效地处理不一致,以确保系统的可靠性。

此外,分布式系统中的节点可能会出现负载不均衡的情况。这是由于节点之间的网络延迟、节点之间的负载不均衡或其他原因引起的。这种负载不均衡可能会导致系统的性能下降,从而影响系统的可用性。因此,系统设计者必须考虑如何有效地处理负载不均衡,以确保系统的可用性。

最后,分布式系统中的节点可能会出现安全漏洞。这可能是由于系统设计不当、软件缺陷或恶意攻击引起的。这些安全漏洞可能会导致系统的数据泄露或损坏,从而影响系统的可靠性。因此,系统设计者必须考虑如何有效地处理安全漏洞,以确保系统的可靠性。

总之,分布式系统中存在许多挑战,这些挑战可能会影响系统的可用性、可靠性和性能。因此,系统设计者必须考虑如何有效地处理这些挑战,以确保系统的可用性、可靠性和性能。

具体问题如下图:

解决分布式系统中的挑战,从容应对复杂性

服务的可用性场景

在微服务架构中,我们实现的业务逻辑通常需要依赖多个微服务协同完成,以经典的商城服务为例,如下图:

解决分布式系统中的挑战,从容应对复杂性

上图是在正常流量下的健康状态,但如果其中的某个服务(比如积分服务)由于某些原因宕机了,这时就会出现线程池里所有线程都因等待响应而被阻塞, 从而造成整个服务链路不可用, 进而导致整个系统的服务雪崩. 如图所示:

解决分布式系统中的挑战,从容应对复杂性

什么是服务雪崩效应?

服务雪崩效应是指当一个服务出现故障时,由于服务之间的依赖关系,导致其他服务也出现故障,从而形成一个“雪崩”效应。这种效应可能会导致系统的瘫痪,从而影响到系统的正常运行。

以上图举例,在并发较大的情况下下,积分服务挂掉了,这样在商品服务调用积分服务的时候就会被卡住,这样就会导致商品服务挂掉,当商品服务挂掉,订单服务也会挂掉,从而导致秒杀商品整个链路都挂掉,而且因为商品服务挂掉,就会导致商品详情,购物车等链路都挂掉,最终导致整个服务全部挂掉。

导致服务不可用的原因:

解决分布式系统中的挑战,从容应对复杂性

在服务提供者不可用的时候,会出现大量重试的情况:用户重试、代码逻辑重试,这些重试最终导致:进一步加大请求流量。所以归根结底导致雪崩效应的最根本原因是:大量请求线程同步等待造成的资源耗尽。当服务调用者使用同步调用时, 会产生大量的等待线程占用系统资源。一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 于是服务雪崩效应产生了。

解决方案

如何解决?

要解决服务不可用的问题,通常会从两个维度着手。

  • 提升系统稳定性(Reliability)
  • 降低系统恢复时长(Resilience)

本文主要针对提升系统稳定性对微服务进行一些容错设计。

常见的容错机制

超时机制

在不做任何处理的情况下,服务提供者不可用会导致消费者请求线程强制等待,而造成系统资源耗尽。加入超时机制,一旦超时,就释放资源。由于释放资源速度较快,一定程度上可以抑制资源耗尽的问题。

比如在Nacos注册中心、我们使用feign作为服务通信的时候就可以设置服务连接超时时间和服务处理超时时间。

服务限流

服务限流技术是用于限制系统中的服务访问量,以避免系统负载过大而导致的性能问题。它可以限制特定的客户端或服务器的访问量,以确保系统的可用性和可靠性。

比如我们通过压测,可以知道服务可以承受的最大连接数,如果不做限制,那么服务就会被压垮,但是我们如果设置了服务限流,那么超过的请求我们就可以限制禁止访问服务,比如提示用户服务繁忙,稍后重试。这样至少可以保证服务的可用性。

解决分布式系统中的挑战,从容应对复杂性

隔离

隔离可分为:

  • 服务线程隔离

服务线程隔离技术是用于将不同服务的线程隔离开来,以防止一个服务的线程池中的线程影响另一个服务的线程池中的线程。这样,即使一个服务的线程池中的线程出现问题,也不会影响另一个服务的线程池中的线程。

比如在商品详情服务中需要调用到商品服务、价格服务、评论服务,比如设定商品服务线程池中有100个线程,那么我们就可以设定商品服务(20个线程)、价格服务(30个线程)、评论服务(20个线程),如果某一个服务的线程池已满,则会进行降级处理,用户的请求不会被阻塞,至少可以看到一个执行结果(例如返回友好的提示信息),而不是无休止的等待或者看到系统崩溃。

解决分布式系统中的挑战,从容应对复杂性

  • 信号隔离

信号隔离也可以用于限制并发访问,防止阻塞扩散, 与线程隔离最大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请, 如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销。信号量的大小可以动态调整, 线程池大小不可以。

信号隔离其实就等同于服务限流。

服务熔断

服务熔断是一种服务保护机制,它可以在出现服务故障时,自动地将服务从系统中断开,以防止故障扩散,保护系统的稳定性。

当服务出现故障时,服务熔断机制会自动将服务从系统中断开,以防止故障扩散,保护系统的稳定性。当服务恢复正常时,服务熔断机制会自动将服务恢复到系统中,以恢复正常的服务。

现实世界的断路器大家肯定都很了解,断路器实时监控电路的情况,如果发现电路电流异常,就会跳闸,从而防止电路被烧毁。

软件世界的断路器可以这样理解:实时监测应用,如果发现在一定时间内失败次数/失败率达到一定阈值,就“跳闸”,断路器打开——此时,请求直接返回,而不去调用原本调用的逻辑。跳闸一段时间后(例如10秒),断路器会进入半开状态,这是一个瞬间态,此时允许一次请求调用该调的逻辑,如果成功,则断路器关闭,应用正常调用;如果调用依然不成功,断路器继续回到打开状态,过段时间再进入半开状态尝试——通过”跳闸“,应用可以保护自己,而且避免浪费资源;而通过半开的设计,可实现应用的“自我修复“。

所以,同样的道理,当依赖的服务有大量超时时,再让新的请求去访问根本没有意义,只会无畏的消耗现有资源。比如我们设置了超时时间为1s,如果短时间内有大量请求在1s内都得不到响应,就意味着这个服务出现了异常,此时就没有必要再让其他的请求去访问这个依赖了,这个时候就应该使用断路器避免资源浪费。

解决分布式系统中的挑战,从容应对复杂性

服务降级

服务降级是指在系统出现异常时,为了保证系统的稳定性,降低系统的服务质量,以减少系统的负载,从而缓解系统压力的一种技术手段。服务降级的实现方式有:限流、降级、熔断等。

当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。例如:(备用接口/缓存/mock数据) 。

这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。

比如在秒杀场景,积分服务挂了,我们就可以使用服务降级来保证核心流程还可以继续访问。但是如果商品服务挂了或者库存服务挂了,这样就会影响到核心业务的处理,就不能使用服务降级了。

总结

  • 使用微服务架构构建的分布式系统可以提高系统的高可用性、扩展性与可靠性,这是分布式系统的优势。
  • 但要实现分布式系统的高可用性&可靠性需要面临很多的挑战,如:硬件故障、软件故障、网络故障、程序bug等等,这非常考验系统设计者如何有效地处理这些故障,以确保系统的可用性和可靠性。
  • 在微服务架构下常见的系统容错机制包括超时机制、隔离机制、服务限流、服务熔断、服务降级等。
  • 接下来将重点介绍Sentinel在这些容错机制上的具体实现及应用。

 

发表回复

登录后才能评论
客服