轉自:http://blog.csdn.net/rulon147/article/details/53814589java
1、什麼是RPC
RPC(Remote Procedure Call Protocol)——
遠程過程調用協議,它是一種經過
網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議。
RPC協議假定某些
傳輸協議的存在,如TCP或UDP,爲通訊程序之間攜帶信息數據。在OSI
網絡通訊模型中,RPC跨越了
傳輸層和
應用層。RPC使得開發包括網絡
分佈式多程序在內的應用程序更加容易。
RPC採用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,而後等待應答信息。在服務器端,進程保持睡眠狀態直到調用信息到達爲止。當一個調用信息到達,服務器得到進程參數,計算結果,發送答覆
信息,而後等待下一個調用信息,最後,客戶端調用進程接收答覆信息,得到進程結果,而後調用執行繼續進行。
有多種 RPC模式和執行。最初由 Sun 公司提出。IETF ONC 憲章從新修訂了 Sun 版本,使得 ONC RPC 協議成爲 IETF 標準協議。如今使用最廣泛的模式和執行是開放式軟件基礎的分佈式計算
環境(DCE)。
2、圖例說明
![](http://static.javashuo.com/static/loading.gif)
3、java 實例演示
一、實現技術方案
下面使用比較原始的方案實現RPC框架,採用Socket通訊、動態代理與反射與Java原生的序列化。bash
二、RPC框架架構
RPC架構分爲三部分:服務器
- 服務提供者,運行在服務器端,提供服務接口定義與服務實現類。
- 服務中心,運行在服務器端,負責將本地服務發佈成遠程服務,管理遠程服務,提供給服務消費者使用。
- 服務消費者,運行在客戶端,經過遠程代理對象調用遠程服務。
三、 具體實現
1)服務提供者接口定義與實現,代碼以下:網絡
- package services;
-
-
- public interface HelloService {
-
-
- String sayHi(String name);
-
-
- }
2)HelloServices接口實現類:架構
- package services.impl;
-
-
- import services.HelloService;
-
-
- public class HelloServiceImpl implements HelloService {
-
-
- public String sayHi(String name) {
- return "Hi, " + name;
- }
-
-
- }
3)服務中心代碼實現,代碼以下:框架
- package services;
-
-
- import java.io.IOException;
-
-
- public interface Server {
- public void stop();
-
-
- public void start() throws IOException;
-
-
- public void register(Class serviceInterface, Class impl);
-
-
- public boolean isRunning();
-
-
- public int getPort();
- }
4)服務中心實現類:socket
5)客戶端的遠程代理對象:分佈式
- package client;
-
-
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Proxy;
- import java.net.InetSocketAddress;
- import java.net.Socket;
- import java.lang.reflect.Method;
-
-
- public class RPCClient<T> {
- @SuppressWarnings("unchecked")
- public static <T> T getRemoteProxyObj(final Class<?> serviceInterface, final InetSocketAddress addr) {
-
- return (T) Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class<?>[] { serviceInterface },
- new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Socket socket = null;
- ObjectOutputStream output = null;
- ObjectInputStream input = null;
- try {
-
- socket = new Socket();
- socket.connect(addr);
-
-
-
- output = new ObjectOutputStream(socket.getOutputStream());
- output.writeUTF(serviceInterface.getName());
- output.writeUTF(method.getName());
- output.writeObject(method.getParameterTypes());
- output.writeObject(args);
-
-
-
- input = new ObjectInputStream(socket.getInputStream());
- return input.readObject();
- } finally {
- if (socket != null)
- socket.close();
- if (output != null)
- output.close();
- if (input != null)
- input.close();
- }
- }
- });
- }
- }
6)最後爲測試類:測試
- package client;
-
-
- import java.io.IOException;
- import java.net.InetSocketAddress;
-
-
- import services.HelloService;
- import services.Server;
- import services.impl.HelloServiceImpl;
- import services.impl.ServiceCenter;
-
-
- public class RPCTest {
- public static void main(String[] args) throws IOException {
- new Thread(new Runnable() {
- public void run() {
- try {
- Server serviceServer = new ServiceCenter(8088);
- serviceServer.register(HelloService.class, HelloServiceImpl.class);
- serviceServer.start();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }).start();
- HelloService service = RPCClient
- .getRemoteProxyObj(HelloService.class, new InetSocketAddress("localhost", 8088));
- System.out.println(service.sayHi("test"));
- }
-
-
- }
運行結果:this
- regeist service HelloService
- start server
- Hi, test