微服务架构实践之服务注册发现与调用

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

引子

在上篇文章中我们简单回顾了我们服务器端架构的演变过程 从而引出了微服务,面向服务的架构体系 从而也带来了新的问题就是服务之间的如何相互调用,服务如何注册与发现的问题

服务调用方式

我们先来了解一下服务之间如何调用,在Java领域通常有几种方式

  1. 使用Tcp或者Http实现通信 跨平台

  2. RMI (Remote Method Invocation) 远程方法调用 只支持Java 客户机与服务器强耦合 不推荐使用

  3. WebService
    跨平台 通过Http实现通信 复杂度较高 传统SOA使用较多

  4. MQ (Message Queue)消息队列 跨平台 完全隔离了客户端和服务提供者 通常异步使用

综合以上几种方案的特点我们会选择使用使用Http或者Tcp的协议来完成RPC(同步) 和MQ(异步)来实现我们的服务调用

对于Java系统的内部调用而言我们可使用Tcp来提高性能, 而对于外面接口统一使用Http的形式,如果对性能要求不高也可以直接使用Http的形式 对于以后系统的异构化更方便和统一

服务发现与注册

我们有了服务间调用的机制,但是 我还需要知道另一个服务的地址我们才能调用, MQ没有这种烦恼直接发送到消息中间件里就可以了, 但是RPC就不行了难道直接在代码里写死吗如果有多个实例呐? 这时候我们最常用的方法是使用集中式的负载均衡来解决

微服务架构实践之服务注册发现与调用_第1张图片

集中式LB方案实现简单,在LB上也容易做集中式的访问控制 集中式LB的主要问题是单点问题,所有服务调用流量都经过LB, 当服务数量和调用量大的时候,LB容易成为瓶颈, 且一旦LB发生故障对整个系统的影响是灾难性的 另外,LB在服务消费方和服务提供方之间增加了跳转,有一定性能开销

这里我们通常是使用nginx代理来实现的, 但是服务实例的网络位置都是动态分配的,而且因为扩展,失效和升级等需求, 服务实例会经常动态改变,因此也需要使用一种更加复杂的服务发现机制。

既然如此我们就引出了我们的服务注册的概念

*服务注册**是服务发现很重要的部分,他是包含服务实例网络地址的数据库 服务注册需要高可用而且随时更新,客户端可以缓存从服务注册表获得的网络地址 然而,这些信息最终会变得过时,客户端也无法发现服务实例 因此,服务注册由若干使用复制协议保持同步的服务器构成 我们使用类似Zookeeper之类具有分布式的强一致性的key/value数据库来实现

服务注册与发现有下面几种模式

  • 客户端模式

微服务架构实践之服务注册发现与调用_第2张图片 服务实例的网络地址在启动时注册到服务注册中心中,并且在服务终止时从注册表中删除 服务实例注册信息一般是使用心跳机制来定期刷新

客户端模式的LB方案是一种分布式方案,LB和服务发现能力被分散到每一个服务消费者的进程内部,同时服务消费方和服务提供方之间是直接调用,没有额外开销,性能比较好。但是,该方案以库的方式集成到服务调用方进程里头,如果企业内有多种不同的语言栈,就要配合开发多种不同的客户端,有一定维护成本

  • 主机独立LB进程方案

微服务架构实践之服务注册发现与调用_第3张图片

该方案是针对客户端模式的不足而提出的一种折中方案,原理和第二种方案基本类似,不同之处是,他将LB和服务发现功能从进程内移出来,变成主机上的一个独立进程,主机上的一个或者多个服务要访问目标服务时,他们都通过同一主机上的独立LB进程做服务发现和负载均衡 通过这种形式就解决了与服务模块耦合的问题方便升级和维护

总结

目前在微服务中使用更多的是客户端发现的模式 使用的案例有Netflix的开源服务框架,对应的组件分别是:Eureka服务注册表,Karyon服务端框架支持服务自注册和健康检查,Ribbon客户端框架支持服务自发现和软路由 另外,阿里开源的服务框架Dubbo也是采用类似机制

转载于:https://my.oschina.net/jayqqaa12/blog/899028

你可能感兴趣的:(微服务架构实践之服务注册发现与调用)