從零手寫RPC

RPC概述

RPC(Remote Proceduce Call 遠程過程調(diào)用) 一般用來實現(xiàn)部署在不同機器上的系統(tǒng)之間的方法調(diào)用,使程序能夠像訪問本地系統(tǒng)資源一樣轮蜕,通過網(wǎng)絡(luò)傳輸過去訪問遠端系統(tǒng)資源昨悼。

RPC 調(diào)用過程

  1. Client 客戶端調(diào)用方法實現(xiàn),負責發(fā)起RPC調(diào)用跃洛。
  2. ClientStub/SereverStub 可以看作一個代理對象率触,屏蔽RPC調(diào)用過程中復雜的網(wǎng)絡(luò)處理邏輯,使RPC透明化汇竭,使得調(diào)用遠程方法想調(diào)用本地方法一樣葱蝗。
  3. Server 服務(wù)端提供遠程服務(wù)穴张。

Stub 主要作用

  • 序列化:負責數(shù)據(jù)的序列化發(fā)序列化。
  • 網(wǎng)絡(luò)傳輸:數(shù)據(jù)發(fā)送與接收两曼。

注:ServerStub又叫Skeleton皂甘。

RPC 實現(xiàn)

1. 遠程服務(wù)接口

public interface IHello {
    public String sayHello(String info);
}

2. 遠程服務(wù)接口實現(xiàn)類(Server)

public class HelloService implements IHello {
    public String sayHello(String info) {
        String result = "hello : " + info;
        System.out.println(result);
        return result;
    }
}

提供服務(wù)實現(xiàn)的類。

3.服務(wù)器代理實現(xiàn)(Skeleton)

public class RpcProxyServer {
    private IHello hello = new HelloService();

    public void publisherServer(int port) {
        try (ServerSocket ss = new ServerSocket(port)) {
            while (true) {
                try (Socket socket = ss.accept()) {
                    try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
                        String method = ois.readUTF();
                        Object[] objs = (Object[]) ois.readObject();
                        Class<?>[] types = new Class[objs.length];
                        for (int i = 0; i < types.length; i++) {
                            types[i] = objs[i].getClass();
                        }
                        Method m = HelloService.class.getMethod(method, types);
                        Object obj = m.invoke(hello, objs);

                        try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {
                            oos.writeObject(obj);
                            oos.flush();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  1. 構(gòu)建一個ServerSocket服務(wù)監(jiān)聽來自客戶端的請求悼凑。
  2. 接收請求的數(shù)據(jù)偿枕。(方法名和參數(shù))
  3. 根據(jù)請求的數(shù)據(jù)(方法名和參數(shù)),使用反射調(diào)用相應(yīng)的服務(wù)户辫。
  4. 輸出服務(wù)的響應(yīng)數(shù)據(jù)渐夸。

4. RPC 客戶端代理實現(xiàn)(ClientStub)

public class RpcProxyClient<T> {

    public T proxyClient(Class<T> clazz) {
        return (T) clazz.cast(Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        try (Socket socket = new Socket("localhost", 8000)) {
                            try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {
                                oos.writeUTF(method.getName());
                                oos.writeObject(args);
                                oos.flush();

                                try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
                                    return ois.readObject();
                                }
                            }
                        }
                    }
                }));
    }
}
  1. 構(gòu)建一個Socket,連接遠程服務(wù)寸莫。
  2. 向遠程服務(wù)發(fā)送數(shù)據(jù)捺萌。(方法名和方法參數(shù))
  3. 接收遠程服務(wù)響應(yīng)的數(shù)據(jù)。

5.服務(wù)端發(fā)布服務(wù)

public class RpcServer {
    //發(fā)布服務(wù)
    public static void main(String[] args) {
        RpcProxyServer server = new RpcProxyServer();
        server.publisherServer(8000);
    }
}

6.客戶端調(diào)用(Client)

public class RpcClient {
    // 調(diào)用服務(wù)
    public static void main(String[] args) {
        RpcProxyClient<HelloService> rpcClient = new RpcProxyClient<>();

        IHello hello = rpcClient.proxyClient(HelloService.class);
        String s = hello.sayHello("dd");
        System.out.println(s);
    }
}

想了解更多精彩內(nèi)容請關(guān)注我的公眾號

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膘茎,一起剝皮案震驚了整個濱河市桃纯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌披坏,老刑警劉巖态坦,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異棒拂,居然都是意外死亡伞梯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門帚屉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谜诫,“玉大人,你說我怎么就攤上這事攻旦∮骺酰” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵牢屋,是天一觀的道長且预。 經(jīng)常有香客問我,道長烙无,這世上最難降的妖魔是什么锋谐? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮截酷,結(jié)果婚禮上涮拗,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好多搀,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布歧蕉。 她就那樣靜靜地躺著,像睡著了一般康铭。 火紅的嫁衣襯著肌膚如雪惯退。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天从藤,我揣著相機與錄音催跪,去河邊找鬼。 笑死夷野,一個胖子當著我的面吹牛懊蒸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悯搔,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼骑丸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了妒貌?” 一聲冷哼從身側(cè)響起通危,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灌曙,沒想到半個月后菊碟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡在刺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年微驶,在試婚紗的時候發(fā)現(xiàn)自己被綠了蝇恶。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡局劲,死狀恐怖智蝠,靈堂內(nèi)的尸體忽然破棺而出堕油,到底是詐尸還是另有隱情螟蒸,我是刑警寧澤唉擂,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站输玷,受9級特大地震影響队丝,放射性物質(zhì)發(fā)生泄漏靡馁。R本人自食惡果不足惜欲鹏,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臭墨。 院中可真熱鬧赔嚎,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至损晤,卻和暖如春软棺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尤勋。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工喘落, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人最冰。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓瘦棋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親暖哨。 傳聞我的和親對象是個殘疾皇子赌朋,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)篇裁,斷路器沛慢,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 轉(zhuǎn)自:http://blog.csdn.net/kesonyk/article/details/50924489 ...
    晴天哥_王志閱讀 24,808評論 2 38
  • 今天分布式應(yīng)用、云計算茴恰、微服務(wù)大行其道颠焦,作為其技術(shù)基石之一的 RPC 你了解多少?一篇 RPC 的技術(shù)總結(jié)文章往枣,數(shù)...
    零一間閱讀 1,893評論 1 46
  • 一伐庭、 “新生對吧?周末回家叫家長帶你去醫(yī)院查一下分冈』恚”校醫(yī)拿著止血帶,手腳利索地在傷者的受傷的膝蓋處纏繞著雕沉。 “嗯集乔?...
    木拾柒閱讀 766評論 3 7
  • 如果說今天走在街上問別人知不知道今天是什么節(jié)日,九成九的人會一臉懵坡椒,五月十二離五一假期結(jié)束已經(jīng)一段時間了扰路,離六一兒...
    南慕南閱讀 176評論 0 0