www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 單片機 > 架構師社區(qū)
[導讀]I作者:vivo互聯(lián)網(wǎng)服務器團隊-WangGenfu一、Dubbo分層整體設計概述我們先從下圖開始簡單介紹Dubbo分層設計概念:(引用自Duboo開發(fā)指南-框架設計文檔)如圖描述Dubbo實現(xiàn)的RPC整體分10層:service、config、proxy、registry、cl...

I作者:vivo互聯(lián)網(wǎng)服務器團隊-Wang Genfu

一、Dubbo分層整體設計概述


我們先從下圖開始簡單介紹Dubbo分層設計概念:


源碼解讀Dubbo分層設計思想

(引用自Duboo開發(fā)指南-框架設計文檔


如圖描述Dubbo實現(xiàn)的RPC整體分10層:service、config、proxy、registry、cluster、monitor、protocol、exchange、transport、serialize。


  • service:使用方定義的接口和實現(xiàn)類;

  • config:負責解析Dubbo定義的配置,比如注解和xml配置,各種參數(shù);

  • proxy:主要負責生成消費者和提供者的代理對象,加載框架功能,比如提供者過濾器鏈,擴展點;

  • registry:負責注冊服務的定義和實現(xiàn)類的裝載;

  • cluster:只有消費者有這么一層,負責包裝多個服務提供者成一個‘大提供者’,加載負載均衡、路有等擴展點;

  • monitor:定義監(jiān)控服務,加載監(jiān)控實現(xiàn)提供者;

  • protocol:封裝RPC調(diào)用接口,管理調(diào)用實體的生命周期;

  • exchange:封裝請求響應模式,同步轉(zhuǎn)異步;

  • transport:抽象傳輸層模型,兼容netty、mina、grizzly等通訊框架;

  • serialize:抽象序列化模型,兼容多種序列化框架,包括:fastjson、fst、hessian2、kryo、kryo2、protobuf等,通過序列化支持跨語言的方式,支持跨語言的rpc調(diào)用;


Dubbo這么分層的目的在于實現(xiàn)層與層之間的解耦,每一層都定義了接口規(guī)范,也可以根據(jù)不同的業(yè)務需求定制、加載不同的實現(xiàn),具有極高的擴展性。


1.1. RPC調(diào)用過程


接下來結(jié)合上圖簡單描述一次完整的rpc調(diào)用過程:


Dubbo分層的角度看,詳細時序圖如下,藍色部分是服務消費端,淺綠色部分是服務提供端,時序圖從消費端一次Dubbo方法調(diào)用開始,到服務端本地方法執(zhí)行結(jié)束。


源碼解讀Dubbo分層設計思想


Dubbo核心領域?qū)ο蟮慕嵌瓤?,我們引?span>Dubbo官方文檔說明,如下圖所示。Dubbo核心領域?qū)ο笫荌nvoker,消費端代理對象是proxy,包裝了Invoker的調(diào)用;服務端代理對象是一個Invoker,他通過exporter包裝,當服務端接收到調(diào)用請求后,通過exporter找到Invoker,Invoker去實際執(zhí)行用戶的業(yè)務邏輯。


源碼解讀Dubbo分層設計思想

(引用自Dubbo官方文檔)


1.2 Dubbo服務的注冊和發(fā)現(xiàn)流程


下圖出自開發(fā)指南-框架設計-引用服務時序,主要流程是:從注冊中心訂閱服務提供者,然后啟動tcp服務連接遠端提供者,將多個服務提供者合并成一個Invoker,用這個Invoker創(chuàng)建代理對象。


源碼解讀Dubbo分層設計思想


下圖出自開發(fā)指南-框架設計-暴露服務時序,主要流程是:創(chuàng)建本地服務的代理Invoker,啟動tcp服務暴露服務,然后將服務注冊到注冊中心。


源碼解讀Dubbo分層設計思想


接下來我們結(jié)合Dubbo服務的注冊和發(fā)現(xiàn),從配置層開始解釋每一層的作用和原理。


示例服務接口定義如下:

public interface CouponServiceViewFacade { /** * 查詢單張優(yōu)惠券 */ CouponViewDTO query(String code);}

