摘要:遠程調(diào)用本地調(diào)用目標(biāo)介紹本地調(diào)用的設(shè)計和實現(xiàn),介紹的源碼。前言是一個遠程調(diào)用的框架,但是它沒有理由不支持本地調(diào)用,本文就要講解關(guān)于本地調(diào)用的實現(xiàn)。服務(wù)暴露者集合取消暴露調(diào)用父類的取消暴露方法從集合中移除二該類繼承了類,是本地調(diào)用的實現(xiàn)。
遠程調(diào)用——injvm本地調(diào)用
目標(biāo):介紹injvm本地調(diào)用的設(shè)計和實現(xiàn),介紹dubbo-rpc-injvm的源碼。前言
dubbo是一個遠程調(diào)用的框架,但是它沒有理由不支持本地調(diào)用,本文就要講解dubbo關(guān)于本地調(diào)用的實現(xiàn)。本地調(diào)用要比遠程調(diào)用簡單的多。
源碼分析 (一)InjvmExporter該類繼承了AbstractExporter,是本地服務(wù)的暴露者封裝,其中實現(xiàn)比較簡單。只是實現(xiàn)了unexport方法,并且維護了一份保存暴露者的集合。
class InjvmExporter(二)InjvmInvokerextends AbstractExporter { /** * 服務(wù)key */ private final String key; /** * 暴露者集合 */ private final Map > exporterMap; InjvmExporter(Invoker invoker, String key, Map > exporterMap) { super(invoker); this.key = key; this.exporterMap = exporterMap; exporterMap.put(key, this); } /** * 取消暴露 */ @Override public void unexport() { // 調(diào)用父類的取消暴露方法 super.unexport(); // 從集合中移除 exporterMap.remove(key); } }
該類繼承了AbstractInvoker類,是本地調(diào)用的invoker實現(xiàn)。
class InjvmInvokerextends AbstractInvoker { /** * 服務(wù)key */ private final String key; /** * 暴露者集合 */ private final Map > exporterMap; InjvmInvoker(Class type, URL url, String key, Map > exporterMap) { super(type, url); this.key = key; this.exporterMap = exporterMap; } /** * 服務(wù)是否活躍 * @return */ @Override public boolean isAvailable() { InjvmExporter> exporter = (InjvmExporter>) exporterMap.get(key); if (exporter == null) { return false; } else { return super.isAvailable(); } } /** * invoke方法 * @param invocation * @return * @throws Throwable */ @Override public Result doInvoke(Invocation invocation) throws Throwable { // 獲得暴露者 Exporter> exporter = InjvmProtocol.getExporter(exporterMap, getUrl()); // 如果為空,則拋出異常 if (exporter == null) { throw new RpcException("Service [" + key + "] not found."); } // 設(shè)置遠程地址為127.0.0.1 RpcContext.getContext().setRemoteAddress(NetUtils.LOCALHOST, 0); // 調(diào)用下一個調(diào)用鏈 return exporter.getInvoker().invoke(invocation); } }
其中重寫了isAvailable和doInvoke方法。
(三)InjvmProtocol該類是本地調(diào)用的協(xié)議實現(xiàn),其中實現(xiàn)了服務(wù)調(diào)用和服務(wù)暴露方法,并且封裝了一個判斷是否是本地調(diào)用的方法。
1.屬性/** * 本地調(diào)用 Protocol的實現(xiàn)類key */ public static final String NAME = Constants.LOCAL_PROTOCOL; /** * 默認(rèn)端口 */ public static final int DEFAULT_PORT = 0; /** * 單例 */ private static InjvmProtocol INSTANCE;2.getExporter
static Exporter> getExporter(Map> map, URL key) { Exporter> result = null; // 如果服務(wù)key不是* if (!key.getServiceKey().contains("*")) { // 直接從集合中取出 result = map.get(key.getServiceKey()); } else { // 如果 map不為空,則遍歷暴露者,來找到對應(yīng)的exporter if (map != null && !map.isEmpty()) { for (Exporter> exporter : map.values()) { // 如果是服務(wù)key if (UrlUtils.isServiceKeyMatch(key, exporter.getInvoker().getUrl())) { // 賦值 result = exporter; break; } } } } // 如果沒有找到exporter if (result == null) { // 則返回null return null; } else if (ProtocolUtils.isGeneric( result.getInvoker().getUrl().getParameter(Constants.GENERIC_KEY))) { // 如果是泛化調(diào)用,則返回null return null; } else { return result; } }
該方法是獲得相關(guān)的暴露者。
3.export@Override public4.referExporter export(Invoker invoker) throws RpcException { // 創(chuàng)建InjvmExporter 并且返回 return new InjvmExporter (invoker, invoker.getUrl().getServiceKey(), exporterMap); }
@Override public5.isInjvmReferInvoker refer(Class serviceType, URL url) throws RpcException { // 創(chuàng)建InjvmInvoker 并且返回 return new InjvmInvoker (serviceType, url, url.getServiceKey(), exporterMap); }
public boolean isInjvmRefer(URL url) { final boolean isJvmRefer; // 獲得scope配置 String scope = url.getParameter(Constants.SCOPE_KEY); // Since injvm protocol is configured explicitly, we don"t need to set any extra flag, use normal refer process. if (Constants.LOCAL_PROTOCOL.toString().equals(url.getProtocol())) { // 如果是injvm,則不是本地調(diào)用 isJvmRefer = false; } else if (Constants.SCOPE_LOCAL.equals(scope) || (url.getParameter("injvm", false))) { // if it"s declared as local reference // "scope=local" is equivalent to "injvm=true", injvm will be deprecated in the future release // 如果它被聲明為本地引用 scope = local"相當(dāng)于"injvm = true",將在以后的版本中棄用injvm isJvmRefer = true; } else if (Constants.SCOPE_REMOTE.equals(scope)) { // it"s declared as remote reference // 如果被聲明為遠程調(diào)用 isJvmRefer = false; } else if (url.getParameter(Constants.GENERIC_KEY, false)) { // generic invocation is not local reference // 泛化的調(diào)用不是本地調(diào)用 isJvmRefer = false; } else if (getExporter(exporterMap, url) != null) { // by default, go through local reference if there"s the service exposed locally // 默認(rèn)情況下,如果本地暴露服務(wù),請通過本地引用 isJvmRefer = true; } else { isJvmRefer = false; } return isJvmRefer; }
該方法是判斷是否為本地調(diào)用。
后記該部分相關(guān)的源碼解析地址:https://github.com/CrazyHZM/i...
該文章講解了遠程調(diào)用中關(guān)于injvm本地調(diào)用的部分,三種抽象的角色還是比較鮮明的,服務(wù)暴露相關(guān)的exporter、服務(wù)引用相關(guān)的invoker、以及協(xié)議相關(guān)的protocol,關(guān)鍵還是弄清楚再設(shè)計上的意圖,以及他們分別代表的是什么。那么看這些不同的協(xié)議實現(xiàn)會很容易看懂。接下來我將開始對rpc模塊關(guān)于memcached協(xié)議部分進行講解。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/73232.html
摘要:大揭秘異步化改造目標(biāo)從源碼的角度分析的新特性中對于異步化的改造原理??丛创a解析四十六消費端發(fā)送請求過程講到的十四的,在以前的邏輯會直接在方法中根據(jù)配置區(qū)分同步異步單向調(diào)用。改為關(guān)于可以參考源碼解析十遠程通信層的六。 2.7大揭秘——異步化改造 目標(biāo):從源碼的角度分析2.7的新特性中對于異步化的改造原理。 前言 dubbo中提供了很多類型的協(xié)議,關(guān)于協(xié)議的系列可以查看下面的文章: du...
摘要:服務(wù)暴露過程目標(biāo)從源碼的角度分析服務(wù)暴露過程。導(dǎo)出服務(wù),包含暴露服務(wù)到本地,和暴露服務(wù)到遠程兩個過程。其中服務(wù)暴露的第八步已經(jīng)沒有了。將泛化調(diào)用版本號或者等信息加入獲得服務(wù)暴露地址和端口號,利用內(nèi)數(shù)據(jù)組裝成。 dubbo服務(wù)暴露過程 目標(biāo):從源碼的角度分析服務(wù)暴露過程。 前言 本來這一篇一個寫異步化改造的內(nèi)容,但是最近我一直在想,某一部分的優(yōu)化改造該怎么去撰寫才能更加的讓讀者理解。我覺...
摘要:前言基于表單的遠程調(diào)用協(xié)議,采用的實現(xiàn),關(guān)于協(xié)議就不用多說了吧。后記該部分相關(guān)的源碼解析地址該文章講解了遠程調(diào)用中關(guān)于協(xié)議的部分,內(nèi)容比較簡單,可以參考著官方文檔了解一下。 遠程調(diào)用——http協(xié)議 目標(biāo):介紹遠程調(diào)用中跟http協(xié)議相關(guān)的設(shè)計和實現(xiàn),介紹dubbo-rpc-http的源碼。 前言 基于HTTP表單的遠程調(diào)用協(xié)議,采用 Spring 的HttpInvoker實現(xiàn),關(guān)于h...
摘要:而存在的意義就是保證請求或響應(yīng)對象可在線程池中被解碼,解碼完成后,就會分發(fā)到的。 2.7大揭秘——服務(wù)端處理請求過程 目標(biāo):從源碼的角度分析服務(wù)端接收到請求后的一系列操作,最終把客戶端需要的值返回。 前言 上一篇講到了消費端發(fā)送請求的過程,該篇就要將服務(wù)端處理請求的過程。也就是當(dāng)服務(wù)端收到請求數(shù)據(jù)包后的一系列處理以及如何返回最終結(jié)果。我們也知道消費端在發(fā)送請求的時候已經(jīng)做了編碼,所以我...
摘要:可以參考源碼解析二十四遠程調(diào)用協(xié)議的八。十六的該類也是用了適配器模式,該類主要的作用就是增加了心跳功能,可以參考源碼解析十遠程通信層的四。二十的可以參考源碼解析十七遠程通信的一。 2.7大揭秘——消費端發(fā)送請求過程 目標(biāo):從源碼的角度分析一個服務(wù)方法調(diào)用經(jīng)歷怎么樣的磨難以后到達服務(wù)端。 前言 前一篇文章講到的是引用服務(wù)的過程,引用服務(wù)無非就是創(chuàng)建出一個代理。供消費者調(diào)用服務(wù)的相關(guān)方法。...
閱讀 1084·2021-11-16 11:45
閱讀 2732·2021-09-27 13:59
閱讀 1328·2021-08-31 09:38
閱讀 3159·2019-08-30 15:52
閱讀 1324·2019-08-29 13:46
閱讀 2096·2019-08-29 11:23
閱讀 1654·2019-08-26 13:47
閱讀 2502·2019-08-26 11:54