分布式系统的中枢Naming-Service

  另外有一部分服务则通过手动添加的方式来注册。这一部分主要是用到的一些开源软件,修改他们的成本比较高,索性就不改,采用手动添加就好了(这就是偷懒 ^_^)。而这部分服务占比很小,所以手动的成本也不高。

  B 、服务可用性如何保证?

  那既然 Naming-Service 承担了服务注册和获取的责任,那么服务的可用性如何保证呢?老王设计的时候, Naming-Service 专门有一个服务功能:健康检查。 Naming-Service 会定期的检查服务是否存活(主要是 socket 的可连接性),以及是否可以提供服务( ping 检查 - 这个老王偷懒了没做 ~ ),这个是配置的,一般是秒级(因为调用者一般都是有重试,所以这个时间差还是可以接受的)。如果健康检查多次以后,服务仍然不可用,则出现服务报警,同时, Naming-Service 会将出问题的机器从可用服务列表中摘除。这样保证服务列表在绝大多数情况下都是可用的。

  C 、单点如何解决?

  从之前的拓扑图可以看到,我们的 Naming-Service 是星形结构的中心结点。如果这个服务挂掉了,我们的整个系统就瘫痪了,对吧。那我们如何解决这个中心结点的单点问题呢?

  老王用了几个手段:

  a 、服务的多机化 + 存储的主从化:

物联网

  Naming-Service 提供一个服务组(多个 IP 配置到服务列表中),如果某一台挂掉了,请求服务可以重试其他 Naming-Service 。

  同时,后台的数据存储用的是数据库主从的方式,即使有库挂掉了,也还有其他备份库可以使用。

  b 、定期重复注册。

  刚刚将注册方式的时候,也讲到这个问题。即使所有数据库都挂掉了(比如:机房光纤挖断了),那我能够很快的搭建好另外一个数据库,通过定期重复注册的方式,迅速恢复服务。

  c 、本地备份 service-list 。

  在客户端有一个功能,就是请求完 Naming-Service 以后,会在本地生成一份最新请求下来的服务列表(自动的)。如果我们的 Naming-Service 遭到毁灭性打击(比如:所在的机房断电了),我们本地还有一份最近的服务列表,可以直接使用。

  通过上述几种方式,基本上能保证我们服务不会出现问题。

  其实还有另外一些实现方式:比如 Naming-Service 之间通过一些广播协议(比如:gossip 等)将注册信息进行广播,各自存储一份信息,而不采用数据库集群的方式。也可以让客户端向所有的 Naming-Service 广播自己的注册信息,而每个 Naming-Service 也是独自保留自己的信息等等方式。

  3 、应用场景

  Naming-Service 在几百台、几千台机器的体系架构中其实是蛮好的一个解决方案。如果再大规模,如几万、十几万台机器的规模下是否适合,老王就不得而知了(因为没有那么多机器去实验,不过老王觉得其实也可以通过拆分系统,化整为零来解决)。

  不过现在也有很多系统,使用了去中心化的设计思想。比如: memcache 就是通过客户端做一致 hash 的方式,来避免中心化的结点。 redis 好像有自己的一套分布式去中心化的方案。这些方案都是可行的。

 

  在分布式体系架构中,没有一种最完美的方案,只有更适合自己的方案。所以,今天老王抛了一种方案给大家,供大家在平时工作中来选择。