摘要:源碼分析一該類繼承,是協(xié)議實現(xiàn)的核心。屬性默認端口號不支持服務(wù)暴露可以看到,服務(wù)暴露方法直接拋出異常。后記該部分相關(guān)的源碼解析地址該文章講解了遠程調(diào)用中關(guān)于協(xié)議實現(xiàn)的部分,邏輯比較簡單。
遠程調(diào)用——memcached協(xié)議
目標:介紹memcached協(xié)議的設(shè)計和實現(xiàn),介紹dubbo-rpc-memcached的源碼。前言
dubbo實現(xiàn)memcached協(xié)議是基于Memcached,Memcached 是一個高效的 KV 緩存服務(wù)器,在dubbo中沒有涉及到關(guān)于memcached協(xié)議的服務(wù)暴露,只有服務(wù)引用,因為在訪問Memcached服務(wù)器時,Memcached客戶端可以在服務(wù)器上存儲也可以獲取。
源碼分析 (一)MemcachedProtocol該類繼承AbstractProtocol,是memcached協(xié)議實現(xiàn)的核心。
1.屬性/** * 默認端口號 */ public static final int DEFAULT_PORT = 11211;2.export
@Override publicExporter export(final Invoker invoker) throws RpcException { // 不支持memcached服務(wù)暴露 throw new UnsupportedOperationException("Unsupported export memcached service. url: " + invoker.getUrl()); }
可以看到,服務(wù)暴露方法直接拋出異常。
3.refer@Override publicInvoker refer(final Class type, final URL url) throws RpcException { try { // 獲得地址 String address = url.getAddress(); // 獲得備用地址 String backup = url.getParameter(Constants.BACKUP_KEY); // 把備用地址拼接上 if (backup != null && backup.length() > 0) { address += "," + backup; } // 創(chuàng)建Memcached客戶端構(gòu)造器 MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(address)); // 創(chuàng)建客戶端 final MemcachedClient memcachedClient = builder.build(); // 到期時間參數(shù)配置 final int expiry = url.getParameter("expiry", 0); // 獲得值命令 final String get = url.getParameter("get", "get"); // 添加值命令根據(jù)類型來取決是put還是set final String set = url.getParameter("set", Map.class.equals(type) ? "put" : "set"); // 刪除值命令 final String delete = url.getParameter("delete", Map.class.equals(type) ? "remove" : "delete"); return new AbstractInvoker (type, url) { @Override protected Result doInvoke(Invocation invocation) throws Throwable { try { // 如果是獲取方法名的值 if (get.equals(invocation.getMethodName())) { // 如果參數(shù)長度不等于1,則拋出異常 if (invocation.getArguments().length != 1) { throw new IllegalArgumentException("The memcached get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); } // 否則調(diào)用get方法來獲取 return new RpcResult(memcachedClient.get(String.valueOf(invocation.getArguments()[0]))); } else if (set.equals(invocation.getMethodName())) { // 如果參數(shù)長度不為2,則拋出異常 if (invocation.getArguments().length != 2) { throw new IllegalArgumentException("The memcached set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); } // 無論任何現(xiàn)有值如何,都在緩存中設(shè)置一個對象 memcachedClient.set(String.valueOf(invocation.getArguments()[0]), expiry, invocation.getArguments()[1]); return new RpcResult(); } else if (delete.equals(invocation.getMethodName())) { // 刪除操作只有一個參數(shù),如果參數(shù)長度不等于1,則拋出異常 if (invocation.getArguments().length != 1) { throw new IllegalArgumentException("The memcached delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url); } // 刪除某個值 memcachedClient.delete(String.valueOf(invocation.getArguments()[0])); return new RpcResult(); } else { // 不支持的操作 throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in memcached service."); } } catch (Throwable t) { RpcException re = new RpcException("Failed to invoke memcached service method. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url + ", cause: " + t.getMessage(), t); if (t instanceof TimeoutException || t instanceof SocketTimeoutException) { re.setCode(RpcException.TIMEOUT_EXCEPTION); } else if (t instanceof MemcachedException || t instanceof IOException) { re.setCode(RpcException.NETWORK_EXCEPTION); } throw re; } } @Override public void destroy() { super.destroy(); try { // 關(guān)閉客戶端 memcachedClient.shutdown(); } catch (Throwable e) { logger.warn(e.getMessage(), e); } } }; } catch (Throwable t) { throw new RpcException("Failed to refer memcached service. interface: " + type.getName() + ", url: " + url + ", cause: " + t.getMessage(), t); } }
該方法是服務(wù)引用方法,基于MemcachedClient的get、set、delete方法來對應(yīng)Memcached的get、set、delete命令進行對值的操作。
后記該部分相關(guān)的源碼解析地址:https://github.com/CrazyHZM/i...
該文章講解了遠程調(diào)用中關(guān)于memcached協(xié)議實現(xiàn)的部分,邏輯比較簡單。接下來我將開始對rpc模塊關(guān)于redis協(xié)議部分進行講解。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/61750.html
摘要:大揭秘異步化改造目標從源碼的角度分析的新特性中對于異步化的改造原理。看源碼解析四十六消費端發(fā)送請求過程講到的十四的,在以前的邏輯會直接在方法中根據(jù)配置區(qū)分同步異步單向調(diào)用。改為關(guān)于可以參考源碼解析十遠程通信層的六。 2.7大揭秘——異步化改造 目標:從源碼的角度分析2.7的新特性中對于異步化的改造原理。 前言 dubbo中提供了很多類型的協(xié)議,關(guān)于協(xié)議的系列可以查看下面的文章: du...
摘要:遠程調(diào)用本地調(dià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)用 目標:介紹injvm本地調(diào)用的設(shè)計和實現(xiàn),介紹dubbo-rpc-injvm的源碼。 前言 dubbo是一個遠程調(diào)用的...
摘要:可以參考源碼解析二十四遠程調(diào)用協(xié)議的八。十六的該類也是用了適配器模式,該類主要的作用就是增加了心跳功能,可以參考源碼解析十遠程通信層的四。二十的可以參考源碼解析十七遠程通信的一。 2.7大揭秘——消費端發(fā)送請求過程 目標:從源碼的角度分析一個服務(wù)方法調(diào)用經(jīng)歷怎么樣的磨難以后到達服務(wù)端。 前言 前一篇文章講到的是引用服務(wù)的過程,引用服務(wù)無非就是創(chuàng)建出一個代理。供消費者調(diào)用服務(wù)的相關(guān)方法。...
摘要:源碼分析一該類繼承了類,是協(xié)議實現(xiàn)的核心。屬性默認端口號不支持協(xié)議的服務(wù)暴露,拋出異常可以看到不支持服務(wù)暴露。后記該部分相關(guān)的源碼解析地址該文章講解了遠程調(diào)用中關(guān)于協(xié)議實現(xiàn)的部分,邏輯比較簡單。 遠程調(diào)用——redis協(xié)議 目標:介紹redis協(xié)議的設(shè)計和實現(xiàn),介紹dubbo-rpc-redis的源碼。 前言 dubbo支持的redis協(xié)議是基于Redis的,Redis 是一個高效的 ...
摘要:而存在的意義就是保證請求或響應(yīng)對象可在線程池中被解碼,解碼完成后,就會分發(fā)到的。 2.7大揭秘——服務(wù)端處理請求過程 目標:從源碼的角度分析服務(wù)端接收到請求后的一系列操作,最終把客戶端需要的值返回。 前言 上一篇講到了消費端發(fā)送請求的過程,該篇就要將服務(wù)端處理請求的過程。也就是當服務(wù)端收到請求數(shù)據(jù)包后的一系列處理以及如何返回最終結(jié)果。我們也知道消費端在發(fā)送請求的時候已經(jīng)做了編碼,所以我...
閱讀 2890·2021-11-24 09:39
閱讀 2459·2019-08-30 15:53
閱讀 3031·2019-08-30 13:47
閱讀 1302·2019-08-30 12:50
閱讀 1485·2019-08-29 16:31
閱讀 2646·2019-08-29 13:14
閱讀 1562·2019-08-29 10:55
閱讀 795·2019-08-26 13:32