二、配置層


2.1. 做什么


配置層提供配置處理工具類,在容器啟動的時候,通過ServiceConfig.export實例化服務提供者,ReferenceConfig.get實例化服務消費者對象。


Dubbo應用使用spring容器啟動時,Dubbo服務提供者配置處理器通過ServiceConfig.export啟動Dubbo遠程服務暴露本地服務。Dubbo服務消費者配置處理器通過ReferenceConfig.get實例化一個代理對象,并通過注冊中心服務發(fā)現(xiàn),連接遠端服務提供者。


Dubbo配置可以使用注解和xml兩種形式,本文采用注解的形式進行說明。


2.2. 怎么做


2.2.1 服務消費端的解析


Spring容器啟動過程中,填充bean屬性時,對含有Dubbo引用注解的屬性使用

org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor進行初始化。


如下是

ReferenceAnnotationBeanPostProcessor的構造方法,Dubbo服務消費者注解處理器處理以下三個注解:

DubboReference.class,?

Reference.class,?

com.alibaba.dubbo.config.annotation.Reference.class修飾的類。


ReferenceAnnotationBeanPostProcessor類定義:

public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBeanPostProcessor implements ApplicationContextAware { public ReferenceAnnotationBeanPostProcessor() { super(DubboReference.class, Reference.class, com.alibaba.dubbo.config.annotation.Reference.class); }}

Dubbo服務發(fā)現(xiàn)到這一層,Dubbo即將開始構建服務消費者的代理對象,

CouponServiceViewFacade接口的代理實現(xiàn)類。


2.2.2 服務提供端的解析


Spring容器啟動的時候,加載注解

@org.apache.dubbo.config.spring.context.annotation.DubboComponentScan指定范圍的類,并初始化;初始化使用dubbo實現(xiàn)的擴展點

org.apache.dubbo.config.spring.beans.factory.annotation.ServiceClassPostProcessor。


ServiceClassPostProcessor處理的注解類有

DubboService.class,Service.class,com.alibaba.dubbo.config.annotation.Service.class。


如下是ServiceClassPostProcessor類定義:

public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, ResourceLoaderAware, BeanClassLoaderAware { private final static List> serviceAnnotationTypes = asList( DubboService.class,Service.class,com.alibaba.dubbo.config.annotation.Service.class );。。。}

等待Spring容器ContextRefreshedEvent事件,啟動Dubbo應用服務監(jiān)聽端口,暴露本地服務。


Dubbo服務注冊到這一層,Dubbo即將開始構建服務提供者的代理對象,CouponServiceViewFacade實現(xiàn)類的反射代理類。


三、?代理層


3.1 做什么


為服務消費者生成代理實現(xiàn)實例,為服務提供者生成反射代理實例。


CouponServiceViewFacade的代理實現(xiàn)實例,消費端在調(diào)用query方法的時候,實際上是調(diào)用代理實現(xiàn)實例的query方法,通過他調(diào)用遠程服務。

//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)// package org.apache.dubbo.common.bytecode; public class proxy1 implements DC, Destroyable, CouponServiceViewFacade, EchoService { public static Method[] methods; private InvocationHandler handler; public proxy1(InvocationHandler var1) { this.handler = var1; } public proxy1() { } public CouponViewDTO query(String var1) { Object[] var2 = new Object[]{var1}; Object var3 = this.handler.invoke(this, methods[0], var2); return (CouponViewDTO)var3; }}

CouponServiceViewFacade的反射代理實例,服務端接收到請求后,通過該實例的Invoke方法最終執(zhí)行本地方法query。

