微服务的架构次要包含服务形容、服务发现、服务调用、服务监控、服务追踪以及服务治理这几个根本组件。
那么每个根本组件从架构和代码设计上该如何实现?组件之间又是如何串联来实现一个残缺的微服务架构呢?明天我就以开源微服务框架 Dubbo 为例来给你具体解说这些组件。
服务公布与援用
服务公布与援用的三种罕用形式:RESTful API、XML 配置以及 IDL 文件,其中 Dubbo 框架次要是应用 XML 配置形式。
首先来看服务公布的过程,上面这段代码是服务提供者的 XML 配置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方利用信息,用于计算依赖关系 -->
<dubbo:application name="hello-world-app" />
<!-- 应用 multicast 播送注册核心裸露服务地址 -->
<dubbo:registry address="multicast://127.0.0.1:3435" />
<!-- 用 dubbo 协定在 20880 端口裸露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 申明须要裸露的服务接口 -->
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" />
<!-- 和本地 bean 一样实现服务 -->
<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />
</beans>
其中“dubbo:service”结尾的配置项申明了服务提供者要公布的接口,“dubbo:protocol”结尾的配置项申明了服务提供者要公布的接口的协定以及端口号。
Dubbo 会把以上配置项解析成上面的 URL 格局:
dubbo://host-ip:20880/com.alibaba.dubbo.demo.DemoService
而后基于扩大点自适应机制,通过 URL 的“dubbo://”协定头辨认,就会调用 DubboProtocol 的 export() 办法,关上服务端口 20880,就能够把服务 demoService 裸露到 20880 端口了。
再来看下服务援用的过程,上面这段代码是服务消费者的 XML 配置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 生产方利用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer-of-helloworld-app" />
<!-- 应用 multicast 播送注册核心裸露发现服务地址 -->
<dubbo:registry address="multicast://127.0.0.1:3435" />
<!-- 生成近程服务代理,能够和本地 bean 一样应用 demoService -->
<dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" />
</beans>
其中“dubbo:reference”结尾的配置项申明了服务消费者要援用的服务,Dubbo 会把以上配置项解析成上面的 URL 格局:
dubbo://com.alibaba.dubbo.demo.DemoService
而后基于扩大点自适应机制,通过 URL 的“dubbo://”协定头辨认,就会调用 DubboProtocol 的 refer() 办法,失去服务 demoService 援用,实现服务援用过程。
服务注册与发现
先来看下服务提供者注册服务的过程,持续以后面服务提供者的 XML 配置为例,其中“dubbo://registry”结尾的配置项申明了注册核心的地址,Dubbo 会把以上配置项解析成上面的 URL 格局:
registry://multicast://127.0.0.1:3435/com.alibaba.dubbo.registry.RegistryService?export=URL.encode("dubbo://host-ip:20880/com.alibaba.dubbo.demo.DemoService")
而后基于扩大点自适应机制,通过 URL 的“registry://”协定头辨认,就会调用 RegistryProtocol 的 export() 办法,将 export 参数中的提供者 URL,注册到注册核心。
再来看下服务消费者发现服务的过程,同样以后面服务消费者的 XML 配置为例,其中“dubbo://registry”结尾的配置项申明了注册核心的地址,跟服务注册的原理相似,Dubbo 也会把以上配置项解析成上面的 URL 格局:
registry://multicast://127.0.0.1:3435/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode("consummer://host-ip/com.alibaba.dubbo.demo.DemoService")
而后基于扩大点自适应机制,通过 URL 的“registry://”协定头辨认,就会调用 RegistryProtocol 的 refer() 办法,基于 refer 参数中的条件,查问服务 demoService 的地址。
服务调用
在服务调用的过程中,通常把服务消费者叫作客户端,服务提供者叫作服务端,发动一次服务调用须要解决四个问题:
- 客户端和服务端如何建设网络连接?
- 服务端如何解决申请?
- 数据传输采纳什么协定?
- 数据该如何序列化和反序列化?
其中前两个问题客户端和服务端如何建设连贯和服务端如何解决申请是通信框架要解决的问题,Dubbo 反对多种通信框架,比方 Netty 4,须要在服务端和客户端的 XML 配置中增加上面的配置项。
服务端:
<dubbo:protocol server="netty4" />
客户端:
<dubbo:consumer client="netty4" />
这样基于扩大点自适应机制,客户端和服务端之间的调用会通过 Netty 4 框架来建设连贯,并且服务端采纳 NIO 形式来解决客户端的申请。
再来看下 Dubbo 的数据传输采纳什么协定。Dubbo 不仅反对公有的 Dubbo 协定,还反对其余协定比方 Hessian、RMI、HTTP、Web Service、Thrift 等。上面这张图形容了公有 Dubbo 协定的协定头约定。
至于数据序列化和反序列方面,Dubbo 同样也反对多种序列化格局,比方 Dubbo、Hession 2.0、JSON、Java、Kryo 以及 FST 等,能够通过在 XML 配置中增加上面的配置项。
例如:
<dubbo:protocol name="dubbo" serialization="kryo"/>
服务监控
服务监控次要包含四个流程:数据采集、数据传输、数据处理和数据展现,其中服务框架的作用是进行埋点数据采集,而后上报给监控零碎。
在 Dubbo 框架中,无论是服务提供者还是服务消费者,在执行服务调用的时候,都会通过 Filter 调用链拦挡,来实现一些特定性能,比方监控数据埋点就是通过在 Filter 调用链上配备了 MonitorFilter 来实现的。
服务治理
服务治理伎俩包含节点治理、负载平衡、服务路由、服务容错等,上面这张图给出了 Dubbo 框架服务治理的具体实现。
图中的 Invoker 是对服务提供者节点的形象,Invoker 封装了服务提供者的地址以及接口信息。
- 节点治理:Directory 负责从注册核心获取服务节点列表,并封装成多个 Invoker,能够把它看成“List<Invoker>”,它的值可能是动态变化的,比方注册核心推送变更时须要更新。
- 负载平衡:LoadBalance 负责从多个 Invoker 中选出某一个用于发动调用,抉择时能够采纳多种负载平衡算法,比方 Random、RoundRobin、LeastActive 等。
- 服务路由:Router 负责从多个 Invoker 中按路由规定选出子集,比方读写拆散、机房隔离等。
- 服务容错:Cluster 将 Directory 中的多个 Invoker 伪装成一个 Invoker,对下层通明,假装过程蕴含了容错逻辑,比方采纳 Failover 策略的话,调用失败后,会抉择另一个 Invoker,重试申请。
一次服务调用的流程
下面我讲的是 Dubbo 下每个根本组件的实现形式,那么 Dubbo 框架下,一次服务调用的流程是什么样的呢?
首先我来解释微服务架构中各个组件别离对应到下面这张图中是如何实现。
- 服务公布与援用:对应实现是图里的 Proxy 服务代理层,Proxy 依据客户端和服务端的接口形容,生成接口对应的客户端和服务端的 Stub,使得客户端调用服务端就像本地调用一样。
- 服务注册与发现:对应实现是图里的 Registry 注册核心层,Registry 依据客户端和服务端的接口形容,解析成服务的 URL 格局,而后调用注册核心的 API,实现服务的注册和发现。
- 服务调用:对应实现是 Protocol 近程调用层,Protocol 把客户端的本地申请转换成 RPC 申请。而后通过 Transporter 层来实现通信,Codec 层来实现协定封装,Serialization 层来实现数据序列化和反序列化。
- 服务监控:对应实现层是 Filter 调用链层,通过在 Filter 调用链层中退出 MonitorFilter,实现对每一次调用的拦挡,在调用前后进行埋点数据采集,上传给监控零碎。
- 服务治理:对应实现层是 Cluster 层,负责服务节点治理、负载平衡、服务路由以及服务容错。
再来看下微服务架构各个组件是如何串联起来组成一个残缺的微服务框架的,以 Dubbo 框架下一次服务调用的过程为例,先来看下客户端发动调用的过程。
- 首先依据接口定义,通过 Proxy 层封装好的透明化接口代理,发动调用。
- 而后在通过 Registry 层封装好的服务发现性能,获取所有可用的服务提供者节点列表。
- 再依据 Cluster 层的负载平衡算法从可用的服务节点列表中选取一个节点发动服务调用,如果调用失败,依据 Cluster 层提供的服务容错伎俩进行解决。
- 同时通过 Filter 层拦挡调用,实现客户端的监控统计。
- 最初在 Protocol 层,封装成 Dubbo RPC 申请,发给服务端节点。
这样的话,客户端的申请就从一个本地调用转化成一个近程 RPC 调用,通过服务调用框架的解决,通过网络传输达到服务端。其中服务调用框架包含通信协议框架 Transporter、通信协议 Codec、序列化 Serialization 三层解决。
服务端从网络中接管到申请后的处理过程是这样的:
- 首先在 Protocol 层,把网络上的申请解析成 Dubbo RPC 申请。
- 而后通过 Filter 拦挡调用,实现服务端的监控统计。
- 最初通过 Proxy 层的解决,把 Dubbo RPC 申请转化为接口的具体实现,执行调用。
总结
明天咱们讲述了 Dubbo 服务化框架每个根本组件的实现形式,以及一次 Dubbo 调用的流程。
对于学习微服务架构来说,最好的形式是去理论搭建一个微服务的框架,甚至去从代码动手做一些二次开发 。
本文由 mdnice 多平台公布