<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java 實現簡單的 RPC 框架

      RPC 簡介

      RPC,全稱為 Remote Procedure Call,即遠程過程調用,它是一個計算機通信協議。它允許像調用本地服務一樣調用遠程服務。它可以有不同的實現方式,而不需要了解底層網絡技術的協議。 RPC 協議假定某些傳輸協議的存在,如 TCP 或 UDP,為通信程序之間攜帶信息數據。如 RMI(遠程方法調用)、Hessian、Http invoker 等。

      怎樣實現一個 RPC 框架

      RPC 能夠讓本地應用簡單、高效地調用服務器中的過程。它主要應用在分布式系統。如 Hadoop 中的 IPC 組件。但怎樣實現一個 RPC 框架呢?
      可以從下面幾個方面思考:

      • 通信模型:假設通信的為 A 機器與 B 機器,A 與 B 之間有通信模型,在 Java 中一般基于 BIO 或 NIO。
      • 過程(服務)定位:使用給定的通信方式,與確定 IP 與端口及方法名稱確定具體的過程或方法;
      • 遠程代理對象:本地調用的方法(服務)其實是遠程方法的本地代理,因此可能需要一個遠程代理對象,對于 Java 而言,遠程代理對象可以使用 Java 的動態對象實現,封裝了調用遠程方法調用;
      • 序列化,將對象名稱、方法名稱、參數等對象信息進行網絡傳輸需要轉換成二進制傳輸,這里可能需要不同的序列化技術方案。如:protobuf,Arvo 等。

      RPC 框架架構

      RPC 架構分為三部分:

      • 服務提供者,運行在服務器端,提供服務接口定義與服務實現類。
      • 服務中心,運行在服務器端,負責將本地服務發布成遠程服務,管理遠程服務,提供給服務消費者使用。
      • 服務消費者,運行在客戶端,通過遠程代理對象調用遠程服務。

      RPC 框架的簡單實現

      這里我只介紹服務提供者和客戶端的實現方式。

      服務提供者

      服務提供者 IHello 接口定義:

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

      服務提供者 IHello 接口實現:

      public class HelloImpl implements IHello {
          @Override
          public String sayHello(String string) {
              return "Hello:" + string;
          }
      }

      服務端 RpcProxyServer 類:

      public class RpcProxyServer {
      
          ExecutorService executorService = Executors.newCachedThreadPool();
      
          public void publisher(Object service, int port) {
              ServerSocket serverSocket = null;
              try {
                  // 啟動 socket 服務
                  serverSocket = new ServerSocket(port);
                  while (true) {
                      Socket socket = serverSocket.accept();
                      executorService.execute(new ProcessorHandler(service, socket));
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }  

      服務端 RpcRequest 類:

      public class RpcRequest implements Serializable {
          private static final long serialVersionUID = 383378368319625542L;
          private String className;
          private String methodName;
          private Object[] params;
      
          public String getClassName() {
              return className;
          }
      
          public void setClassName(String className) {
              this.className = className;
          }
      
          public String getMethodName() {
              return methodName;
          }
      
          public void setMethodName(String methodName) {
              this.methodName = methodName;
          }
      
          public Object[] getParams() {
              return params;
          }
      
          public void setParams(Object[] params) {
              this.params = params;
          }
      
          @Override
          public String toString() {
              return "RpcRequest{" +
                      "className='" + className + '\'' +
                      ", methodName='" + methodName + '\'' +
                      ", params=" + Arrays.toString(params) +
                      '}';
          }
      }

      服務端 ProcessorHandler 類:

      import java.io.IOException;
      import java.io.ObjectInputStream;
      import java.io.ObjectOutputStream;
      import java.lang.reflect.InvocationTargetException;
      import java.lang.reflect.Method;
      import java.net.Socket;
      
      public class ProcessorHandler implements Runnable {
          Socket socket;
          Object service;
      
          public ProcessorHandler(Object service, Socket socket) {
              this.socket = socket;
              this.service = service;
          }
      
          @Override
          public void run() {
              System.out.println("begin processor handler!");
              ObjectInputStream objectInputStream = null;
              try {
                  objectInputStream = new ObjectInputStream(socket.getInputStream());
                  RpcRequest rpcRequest = (RpcRequest) objectInputStream.readObject();
                  Object restlt = invoke(rpcRequest);
      
                  ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                  objectOutputStream.writeObject(restlt);
                  objectOutputStream.flush();
      
                  objectInputStream.close();
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  if (objectInputStream != null) {
                      try {
                          objectInputStream.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      
          private Object invoke(RpcRequest request) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
              Object[] args = request.getParams();
              Class<?>[] types = new Class[args.length];
              for (int i = 0; i < args.length; i++) {
                  types[i] = args[i].getClass();
              }
              Method method = service.getClass().getMethod(request.getMethodName(), types);
              return method.invoke(service, args);
          }
      }

      服務端主類 RpcServerMain:

      public class RpcServerMain {
          public static void main(String[] args) {
              IHello hello = new HelloImpl();
              RpcProxyServer rpcProxyServer = new RpcProxyServer();
              rpcProxyServer.publisher(hello, 8080);
              System.out.println(hello.sayHello("charles"));
          }
      }

      客戶端

      客戶端 IHello 類:

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

      客戶端 RpcClientProxy 類:

      public class RpcClientProxy {
          public <T> T clientProxy(Class<T> interfaceCls, String host, int port) {
              return (T) Proxy.newProxyInstance(interfaceCls.getClassLoader(), new Class<?>[]{interfaceCls}, new RemoteInvocationHandler(host, port));
          }
      }

      客戶端 RpcRequest 類:

      public class RpcRequest implements Serializable {
          private static final long serialVersionUID = 383378368319625542L;
          private String className;
          private String methodName;
          private Object[] params;
      
          public String getClassName() {
              return className;
          }
      
          public void setClassName(String className) {
              this.className = className;
          }
      
          public String getMethodName() {
              return methodName;
          }
      
          public void setMethodName(String methodName) {
              this.methodName = methodName;
          }
      
          public Object[] getParams() {
              return params;
          }
      
          public void setParams(Object[] params) {
              this.params = params;
          }
      
          @Override
          public String toString() {
              return "RpcRequest{" +
                      "className='" + className + '\'' +
                      ", methodName='" + methodName + '\'' +
                      ", params=" + Arrays.toString(params) +
                      '}';
          }
      }
      

      客戶端 RpcNetTransport 類:

      import java.io.IOException;
      import java.io.ObjectInputStream;
      import java.io.ObjectOutput;
      import java.io.ObjectOutputStream;
      import java.net.Socket;
      
      public class RpcNetTransport {
      
          String host;
          int port;
      
          public RpcNetTransport(String host, int port) {
              this.host = host;
              this.port = port;
          }
      
          private Socket createSocket() {
              System.out.println("Begin create socket connect!");
              Socket socket = null;
      
              try {
                  socket = new Socket(host, port);
              } catch (Exception e) {
                  throw new RuntimeException("build connect failed.");
              }
              return socket;
          }
      
          public Object send(RpcRequest rpcRequest) {
              Socket socket = null;
      
      
              try {
                  socket = createSocket();
                  ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                  objectOutputStream.writeObject(rpcRequest);
                  objectOutputStream.flush();
      
                  // 返回結果接收
      
                  ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                  Object resultObject = objectInputStream.readObject();// 反序列化 對象
                  objectInputStream.close();
                  objectOutputStream.close();
      
                  return resultObject;
              } catch (Exception e) {
                  throw new RuntimeException("send request exception:" + e);
              } finally {
                  if (socket != null) {
                      try {
                          socket.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
      

      客戶端 RemoteInvocationHandler 類:

      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      
      public class RemoteInvocationHandler implements InvocationHandler {
          String host;
          int port;
      
          public RemoteInvocationHandler(String host, int port) {
              this.host = host;
              this.port = port;
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              RpcRequest rpcRequest = new RpcRequest();
              rpcRequest.setClassName(method.getDeclaringClass().getName());
              rpcRequest.setMethodName(method.getName());
              rpcRequest.setParams(args);
      
              RpcNetTransport rpcNetTransport = new RpcNetTransport(host, port);
              return rpcNetTransport.send(rpcRequest);
          }
      }
      

      客戶端主類 RpcClientMain:

      public class RpcClientMain {
          public static void main(String[] args) {
              RpcClientProxy rpcClientProxy = new RpcClientProxy();
              IHello hello = rpcClientProxy.clientProxy(IHello.class, "localhost", 8080);
              System.out.println(hello.sayHello("charles"));
          }
      }

      項目啟動后客戶端向服務端發送了一條消息,分別運行兩個項目后輸出結果如下

      服務端:

      begin processor handler!

      客戶端:

      Begin create socket connect!
      Hello:charles

      總結

      RPC 本質為消息處理模型,RPC 屏蔽了底層不同主機間的通信細節,讓進程調用遠程的服務就像是本地的服務一樣。

      posted @ 2015-11-17 20:26  Charles Zhang  閱讀(495)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产福利在线观看免费第一福利| 伊人久久大香线蕉综合网| 国产三级黄色片在线观看| 亚洲一区二区三上悠亚| 午夜福利精品国产二区| 国产极品尤物粉嫩在线观看 | 国产成人亚洲老熟女精品| 人妻久久久一区二区三区| 青青青爽在线视频观看| 色综合久久久久综合体桃花网| 国产揄拍国产精品| 读书| 色道久久综合亚洲精品蜜桃| av在线播放观看国产| 香蕉av777xxx色综合一区| 人人狠狠综合久久亚洲爱咲| 开心一区二区三区激情| 亚洲色大成网站www久久九九| 国产精品对白刺激久久久| 亚洲综合不卡一区二区三区| 日韩深夜福利视频在线观看| 美女一区二区三区亚洲麻豆| 国产一区二区三区黄色大片| 从江县| 色偷偷www.8888在线观看| 国产精品乱码久久久久久小说| 精品一区二区三区在线视频观看| 99精品视频在线观看免费蜜桃| 欧美性大战xxxxx久久久| 国内揄拍国内精品对久久| 久久午夜无码免费| 亚洲无av中文字幕在线| 午夜爽爽爽男女免费观看影院 | 肉大榛一进一出免费视频| 韩国美女福利视频在线观看| 4hu44四虎www在线影院麻豆| 男同精品视频免费观看网站| 四虎国产精品永久在线下载| 巨胸美乳无码人妻视频漫画| av亚洲一区二区在线| 国产精品va在线观看无码不卡|