/** * InvokerWrapper */public class AbstractProxyInvoker implements Invoker { // 。。。 public AbstractProxyInvoker(CouponServiceViewFacade proxy, Class type, URL url) { //。。。 this.proxy = proxy; this.type = type; this.url = url; } @Override public Result invoke(Invocation invocation) throws RpcException { //。。。 Object value = doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments()); //。。。 } protected Object doInvoke(CouponServiceViewFacade proxy, String methodName, Class[] parameterTypes, Object[] arguments) throws Throwable{ //。。。 return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments); } }

3.2 怎么做


Dubbo代理工廠接口定義如下,定義了服務提供者和服務消費者的代理對象工廠方法。服務提供者代理對象和服務消費者代理對象都是通過工廠方法創(chuàng)建,工廠實現(xiàn)類可以通過SPI自定義擴展。

@SPI("javassist")public interface ProxyFactory { // 生成服務消費者代理對象 @Adaptive({PROXY_KEY}) T getProxy(Invoker invoker) throws RpcException; // 生成服務消費者代理對象 @Adaptive({PROXY_KEY}) T getProxy(Invoker invoker, boolean generic) throws RpcException; // 生成服務提供者代理對象 @Adaptive({PROXY_KEY}) Invoker getInvoker(T proxy, Class type, URL url) throws RpcException; }

3.2.1 服務消費者


3.2.1.1 創(chuàng)建服務消費者代理類


默認采用Javaassist代理工廠實現(xiàn),Proxy.getProxy(interfaces)創(chuàng)建代理工廠類,newInstance創(chuàng)建具體代理對象。

public class JavassistProxyFactory extends AbstractProxyFactory { @Override @SuppressWarnings("unchecked") public T getProxy(Invoker invoker, Class[] interfaces) { return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker)); } 。。。 }

3.2.1.2 服務消費者代理


Dubbo為每個服務消費者生成兩個代理類:代理工廠類,接口代理類。


CouponServiceViewFacade代理工廠類:

public class Proxy1 extends Proxy implements DC { public Proxy1() { } public Object newInstance(InvocationHandler var1) { return new proxy1(var1); }}

最終生成的CouponServiceViewFacade的代理對象如下,其中handler的實現(xiàn)類是InvokerInvocationHandler,

this.handler.invoke方法發(fā)起Dubbo調(diào)用。

//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)// package org.apache.dubbo.common.bytecode; public class proxy1 implements DC, Destroyable, CouponServiceViewFacade, EchoService { public static Method[] methods; private InvocationHandler handler; public proxy1(InvocationHandler var1) { this.handler = var1; } public proxy1() { } public CouponViewDTO query(String var1) { Object[] var2 = new Object[]{var1}; Object var3 = this.handler.invoke(this, methods[0], var2); return (CouponViewDTO)var3; }}

3.2.2 服務提供者


3.2.2.1 創(chuàng)建服務提供者代理類


默認Javaassist代理工廠實現(xiàn),使用Wrapper包裝本地服務提供者。proxy是實際的服務提供者實例,即CouponServiceViewFacade的本地實現(xiàn)類,type是接口類定義,URL是injvm協(xié)議URL。

public class JavassistProxyFactory extends AbstractProxyFactory { 。。。 @Override public Invoker getInvoker(T proxy, Class type, URL url) { // 代理包裝類,包裝了本地的服務提供者 final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type); // 代理類入口 return new AbstractProxyInvoker(proxy, type, url) { @Override protected Object doInvoke(T proxy, String methodName, Class[] parameterTypes, Object[] arguments) throws Throwable { return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments); } }; } }

3.2.2.2 Wrapper包裝類


Dubbo為每個服務提供者的本地實現(xiàn)生成一個Wrapper代理類,抽象Wrapper類定義如下:

public abstract class Wrapper { 。。。 abstract public Object invokeMethod(Object instance, String mn, Class[] types, Object[] args) throws NoSuchMethodException, InvocationTargetException;}

具體Wrapper代理類使用字節(jié)碼技術動態(tài)生成,本地服務CouponServiceViewFacade的代理包裝類舉例:

//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)// package org.apache.dubbo.common.bytecode; import com.xxx.CouponServiceViewFacade;import java.lang.reflect.InvocationTargetException;import java.util.Map;import org.apache.dubbo.common.bytecode.ClassGenerator.DC; public class Wrapper25 extends Wrapper implements DC { 。。。 public Wrapper25() { } public Object invokeMethod(Object var1, String var2, Class[] var3, Object[] var4) throws InvocationTargetException { CouponServiceViewFacade var5; try { var5 = (CouponServiceViewFacade)var1; } catch (Throwable var8) { throw new IllegalArgumentException(var8); } try { if ("query".equals(var2)
本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
關閉