上篇博客主要介紹了dubbo的使用,這篇文章主要深刻rpc的核心原理html
準備知識:java
1 java 網絡編程(這裏使用的bio)編程
2 java動態代理服務器
3 反射網絡
=================================架構
通俗來講rpc就是框架
客戶端持有的是接口(可是沒有持有實現),socket
服務端放的是接口的具體實現以及接口。ide
客戶端把方法和方法的參數 以及其餘參數 經過socket發送給服務端,性能
而後服務端執行相對應的方法,最後再把執行結果返回給客戶端。
RPC的架構通常分爲三部分:
1)服務提供者,運行在服務器端,提供服務接口定義與服務實現類。
在本項目主要是(ITestService 以及 TestServiceImpl)
2)服務中心,運行在服務器端,負責將本地服務註冊成遠程服務,管理遠程服務,提供給服務消費者使用。
在本項目主要是(IServerCenter以及BioServiceCenter)
3)服務消費者,運行在客戶端,經過遠程代理對象調用遠程服務。
在本項目主要是(RpcProxy 返回代理對象)
核心代碼以下:
服務提供者的接口定義
public interface ITestService { String sayHi(String name); }
服務提供者的接口實現
public class TestServiceImpl implements ITestService { public String sayHi(String name) { return "Hi, " + name; } }
服務中心接口抽象
public interface IServerCenter { public void stop(); /** * 開啓服務 * * @throws IOException */ public void start() throws IOException; /** * 服務提供者註冊到服務中心上 * * @param servInterfaceName * 服務接口名字 * @param servImplClazz * 具體服務實現class * @throws IOException */ public void register(String servInterfaceName, Class<?> servImplClazz); }
服務中心接口實現
客戶端的遠程代理類(主要是生成代理對象,發送請求給服務器 並獲取返回結果)
關閉流的代碼這裏省略了
測試類
public class Test { public static void main(String[] args) { final int port = 9999; new Thread(new Runnable() { @Override public void run() { BioServiceCenter bioServiceCenter = new BioServiceCenter(port); bioServiceCenter.register(ITestService.class.getName(), TestServiceImpl.class); try { bioServiceCenter.start(); } catch (IOException e) { e.printStackTrace(); } } }).start(); ITestService iTestService = (ITestService) RpcProxy.getRpcProxyObject(ITestService.class, new InetSocketAddress("localhost", port)); System.out.println(iTestService.sayHi("nihao ")); } }
運行結果以下
注意:這個例子只是模擬了核心處理流程,還有如下幾個點能夠優化
1 bio相對來講性能不如nio ,能夠考慮使用netty等高性能網絡通訊框架
2 使用更加高效的序列化方式,好比Google protobu ,kryo等
3 服務註冊與發現 能夠使用zookeeper實現,更加穩定