原帖地址 感谢 作者 http://blog.csdn.net/rulon147/article/details/53814589

一、什么是RPC

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
有多种 RPC模式和执行。最初由 Sun 公司提出。IETF ONC 宪章重新修订了 Sun 版本,使得 ONC RPC 协议成为 IETF 标准协议。现在使用最普遍的模式和执行是开放式软件基础的分布式计算环境(DCE)。

二、图例说明

三、java 实例演示

1、实现技术方案

下面使用比较原始的方案实现RPC框架,采用Socket通信、动态代理与反射与Java原生的序列化。

2、RPC框架架构

RPC架构分为三部分:

  1. 服务提供者,运行在服务器端,提供服务接口定义与服务实现类。
  2. 服务中心,运行在服务器端,负责将本地服务发布成远程服务,管理远程服务,提供给服务消费者使用。
  3. 服务消费者,运行在客户端,通过远程代理对象调用远程服务。

3、 具体实现

1)服务提供者接口定义与实现,代码如下:

[java] view plaincopy
  1. package services;
  2. public interface HelloService {
  3. String sayHi(String name);
  4. }

2)HelloServices接口实现类:

[java] view plaincopy
  1. package services.impl;
  2. import services.HelloService;
  3. public class HelloServiceImpl implements HelloService {
  4. public String sayHi(String name) {
  5. return "Hi, " + name;
  6. }
  7. }

3)服务中心代码实现,代码如下:

[java] view plaincopy
  1. package services;
  2. import java.io.IOException;
  3. public interface Server {
  4. public void stop();
  5. public void start() throws IOException;
  6. public void register(Class serviceInterface, Class impl);
  7. public boolean isRunning();
  8. public int getPort();
  9. }

4)服务中心实现类:

[java] view plaincopy
  1. package services.impl;
  2. import java.io.IOException;
  3. import java.io.ObjectInputStream;
  4. import java.io.ObjectOutputStream;
  5. import java.lang.reflect.Method;
  6. import java.net.InetSocketAddress;
  7. import java.net.ServerSocket;
  8. import java.net.Socket;
  9. import java.util.HashMap;
  10. import java.util.concurrent.ExecutorService;
  11. import java.util.concurrent.Executors;
  12. import services.Server;
  13. public class ServiceCenter implements Server {
  14. private static ExecutorService              executor        = Executors.newFixedThreadPool(Runtime.getRuntime()
  15. .availableProcessors());
  16. private static final HashMap<String, Class> serviceRegistry = new HashMap<String, Class>();
  17. private static boolean                      isRunning       = false;
  18. private static int                          port;
  19. public ServiceCenter(int port) {
  20. this.port = port;
  21. }
  22. public void stop() {
  23. isRunning = false;
  24. executor.shutdown();
  25. }
  26. public void start() throws IOException {
  27. ServerSocket server = new ServerSocket();
  28. server.bind(new InetSocketAddress(port));
  29. System.out.println("start server");
  30. try {
  31. while (true) {
  32. // 1.监听客户端的TCP连接,接到TCP连接后将其封装成task,由线程池执行
  33. executor.execute(new ServiceTask(server.accept()));
  34. }
  35. } finally {
  36. server.close();
  37. }
  38. }
  39. public void register(Class serviceInterface, Class impl) {
  40. serviceRegistry.put(serviceInterface.getName(), impl);
  41. }
  42. public boolean isRunning() {
  43. return isRunning;
  44. }
  45. public int getPort() {
  46. return port;
  47. }
  48. private static class ServiceTask implements Runnable {
  49. Socket clent = null;
  50. public ServiceTask(Socket client) {
  51. this.clent = client;
  52. }
  53. public void run() {
  54. ObjectInputStream input = null;
  55. ObjectOutputStream output = null;
  56. try {
  57. // 2.将客户端发送的码流反序列化成对象,反射调用服务实现者,获取执行结果
  58. input = new ObjectInputStream(clent.getInputStream());
  59. String serviceName = input.readUTF();
  60. String methodName = input.readUTF();
  61. Class<?>[] parameterTypes = (Class<?>[]) input.readObject();
  62. Object[] arguments = (Object[]) input.readObject();
  63. Class serviceClass = serviceRegistry.get(serviceName);
  64. if (serviceClass == null) {
  65. throw new ClassNotFoundException(serviceName + " not found");
  66. }
  67. Method method = serviceClass.getMethod(methodName, parameterTypes);
  68. Object result = method.invoke(serviceClass.newInstance(), arguments);
  69. // 3.将执行结果反序列化,通过socket发送给客户端
  70. output = new ObjectOutputStream(clent.getOutputStream());
  71. output.writeObject(result);
  72. } catch (Exception e) {
  73. e.printStackTrace();
  74. } finally {
  75. if (output != null) {
  76. try {
  77. output.close();
  78. } catch (IOException e) {
  79. e.printStackTrace();
  80. }
  81. }
  82. if (input != null) {
  83. try {
  84. input.close();
  85. } catch (IOException e) {
  86. e.printStackTrace();
  87. }
  88. }
  89. if (clent != null) {
  90. try {
  91. clent.close();
  92. } catch (IOException e) {
  93. e.printStackTrace();
  94. }
  95. }
  96. }
  97. }
  98. }
  99. }

