微服务的架构次要包含服务形容、服务发现、服务调用、服务监控、服务追踪以及服务治理这几个根本组件。
那么每个根本组件从架构和代码设计上该如何实现?组件之间又是如何串联来实现一个残缺的微服务架构呢?明天我就以开源微服务框架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多平台公布