服务治理
服务治理可以说是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册与发现.
那么为什么需要服务治理呢?
举个例子,某个系统在最初开始构建微服务系统的时候可能服务并不多,我们可以通过做一些静态配置来完成服务的调用.
比如,有两个服务 A 和 B, 其中服务 A 需要调用服务 B来完成一个业务操作时,为了实现服务 B 的高可用,不论采用服务端负载均衡还是客户端负载均衡,都需要手工维护服务 B 的具体实例清单.
但是随着业务的发展,系统功能越来越复杂,相应的
微服务应用也不断增加,我们的静态配置就会变得越来越难以维护.并且面对不断发展的业务,我们的集群规模,服务的位置, 服务的命名等都有可能发生变化,如果还是通过手
工维护的方式,那么极易发生错误或是命名冲突等问题.同时,对于这类静态内容的维护也必将消耗大量的人力.
通过服务注册和服务发现来完成对微服务应用实例的自动化管理
服务注册
在服务治理框架中,通常都会构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机和端口号,版本号,通信协议等一些附加信息告知注册中心,注册中心按服务名分类,组织服务清单.
比如,我们有两个提供服务A的进程分别运行于192.168.0.100:8000和192.168.0.101:8000位置上,另外还有三个提供服务B的进程分别运行于192.168.0.100:9000,192.168.0.101:9000,192.168.0.102:9000位置上.当这些进程均启动,并向注册中心注册自己的服务之后,注册中心就会维护类似下面的一个服务清单.
服务名 | 位置 |
---|---|
服务A | 192.168.0.100:8000,192.168.0.101:8000 |
服务B | 192.168.0.100:9000,192.168.0.101:9000,192.168.0.102:9000 |
另外,服务注册中心还需要以心跳的方式去监测清单中的服务是否可用,若不可用,需要从服务清单中剔除,达到排除故障服务的效果.
服务发现
由于在服务治理框架下运作,服务间的调用不再通过指定具体的实例地址来实现,而是通过向服务名发起请求调用实现.
所以,服务调用方在调用服务提供方接口的时候,并不知道具体的服务实例位置.因此,调用方需要向服务注册中心咨询服务,并获取所有服务的实例清单,以实现对具体服务实例的访问.
比如,现有服务C希望调用服务A,服务C就需要向注册中心发起咨询服务请求,服务注册中心就会将服务A的位置清单返回给服务C,比如按上个例子中服务A的情况,C便获得了服务A的两个可用位置192.168.0.100:8000和192.168.0.101:8000.当服务C要发起调用的时候,便从该清单中以某种轮询策略取出一个位置来进行服务调用,这就是后续我们将会介绍的客户端负载均衡.这里我们只是列举了一种简单的服务治理逻辑,以方便理解服务治理框架的基本运行思路. 实际的框架为了性能等因素, 不会采用每次都向服务注册中心获取服务的方式.
不同的应用场景在缓存和服务剔除等机制上也会有一些不同的实现策略.
Netflix Eureka
Eureka是Netflix开发的服务发现框架,Spring Cloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能.
为什么要使用Eureka ?
因为在一个完整的系统架构中,任何单点的服务都不能保证不会中断,因此我们需要服务发现机制,在某个节点中断后,其它的节点能够继续提供服务,从而保证整个系统是高可用的.
服务发现有两种模式:一种是客户端发现模式,一种是服务端发现模式.Erueka采用的是客户端发现模式.
Eureka Server会提供服务注册服务,各个服务节点启动后,会在Eureka Server中进行注册,这样Eureka Server中就有了所有服务节点的信息,并且Eureka有监控页面,可以在页面中直观的看到所有注册的服务的情况.
同时Eureka有心跳机制,当某个节点服务在规定时间内没有发送心跳信号时,Eureka会从服务注册表中把这个服务节点移除.
Eureka还提供了客户端缓存的机制,即使所有的Eureka Server都挂掉,客户端仍可以利用缓存中的信息调用服务节点的服务.
Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka中读取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载.
Eureka通过心跳检测、健康检查、客户端缓存等机制,保证了系统具有高可用和灵活性.