5)客户端的远程代理对象:

[java] view plaincopy
  1. package client;
  2. import java.io.ObjectInputStream;
  3. import java.io.ObjectOutputStream;
  4. import java.lang.reflect.InvocationHandler;
  5. import java.lang.reflect.Proxy;
  6. import java.net.InetSocketAddress;
  7. import java.net.Socket;
  8. import java.lang.reflect.Method;
  9. public class RPCClient<T> {
  10. @SuppressWarnings("unchecked")
  11. public static <T> T getRemoteProxyObj(final Class<?> serviceInterface, final InetSocketAddress addr) {
  12. // 1.将本地的接口调用转换成JDK的动态代理,在动态代理中实现接口的远程调用
  13. return (T) Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class<?>[] { serviceInterface },
  14. new InvocationHandler() {
  15. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  16. Socket socket = null;
  17. ObjectOutputStream output = null;
  18. ObjectInputStream input = null;
  19. try {
  20. // 2.创建Socket客户端,根据指定地址连接远程服务提供者
  21. socket = new Socket();
  22. socket.connect(addr);
  23. // 3.将远程服务调用所需的接口类、方法名、参数列表等编码后发送给服务提供者
  24. output = new ObjectOutputStream(socket.getOutputStream());
  25. output.writeUTF(serviceInterface.getName());
  26. output.writeUTF(method.getName());
  27. output.writeObject(method.getParameterTypes());
  28. output.writeObject(args);
  29. // 4.同步阻塞等待服务器返回应答,获取应答后返回
  30. input = new ObjectInputStream(socket.getInputStream());
  31. return input.readObject();
  32. } finally {
  33. if (socket != null)
  34. socket.close();
  35. if (output != null)
  36. output.close();
  37. if (input != null)
  38. input.close();
  39. }
  40. }
  41. });
  42. }
  43. }

6)最后为测试类:

