分布式系统 - 服务治理 - 介绍

这系列文章会系统的说说一些服务治理的技术点,例如:限流、降级、熔断、隔离、路由 & 负载均衡、服务注册 & 发现 等等。又由于作者还没对分布式系统有啥全局的把握,所以只能逐点逐点的学习分析,对于已经掌握的,就暂时不再重复总结了。

服务化

服务化 / 微服务 这些概念被炒作得热火朝天,具体的是非争议,这里都不讨论。

最简化的一句话版本:服务化就是将原来部署在同一个项目的代码,分拆成不同的可以独立部署的项目之中。

而在这系列文章的关注点下,服务化的特点是:原来在一个进程,干所有事,现在是分布到不同的进程,由这些进程协同完成。这是一切的问题的起点。因为这涉及进程间通信,而不同的进程又可以部署在不同的机器上,涉及网络,每多一个环节,都增加出错的可能性。

调用 / 通信

服务化的过程上文已经说了,通常是一个大项目,分拆成若干个小项目。在初级阶段,这些小项目的相互调用可以通过URL来进行HTTP + JSON的RPC调用。

但当服务越来越多时,服务间的依赖错综复杂,这种调用方式会非常混乱。特别是,一个服务模块可以由多个实例提供服务,如果用nginx做为反向代理,会出现单点问题。

这时,需要引入服务调用框架,来封装这些复杂的RPC调用,包括服务治理的功能。以下的技术点,都是对这个服务框架的需求。

服务路由 & 负载均衡

我们可以把分布式中的一次跨服务的调用,还原成一个使用TCP/IP协议的网络请求。而TCP/IP协议需要指定正确的IP + port。也就是说,要发起调用,调用方本身必须知道服务提供方的IP + 端口地址。

这种需求在大规模的分布式系统里会变得非常复杂:

一是由于服务间依赖错综复杂,这些信息该如何有效率的存储;

二是无论是服务提供方还是服务调用方都是以集群的形式、甚至是多个 集群 的性质出现,而IP + 端口是 节点 层面的路由信息;

三是在运行时,所有集群都有可能动态伸缩,当要在一个集群里踢掉一台机,或者新增一台机(也就是节点)时,该怎样使流量流进 / 流出这个节点?

服务路由 & 负载均衡,讨论的就是如何解决这些问题的。

服务注册 & 发现

服务路由和负载均衡的前置条件是:有服务可路由。系统中必然需要有地方保存这些IP和端口。还有各种问题:

  • 一个分布式系统里是怎样获得各个集群里的节点的信息的?
  • 这些节点的健康状况怎么维护和更新。
  • 怎么零配置的上线一个服务而被其他服务发现?

零配置或低配置得让一个上线的节点被集群发现,就是服务发现。

限流

假设这个服务框架已经成型并投入使用,它的职责不仅仅是满足服务间的调用,还有服务治理的功能。服务治理的目的是维持系统高可用高稳定。

限流是其中一个对服务框架的需求:它的需求显而易见:允许一个服务 / 集群直接声明这个服务 / 集群能承载的并发上限,从而:

  • 保护集群本身的资源,防止一波大流量过来,把整个集群调挂了。
  • 或者保护集群的核心资源,例如数据库。

限流的核心思路是,当整个系统的并发数超过阈值,宁愿放弃掉一部分请求,也要保住集群。使正常范围内(阈值以下)的流量得到正确处理。这个思路会在下面多次用到。

降级 & 熔断

在应用系统中,我们通常会去调用远程的服务或者资源(这些服务或资源通常是来自第三方),对这些远程服务或者资源的调用通常会导致失败,

或者挂起没有响应,直到超时的产生。在一些极端情况下,大量的请求会阻塞在对这些异常的远程服务的调用上,会导致一些关键性的系统资源耗尽,

从而导致级联的失败,从而拖垮整个系统。熔断器模式在内部采用状态机的形式,使得对这些可能会导致请求失败的远程服务进行了包装,

当远程服务发生异常时,可以立即对进来的请求返回错误响应,并告知系统管理员,将错误控制在局部范围内,从而提高系统的稳定性和可靠性。

隔离

服务化的更多关键词

关键词:

  • cascading failure

参考

  • 《分布式服务框架原理与实践》
  • 《亿级流量网站架构核心技术》
  • http://microservices.io/patterns/
  • https://www.nginx.com/blog/microservices-at-netflix-architectural-best-practices/