Elasticsearch NettyTransport通訊機制
ES 當發起各種Action類的Request時, 在叢集環境中通常需要進行請求的轉發, 此時就會出現RPC通訊, 針對此RPC通訊ES 是透過NettyTransport類來完成轉發與接收功能的. 實際上就是基於Netty的一個通訊程式碼模組.
在Node啟動以及TransportClient初始化的過程中都會建立NettyTransport
Node節點啟動時
當節點Node啟動時會根據依賴注入獲取TransportService例項, 並呼叫其start方法,最終會轉向NettyTransport的doStart 方法, 進而建立Netty RPC的客戶端以及服務端物件, 透過MessageHandler來處理請求或者處理Response.
public Node start() { //... 省略 injector.getInstance(MappingUpdatedAction.class).setClient(client); injector.getInstance(IndicesService.class).start(); injector.getInstance(IndexingMemoryController.class).start(); injector.getInstance(IndicesClusterStateService.class).start(); injector.getInstance(IndicesTTLService.class).start(); injector.getInstance(SnapshotsService.class).start(); injector.getInstance(SnapshotShardsService.class).start(); injector.getInstance(RoutingService.class).start(); injector.getInstance(SearchService.class).start(); injector.getInstance(MonitorService.class).start(); injector.getInstance(RestController.class).start(); // TODO hack around circular dependencies problems injector.getInstance(GatewayAllocator.class).setReallocation(injector.getInstance(ClusterService.class), injector.getInstance(RoutingService.class)); injector.getInstance(ResourceWatcherService.class).start(); injector.getInstance(GatewayService.class).start(); // Start the transport service now so the publish address will be added to the local disco node in ClusterService TransportService transportService = injector.getInstance(TransportService.class); transportService.start(); injector.getInstance(ClusterService.class).start(); //... 省略 return this; }
轉而AbstractLifecycleComponent的start方法
public T start() { if (!lifecycle.canMoveToStarted()) { return (T) this; } for (LifecycleListener listener : listeners) { listener.beforeStart(); } doStart(); lifecycle.moveToStarted(); for (LifecycleListener listener : listeners) { listener.afterStart(); } return (T) this; }
doStart方法此處只分析NettyTransport的doStart方法(不分析LocalTransport的)
那段程式碼中有如下兩個比較關鍵:
clientBootstrap = createClientBootstrap(); // 啟動客戶端createServerBootstrap(name, mergedSettings); // 啟動Server端
看看客戶端的構造:
private ClientBootstrap createClientBootstrap() { if (blockingClient) { clientBootstrap = new ClientBootstrap(new OioClientSocketChannelFactory(Executors.newCachedThreadPool(daemonThreadFactory(settings, TRANSPORT_CLIENT_WORKER_THREAD_NAME_PREFIX)))); } else { int bossCount = settings.getAsInt("transport.netty.boss_count", 1); clientBootstrap = new ClientBootstrap(new NioClientSocketChannelFactory( Executors.newCachedThreadPool(daemonThreadFactory(settings, TRANSPORT_CLIENT_BOSS_THREAD_NAME_PREFIX)), bossCount, new NioWorkerPool(Executors.newCachedThreadPool(daemonThreadFactory(settings, TRANSPORT_CLIENT_WORKER_THREAD_NAME_PREFIX)), workerCount), new HashedWheelTimer(daemonThreadFactory(settings, "transport_client_timer")))); } clientBootstrap.setPipelineFactory(configureClientChannelPipelineFactory()); //... 省略 return clientBootstrap; }
上面程式碼一個注意的地方是clientBootstrap.setPipelineFactory(configureClientChannelPipelineFactory());
public ChannelPipelineFactory configureClientChannelPipelineFactory() { return new ClientChannelPipelineFactory(this); }
protected static class ClientChannelPipelineFactory implements ChannelPipelineFactory { protected final NettyTransport nettyTransport; public ClientChannelPipelineFactory(NettyTransport nettyTransport) { this.nettyTransport = nettyTransport; } @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); SizeHeaderFrameDecoder sizeHeader = new SizeHeaderFrameDecoder(); if (nettyTransport.maxCumulationBufferCapacity != null) { if (nettyTransport.maxCumulationBufferCapacity.bytes() > Integer.MAX_VALUE) { sizeHeader.setMaxCumulationBufferCapacity(Integer.MAX_VALUE); } else { sizeHeader.setMaxCumulationBufferCapacity((int) nettyTransport.maxCumulationBufferCapacity.bytes()); } } if (nettyTransport.maxCompositeBufferComponents != -1) { sizeHeader.setMaxCumulationBufferComponents(nettyTransport.maxCompositeBufferComponents); } channelPipeline.addLast("size", sizeHeader); // using a dot as a prefix means, this cannot come from any settings parsed channelPipeline.addLast("dispatcher", new MessageChannelHandler(nettyTransport, nettyTransport.logger, ".client")); return channelPipeline; } }
上面的程式碼中channelPipeline.addLast("dispatcher", new MessageChannelHandler(nettyTransport, nettyTransport.logger, ".client"));指定了使用MessageChannelHandler來進行接收處理請求或者Response
createServerBootstrap(name, mergedSettings); // 啟動Server端 基本和createClientBootstrap()流程相似, 最終都是透過MessageChannelHandler來進行接收處理請求或者Response.
建立TransportClient時
當呼叫build方法時會根據依賴注入獲取TransportService例項, 並呼叫其start方法,最終會轉向NettyTransport的doStart 方法, 進而建立Netty RPC的客戶端以及服務端物件, 透過MessageHandler來處理請求或者處理Response.
它的具體流程和上面基本一致.
整體的結構圖如圖所示
image.png
透過這樣的方式, 當Client發起一個請求, 比如先發給協調器, 協調器可能需要透過NettyTranport(也可能是LocalTransport, 看具體情況)轉發到其他的Node, 最終會透過MessageChannelHandler進行處理Request以及Response
作者:kason_zhang
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1762/viewspace-2816613/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Binder通訊機制
- Binder通訊機制與IPC通訊.md
- Linux程式通訊機制Linux
- 通訊機制 synchronous communication
- HTTPS的安全通訊機制HTTP
- Android程式間通訊–訊息機制及IPC機制實現薦Android
- ReactNative原始碼篇:通訊機制React原始碼
- 一張圖進階 RocketMQ - 通訊機制MQ
- React Native通訊機制詳解React Native
- Elasticsearch 模組 - Shard Allocation 機制Elasticsearch
- Android系統之Binder通訊機制Android
- Android 程式通訊機制之 AIDLAndroidAI
- 執行緒間通訊_等待/通知機制執行緒
- Spark原始碼分析之BlockManager通訊機制Spark原始碼BloC
- Kubernetes的容器網路通訊機制
- WebRTC 及點對點網路通訊機制Web
- Java 執行緒間通訊 —— 等待 / 通知機制Java執行緒
- Linux 程式間通訊的六種機制Linux
- ros的幾種通訊機制及程式碼ROS
- React Native原理之跨端通訊機制React Native跨端
- 螞蟻金服通訊框架 SOFABolt 解析 | 超時控制機制及心跳機制框架
- OC訊息機制,訊息轉發機制
- 深入探討程式間通訊的重要性:理解不同的通訊機制(下)
- 深入探討程式間通訊的重要性:理解不同的通訊機制(上)
- PHP-FPM 與 Nginx 的通訊機制總結PHPNginx
- Android 系統原始碼-2:Binder 通訊機制Android原始碼
- 從 Java 層看 React-Native 通訊機制JavaReact
- Spark原始碼分析之Worker啟動通訊機制Spark原始碼
- mysql通訊協議的半雙工機制理解MySql協議
- 遊戲Entity層通訊機制:超越虛擬函式遊戲函式
- 程式間通訊機制(管道、訊號、共享記憶體/訊號量/訊息佇列)、執行緒間通訊機制(互斥鎖、條件變數、posix匿名訊號量)記憶體佇列執行緒變數
- 通過URLSchemes建立應用間通訊機制(例:支付寶)Scheme
- 訊息機制
- 執行緒通訊機制:共享記憶體 VS 訊息傳遞執行緒記憶體
- 聊聊 Elasticsearch 中的任務管理機制Elasticsearch
- ElasticSearch 文件(document)內部機制詳解Elasticsearch
- iOS訊息機制iOS
- SAP訊息機制