[java] view plaincopy
  1. package client;
  2. import java.io.IOException;
  3. import java.net.InetSocketAddress;
  4. import services.HelloService;
  5. import services.Server;
  6. import services.impl.HelloServiceImpl;
  7. import services.impl.ServiceCenter;
  8. public class RPCTest {
  9. public static void main(String[] args) throws IOException {
  10. new Thread(new Runnable() {
  11. public void run() {
  12. try {
  13. Server serviceServer = new ServiceCenter(8088);
  14. serviceServer.register(HelloService.class, HelloServiceImpl.class);
  15. serviceServer.start();
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. }).start();
  21. HelloService service = RPCClient
  22. .getRemoteProxyObj(HelloService.class, new InetSocketAddress("localhost", 8088));
  23. System.out.println(service.sayHi("test"));
  24. }
  25. }

运行结果:

[java] view plaincopy
  1. regeist service HelloService
  2. start server
  3. Hi, test

转载于:https://www.cnblogs.com/juniorMa/p/7530777.html

通俗易懂的rpc原理相关推荐

  1. Dubbo:RPC原理

    1.RPC原理 一次完整的RPC调用流程如下: 1)服务消费方(client)调用以本地调用方式调用服务: 2)client stub接收到调用后负责将方法.参数等组装成能够进行网络传输的消息体: 3 ...

  2. 面试精讲之面试考点及大厂真题 - 分布式专栏 05 公司使用什么RPC框架,聊聊你理解的RPC原理

    05 公司使用什么RPC框架,聊聊你理解的RPC原理 引言 前些年我们在做一个规模不大的系统的时候,也就是单体架构,一台服务器部署上一个应用和数据库也就够了.但是现代化互联网公司业务逐渐扩大,服务逐渐 ...

  3. 从零开始实现RPC框架 - RPC原理及实现

    从零开始实现RPC框架 - RPC原理及实现 RPC概述 RPC(Remote Procedure Call)即远程过程调用,允许一台计算机调用另一台计算机上的程序得到结果,而代码中不需要做额外的编程 ...

  4. Dubbo(RPC原理、Dubbo架构负载均衡配置方式)(1)

    1.什么是 Dubbo? Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能.轻量级的开源Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错 ...

  5. 分布式 - 公司使用什么RPC框架,聊聊你理解的RPC原理

    不啰嗦,我们直接开始! 引言 以前在做一个规模不大的系统的时候,用的是单体架构,一台服务器部署上一个应用和数据库也就够了. 但是现代化互联网公司业务逐渐扩大,服务逐渐细分,很多服务之间需要通过远程分布 ...

  6. RPC原理(1)之深入RPC原理简介

    一.RPC调用原理图 下面这张图是我们微服务一次Http调用请求图: 首先在请求的过程中我们知道是有三次握手,四次挥手的流程,具体流程如下: 1.浏览器请求服务器(订单服务),请求建立连接,首先客户端 ...

  7. java-五十七天---深度剖析java核心技术(微服务、CAP帽子理论、配置中的超时和重试、RPC原理、序列化、注意)

    1   maven的好处 2 为什么要用微服务 3  CAP帽子理论(不能达到100%的C,即不能达到100%的数据一致性) 4  CAP帽子理论中的P 5  CAP帽子理论中的选择 6 微服务开发中 ...

  8. 什么是 RPC?RPC原理是什么?

    什么是 RPC?RPC原理是什么? 什么是 RPC? RPC(Remote Procedure Call)-远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.比 ...

  9. 深度解析xxl-rpc之RPC原理

    一.什么是RPC? RPC(remote process  call),中文是远程过程调用的意思.怎么理解这个远程过程调用呢?可以这样理解,可以与本地的过程调用对比下,本地过程调用,也就是调用函数或者 ...

最新文章

  1. Java:在Bean中使用PropertyChangeSupport支持PropertyChangeListeners
  2. 夏瑞、陈程杰报告—科研神器TBtools 从“结识”到“结伴”(下午3点腾讯会议)...
  3. 文件格式和扩展名不匹配.文件可能已损坏_自媒体良器:音频文件批处理,FFmpeg一行搞定!果断收藏...
  4. python爬虫requests-Python爬虫(requests模块)
  5. 几种进程间的通信方式
  6. Python视频编辑库:MoviePy
  7. FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
  8. P5163-WD与地图【tarjan,整体二分,线段树合并】
  9. 讯飞智能录音笔SR101:考研的温暖陪伴
  10. 7种主流案例,告诉你调度器架构设计通用法则(干货!)
  11. 毫米波雷达探测技术,雷达人体存在感应器,实时检测静止存在应用
  12. 计算机系大学生为什么选择在CSDN写博客?
  13. 微信个人号有哪些好玩的自动回复?自动回复话术分享
  14. 【NLP】千呼万唤始出来——GPT-3终于开源!
  15. Servlet作用域对象
  16. 【优秀课设】基于Linux粤嵌GEC6818开发板的电子乐队程序设计(四种模式:和弦模式、键盘模式、鼓点模式、编曲模式)
  17. 初识Cura3D打印开源项目
  18. 智慧城市背景下智慧消防建设的SWOT分析
  19. 带你了解什么是Nginx(实操反向代理-负载均衡)
  20. 服务器系统防火墙设置在哪里设置方法,服务器怎么设置防火墙设置在哪里

热门文章

  1. 基于流程的多维度企业管理框架(第三稿)
  2. 在VB中如何让背景图片铺满整个MDIForm
  3. 测试你的样子长得美与丑「超准的测试」
  4. 等级考试(二):二级C++---宏观把控
  5. 程序员的“数学修炼手册”,帮你快速恶补数学知识 | 资源
  6. 微信小程序,自动滑动到页面底部功能
  7. 1.4.1bat脚本命令COPY 拷贝 复制到
  8. C/C++ 指针小结——指针的概念和如何使用指针
  9. 更新智能开发研发进度
  10. 不懂得使用工具的测试不是好测试