rpc_rpca - CSDN
rpc 订阅
RPC是远程过程调用(Remote Procedure Call)的缩写形式。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。 展开全文
RPC是远程过程调用(Remote Procedure Call)的缩写形式。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。
信息
外文名
Remote Procedure Call
作    用
对数据进行处理后显示或打印
中文名
远程过程调用
缩写形式
RPC
远程过程调用简介
进程间通信(IPC)是在多任务操作系统或联网的计算机之间运行的程序和进程所用的通信技术。有两种类型的进程间通信(IPC)。本地过程调用(LPC)LPC用在多任务操作系统中,使得同时运行的任务能互相会话。这些任务共享内存空间使任务同步和互相发送信息。 远程过程调用(RPC)RPC类似于LPC,只是在网上工作。RPC开始是出现在Sun微系统公司和HP公司的运行UNⅨ操作系统的计算机中。
收起全文
精华内容
参与话题
  • 什么是RPC? RPC是什么?

    千次阅读 2018-01-16 20:10:37
    什么是RPC 以下摘自百度百科 远程过程调用协议 RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底>层网络技术的协议。RPC协议假定某些传输协议的...

    写在前面: 技术,不要那么复杂

    什么是RPC

    以下摘自百度百科

    远程过程调用协议

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

    术语可能有复杂,那我们要怎么去理解RPC呢?

    我眼中的RPC

    服务提供者提供 —- 消费者消费
    服务提供者在青岛捞海鲜,消费者坐在新疆的餐馆里点了一盘麻辣小龙虾
    这中间的过程就是RPC

    存在即合理,复杂的东西之所以能持续存在并发展不是无缘无故的,更不是因为高手们故弄玄虚,主要是它能带来某些明显的好处,你对这些东西掌握的越熟练,你会越喜欢它。关于RPC,很早以前的RPC也有其他几种比如DCOM,CORBA,RMI(Java)AXIS等,现在花样就多了去了,基本道理都是用XML或者JSON来传递调用参数和结果。个人体会主要用到的优势是如下几点:
    1. RPC能够跨多种开发工具及平台,比如说企业已有的系统开发完毕或者子系统已经部署交付了,它提供了RPC接口,新的子系统要集成,使用业界通用的RPC接口就可以集成了,你不可能要求原来的开发商再来修改一遍接口,否则的话就变成了信息孤岛;
    2. RPC能够跨多个服务器,这个在其他计算机上很容易透过80端口的RPC来访问各个服务器。其他如TCP消息来访问,尽管高效但不方便而且还要穿透防火墙,尤其不方便网页集成。

    举个栗子

    将复杂的事情弄得粗浅易懂,说着简单,做着复杂.可以看看复杂度守恒定律

    远程调用简单说就是发送一个请求给远程机器,远程机器返回一个结果回来的过程,为什么要这么做,单台服务器的性能远远不能满足现在互联网这个体量的用户的需求,就好比你去肯德基点个餐,餐台的服务员把薯条鸡腿汉堡的任务分给不同的人,然后收集起来给你的过程,餐台服务员就相当于调用远程服务.
    但假如不这么做,点餐员直接做这些事情(又得点餐,又得炸薯条,炸鸡腿等等),两相比较,你就知道远程调用有什么好处了

    简单来说就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如比如不同的系统间的通讯,甚至不同的组织间的通讯。由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。

    RPC优缺点

    RPC的优点:
    1. 提升系统可扩展性
    2. 提升系统可维护性和持续交付能力
    3. 实现系统高可用

    RPC的缺点:
    1. 一个完善的RPC框架开发难度大,需要人员配置多
    2. RPC框架调用成功率受限于网络状况
    3. 调用远程方法对初学者来说难度大

    展开全文
  • 常用的RPC框架

    万次阅读 多人点赞 2018-06-26 09:03:25
    1. 为什么要使用RPCRPC(remote procedure call)是指远程过程调用,比如两台服务器A和B,A服务器上部署一个应用,B服务器上部署一个应用,A服务器上的应用想调用B服务器上的应用提供的接口,由于不在一个内存...

    1. 为什么要使用RPC?

    RPC(remote procedure call)是指远程过程调用,比如两台服务器A和B,A服务器上部署一个应用,B服务器上部署一个应用,A服务器上的应用想调用B服务器上的应用提供的接口,由于不在一个内存空间,不能直接调用,所以需要通过网络来表达调用的语义和传达调用的数据。

    RPC(remote procedure call,远程过程调用):

    • 首先,要解决通讯的问题,主要是通过客户端和服务器端之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享一个连接。
    • 第二,要解决寻址的问题,A服务器上的应用要调用B服务器上的应用,A服务器上的应用需要通过底层RPC框架得知:如何连接到B服务器(主机或IP地址)以及特定的端口,方法的名称等信息,这样才能完成调用。
    • 第三,A服务器上的应用发起远程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数需要序列化成二进制形式,然后再通过寻址和传输将序列化的二进制发送给B服务器。
    • 第四:B服务器收到请求后,需要进行反序列化,恢复为内存中的表达方式,然后找到对应的方法进行本地调用并返回,序列化返回值并发送给A服务器。
    • 第五:A服务器收到B服务器的返回值后,进行反序列化,恢复为内存中的表达方式,然后交给A服务器上的应用进行处理。


    RPC的协议有很多,比如Java RMI、WebService的RPC风格、Hession、Thrift、REST API

    2. RPC、RMI、SOAP、REST的区别

    RMI(remote method invocation,面向对象的远程方法调用)
    RPCremote procedure call,远程过程调用)
    SOAP(simple object access protoal,简单对象访问协议)
    REST(representational state transfer,表达性状态转移)

    以都理解为调用远程方法的一些通信技术“风格”:

    · RMI就好比它是本地工作,采用tcp/ip协议,客户端直接调用服务端上的一些方法。优点是强类型,编译期可检查错误,缺点是只能基于JAVA语言,客户机与服务器紧耦合。

    · RPC是一个泛化的概念,严格来说一切远程过程调用手段都属于rpc范畴,包括rmi、hessian、soap、thrift、protobuf等等。

    · SOAP是在XML-RPC基础上,使用标准的XML描述了RPC的请求信息(URI/类/方法/参数/返回值)。因为XML-RPC只能使用有限的数据类型种类和一些简单的数据结构,SOAP能支持更多的类型和数据结构。优点是跨语言,非常适合异步通信和针对松耦合的C/S,缺点是必须做很多运行时检查。

    · REST一般用来和SOAP做比较,它采用简单的URL方式来代替一个对象,优点是轻量,可读性较好,不需要其他类库支持,缺点是URL可能会很长,不容易解析。


    3. Java RMI

    Java RMI(Romote Method Invocation)是一种基于Java的远程方法调用技术,是Java特有的一种RPC实现。它能够部署在不同主机上的Java对象之间进行透明的通信与方法调用。

    RMI工作原理:


    首先,在一个JVM中启动rmiregistry服务,启动时可以指定服务监听的端口,也可以使用默认的端口。

    其次,RMIServer在本地先实例化一个提供服务的实现类,然后通过RMI提供的Naming,Context,Registry等类的bind或rebind方法将刚才实例化好的实现类注册到RMIService上并对外暴露一个名称。

    最后,RMIClient通过本地的接口和一个已知的名称(即RMIServer暴露出的名称)再使用RMI提供的Naming,Context,Registry等类的lookup方法从RMIService那拿到实现类。这样虽然本地没有这个类的实现类,但所有的方法都在接口里了,想怎么调就怎么调。

    RMI 采用stubs 和 skeletons 来进行远程对象(remote object)的通讯。stub 充当远程对象的客户端代理,有着和远程对象相同的远程接口,远程对象的调用实际是通过调用该对象的客户端代理对象stub来完成的,通过该机制RMI就好比它是本地工作,采用tcp/ip协议,客户端直接调用服务端上的一些方法。优点是强类型,编译期可检查错误,缺点是只能基于Java语言,客户机与服务器紧耦合。

    具体RMI的原理可参考:java RMI原理详解

    深入理解rmi原理

    RMI使用Demo:

    定义RMI对外服务接口:RMI接口方法定义必须显示声明抛出RemoteException异常。

    package com.yyy.RMIDemo.java.server;
    
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    /**
     * RMI对外服务接口
     * @author 
     *
     */
    public interface HelloService extends Remote{
    	public String sayHello(String someone) throws RemoteException;
    }
    
    服务端接口实现:服务端方法实现必须继承UnicastRemoteObject类,该类定义了服务调用方与服务提供方对象实例,并建立一对一的连接。

    package com.yyy.RMIDemo.java.server;
    
    import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    
    /**
     * 服务器端接口实现
     * @author 
     *
     */
    public class HelloServiceImpl extends UnicastRemoteObject implements HelloService {
    
    	private static final long serialVersionUID = 4176511759435216154L;
    
    	protected HelloServiceImpl() throws RemoteException {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    
    	@Override
    	public String sayHello(String someone) throws RemoteException {
    		// TODO Auto- generated method stub
    		return "Hello" + someone;
    	}
    
    }
    

    RMI的通信端口是随机产生的,因此有可能被防火墙拦截,为了防止被防火墙拦截,需要强制指定RMI的通信端口。一般通过自定义一个RMISocketFactory类来实现,代码如下:

    package com.yyy.RMIDemo.java.server;
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.rmi.server.RMISocketFactory;
    
    public class CustomerSocketFactory extends RMISocketFactory{
    
    	
    	@Override
    	public ServerSocket createServerSocket(int port) throws IOException {
    		// TODO Auto-generated method stub
    		if (port == 0) {
    			port = 8051;
    		}
    		System.out.println("rmi notify port : " + port);
    		return new ServerSocket(port);
    	}
    
    	//指定通信端口,防止被防火墙拦截
    	@Override
    	public Socket createSocket(String host, int port) throws IOException {
    		// TODO Auto-generated method stub
    		return new Socket(host, port);
    	}
    
    }
    


    服务端RMI服务启动:

    package com.yyy.RMIDemo.java.server;
    
    import java.rmi.Naming;
    import java.rmi.registry.LocateRegistry;
    import java.rmi.server.RMISocketFactory;
    
    public class ServerMain {
    	public static void main(String[] args) throws Exception {
    		//创建服务
    		HelloService helloService = new HelloServiceImpl();
    		//注册服务
    		LocateRegistry.createRegistry(8801);
    		//指定通信端口,防止被防火墙拦截
    		RMISocketFactory.setSocketFactory(new CustomerSocketFactory());
    		
    		Naming.bind("rmi://localhost:8801/helloService", helloService);
    		
    		System.out.println("ServceMain provide service now");
    	}
    }
    

    客户端远程调用RMI服务代码:

    package com.yyy.RMIDemo.java.client;
    
    import java.rmi.Naming;
    
    import com.yyy.RMIDemo.java.server.HelloService;
    
    public class ClientMain {
    	public static void main(String[] args) throws Exception {
    		HelloService helloService = 
    				(HelloService)Naming.lookup("rmi://localhost:8801/helloService");
    		System.out.println("RMI 客户端接收到的结果是:" + helloService.sayHello("RMI"));
    	}
    }
    
    先运行服务器端程序ServerMain,然后运行ClinetMain,运行结果如下:

    RMI 客户端接收到的结果是:HelloRMI


    4. Hessia

    Hessian 是由 caucho 提供的一个基于 binary-RPC 实现的远程通讯 library 。Hessian基于Http协议进行传输。

    Binary-RPC 是一种和 RMI 类似的远程调用的协议,它和 RMI 的不同之处在于它以标准的二进制格式来定义请求的信息 ( 请求的对象、方法、参数等 ) ,这样的好处是什么呢,就是在跨语言通讯的时候也可以使用。传输协议基于TCP。

    Hessian可通过Servlet提供远程服务,需要将匹配某个模式的请求映射到Hessian服务。也可Spring框架整合,通过它的DispatcherServlet可以完成该功能,DispatcherServlet可将匹配模式的请求转发到Hessian服务。Hessian的server端提供一个servlet基类, 用来处理发送的请求,而Hessian的这个远程过程调用,完全使用动态代理来实现的,,建议采用面向接口编程,Hessian服务通过接口暴露。

    Hessian处理过程示意图:

    客户端——>序列化写到输出流——>远程方法(服务器端)——>序列化写到输出流 ——>客户端读取输入流——>输出结果

    Spring + Hessian实现服务器端的demo:

    在工程中导入hessian的jar包

    在web.xml中,我们配置SpringMVC的DispatcherServlet:

    	<!-- Spring hessian servlet -->
    	<servlet>  
    		<servlet-name>hessian</servlet-name>  
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    		<init-param>  
    			<param-name>contextConfigLocation</param-name>  
    			<param-value>classpath:spring-hessian.xml</param-value>  
    		</init-param>  
    		<load-on-startup>1</load-on-startup>  
    		<async-supported>true</async-supported>  
    	</servlet>  
    	<servlet-mapping>  
    		<servlet-name>hessian</servlet-name>  
    		<url-pattern>/pubservice/*</url-pattern>  
    	</servlet-mapping>
    spring-hessian.xml的配置:

    	<bean id="/testService" class="com.example.platform.hession.MyHessianServiceExporter">
    		<property name="service" ref="testServiceImpl" />
    		<property name="serviceInterface" value="com.xinwei.platform.pubservice.TestService" />	
    	</bean>

    使用了org.springframework.remoting.caucho.HessianServiceExporter来发布服务。将程序部署在tomcat中。如果我们想从HessianServiceExporter的handleRequest方法中可以获得客户端request,那我们就会有很多种方法得到此request;Aop方式或重写方法,我们采用重写的方式:

    /**
     * 
     */
    package com.example.platform.hession;
    
    import javax.servlet.ServletRequest;
    
    /**
     * Hession service线程上下文,用以线程安全地保存客户端request
     * @author yangyunyun
     *
     */
    public class HessionContext {
    	private ServletRequest request;
    	private static final ThreadLocal<HessionContext> localContext
    							= new ThreadLocal<HessionContext>(){
    		@Override
    		public HessionContext initialValue(){
    			return new HessionContext();
    		}	
    	};
    	
    	private HessionContext(){
    		
    	}
    
    
    	public static ServletRequest getRequest() {
    		return localContext.get().request;
    	}
    
    
    	public static void setRequest(ServletRequest request) {
    		localContext.get().request = request;
    	}
    	
    	public static void clear() {
    		localContext.get().request = null;
    	}
    	
    	
    	
    	
    }
    
    自定义类:

    /**
     * 
     */
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.remoting.caucho.HessianExporter;
    import org.springframework.web.HttpRequestHandler;
    import org.springframework.web.HttpRequestMethodNotSupportedException;
    import org.springframework.web.util.NestedServletException;
    
    /**
     * @author 
     *
     */
    public class MyHessianServiceExporter extends HessianExporter implements HttpRequestHandler {
    
    	private static final Logger logger = LoggerFactory.getLogger(InmpServiceExporter.class);
    		
    
    	@Override
    	public void handleRequest(HttpServletRequest request, 
    								HttpServletResponse response)
    								throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		if (!"POST".equals(request.getMethod())){
    			throw new HttpRequestMethodNotSupportedException(
    					request.getMethod(), new String[]{"POST"},
    					"HessionSeriviceExporter only supports POST requests");
    		}
    		response.setContentType(CONTENT_TYPE_HESSIAN);
    		try {
    			//保存request到Hession线程上下文
    			HessionContext.setRequest(request);
    			invoke(request.getInputStream(), response.getOutputStream());
    		} catch (Throwable ex) {
    			// TODO: handle exception
    			logger.error("Hession skeleton invocation failed");
    			throw new NestedServletException("Hession skeleton invocation failed", ex);
    		} finally{
    			HessionContext.clear();
    		}
    		
    		
    	}
    
    }
    
    Service开发中就可以直接使用 HessianContext.getRequest(); 来获得客户端的request了,所有的客户端信息随你所用了,而且是线程安全的。

    服务器端服务接口:

    package com.example.platform.pubservice;
    
    public interface TestService {
    	public String sayHello(String datas);
    }
    
    接口实现类:


    package com.example.platform.pubservice.impl;
    
    import com.example.platform.pubservice.TestService;
    
    public class TestServiceImpl extends InmpHessianHandle implements TestService{
    
    	@Override
    	public String sayHello(String datas) {
    		// TODO Auto-generated method stub
    		return "Hello " + datas;
    	}
    
    }
    client调用:

    public class TestClient {
        public static void main(String[] args) {
            try {
                String url = "http://localhost:8080/HessianDemo/pubservice/testService";
                HessianProxyFactory factory = new HessianProxyFactory();
                factory.setOverloadEnabled(true);
                TestService testService = (TestService) factory.create(TestService.class, url);
                System.out.println(basic.sayHello("SW"));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    Hessian的原理以及使用请参考: Hessian的使用以及理解

    5. WebService

    WebService是一种跨平台的RPC技术协议。WebService技术栈由SOAP(简单对象访问协议)、UDDI(统一描述、发现与集成)、WSDL(网络服务描述语言:用来描述Service、以及如何访问WebService)组成。SOAP是一种使用XML进行数据编码的通信协议。独立于平台、独立于语言,简单可扩展。

    WebService常用的两种实现:CXF和Axis2

    详解见 从零开始写分布式服务框架 1.3小节

    目前三种主流的web服务实现方法:

    REST(新型):表象化状态转变 (软件架构风格)RESTEasy、Wink、CXF、Axis2…….

    SOAP(比较成熟):简单对象访问协议  Xfire、Axis2、CXF、Axis1

    XML-RPC(淘汰):远程过程调用协议(慢慢被soap 所取代)

    1、Java开发WebService最重要的两个规范:

    JSR-224 (JAX-WS:Java API for XML-Based Web Services ) ,主要使用soap协议,使用wsdl来描述;

    JSR-311 (JAX-RSThe Java API for RESTful Web Services)简化了 web service 的设计,它不再需要 wsdl ,也不再需要 soap 协议,而是通过最简单的 http 协议传输数据 ( 包括 xml  json) 。既简化了设计,也减少了网络传输量(因为只传输代表数据的 xml  json ,没有额外的 xml 包装)。

    JAX-WS是针对WebService。而JAX-RS是针对RESTful HTTP Service。

    RESTful HTTP Service相关介绍可以参考:RESTful Service API 设计最佳工程实践和常见问题解决方案

    JAX-WS与JAX-RS两者是不同风格的SOA架构。前者以动词为中心,指定的是每次执行函数。而后者以名词为中心,每次执行的时候指的是资源。

    JAX-RS是JAVA EE6 引入的一个新技术。是一个Java 编程语言的应用程序接口,支持按照表述性状态转移(REST)架构风格创建Web服务。JAX-RS使用了Java SE5引入的Java标注来简化Web服务的客户端和服务端的开发和部署。
    JAX-WS规范是一组XML web services的JAVA API,JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。

    支持JAX-WS服务规范的框架有:CXF,Axis,Xfire。结合java语言均可可实现JAX-WS

    支持JAX-RS服务规范的框架有: 

    1.CXF——XFire和Celtix的合并 

    2.Jersey——Sun公司的JAX-RS参考实现。 

    3.RESTEasy——JBoss的JAX-RS项目。

    4.Restlet——也许是最早的REST框架了,它JAX-RS之前就有了。





    在分布式服务框架中,除了实现RPC的特性以外,还包括负载均衡策略以及实现,服务的注册、发布与引入。服务的高可用策略以及服务治理等特性。

    RESTful架构风格参考:RESTful 架构风格概述

    RESTful Web 服务:教程


    展开全文
  • RPC框架(一)RPC简介

    万次阅读 多人点赞 2018-03-02 17:11:03
    二、RPC 2.1、RPC定义 2.2、RPC主要组成部分 三、影响RPC框架性能的因素 四、工业界的 RPC 框架一览 4.1、国内 4.2、国外 五、如何选择RPC框架 一、概述 随着公司规模的扩大,以及业务量的激增,单体应用...

    一、概述

    随着公司规模的扩大,以及业务量的激增,单体应用逐步演化为服务/微服务的架构模式, 服务之间的调用大多采用rpc的方式调用,或者消息队列的方式进行解耦。几乎每个大厂都会创建自己的rpc框架,或者基于知名的rpc框架进行改造。

    目前, rpc框架主要沿着两条路线发展,一个是目标为了跨语言,服务端可以用不同的语言实现,客户端也可以用不同的语言实现,不同的语言实现的客户端和服务器端可以互相调用。很显然,要支持不同的语言,需要基于那种语言实现相同协议的框架,并且协议设计应该也是跨语言的,其中比较典型的是 grpc,基于同一个IDL,可以生成不同语言的代码,并且语言的支持也非常的多。

    另一个rpc框架发展的目标是支持服务治理,主要的精力放在服务发现、路由、容错处理等方面,主要围绕一个语言开发,可能也有一些第三方曲折的实现服务的调用和服务的实现,这其中的代表,也是比较早的开源的框架就是阿里巴巴的dubbo。

    有些rpc框架协议的涉及一开始就没有考虑的跨语言,其中使用了语言的一些特有的属性,比如Java的ObjectInputStream/ObjectOutputStream, Golang的Gob等,有些在协议的设计上就考虑了通用性, 使用JSON或者Protobuffer作为数据序列化。

    有些框架是基于TCP的二进制流的数据传输,有些基于http的request/response模型进行请求,也有基于http2的流式传输,更有一些支持可信赖的UDP进行数据传入,比如quic、kcp等。

    有些提供了生态圈的一些框架,比如gateway、agent等,有些restful风格的rpc框架天然支持API gateway进行负载均衡。

    二、RPC

    2.1、RPC定义

    RPC(Remote Procedure Call Protocol)远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。比较正式的描述是:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。那么我们至少从这样的描述中挖掘出几个要点:

    • RPC是协议:既然是协议就只是一套规范,那么就需要有人遵循这套规范来进行实现。目前典型的RPC实现包括:Dubbo、Thrift、GRPC、Hetty等。这里要说明一下,目前技术的发展趋势来看,实现了RPC协议的应用工具往往都会附加其他重要功能,例如Dubbo还包括了服务治等功能。

    • 网络协议和网络IO模型对其透明:既然RPC的客户端认为自己是在调用本地对象。那么传输层使用的是TCP/UDP还是HTTP协议,又或者是一些其他的网络协议它就不需要关心了。既然网络协议对其透明,那么调用过程中,使用的是哪一种网络IO模型调用者也不需要关心。

    • 信息格式对其透明:我们知道在本地应用程序中,对于某个对象的调用需要传递一些参数,并且会返回一个调用结果。至于被调用的对象内部是如何使用这些参数,并计算出处理结果的,调用方是不需要关心的。那么对于远程调用来说,这些参数会以某种信息格式传递给网络上的另外一台计算机,这个信息格式是怎样构成的,调用方是不需要关心的。

    • 应该有跨语言能力:为什么这样说呢?因为调用方实际上也不清楚远程服务器的应用程序是使用什么语言运行的。那么对于调用方来说,无论服务器方使用的是什么语言,本次调用都应该成功,并且返回值也应该按照调用方程序语言所能理解的形式进行描述。

    那么上面的描述情况可以用下图表示:

    这里写图片描述

    2.2、RPC主要组成部分

    当然,上图是作为RPC的调用者所观察到的现象(而实际情况是客户端或多或少的还是需要知道一些调用RPC的细节)。但是我们是要讲解RPC的基本概念,所以RPC协议内部是怎么回事就要说清楚:

    这里写图片描述

    • Client:RPC协议的调用方。就像上文所描述的那样,最理想的情况是RPC Client在完全不知道有RPC框架存在的情况下发起对远程服务的调用。但实际情况来说Client或多或少的都需要指定RPC框架的一些细节。

    • Server:在RPC规范中,这个Server并不是提供RPC服务器IP、端口监听的模块。而是远程服务方法的具体实现(在JAVA中就是RPC服务接口的具体实现)。其中的代码是最普通的和业务相关的代码,甚至其接口实现类本身都不知道将被某一个RPC远程客户端调用。

    • Stub/ProxyRPC代理存在于客户端,因为要实现客户端对RPC框架“透明”调用,那么客户端不可能自行去管理消息格式、不可能自己去管理网络传输协议,也不可能自己去判断调用过程是否有异常。这一切工作在客户端都是交给RPC框架中的“代理”层来处理的

    • Message Protocol:在上文我们已经说到,一次完整的client-server的交互肯定是携带某种两端都能识别的,共同约定的消息格式。RPC的消息管理层专门对网络传输所承载的消息信息进行编码和解码操作。目前流行的技术趋势是不同的RPC实现,为了加强自身框架的效率都有一套(或者几套)私有的消息格式。

    • Transfer/Network Protocol传输协议层负责管理RPC框架所使用的网络协议、网络IO模型。例如Hessian的传输协议基于HTTP(应用层协议);而Thrift的传输协议基于TCP(传输层协议)。传输层还需要统一RPC客户端和RPC服务端所使用的IO模型;

    • Selector/Processor:存在于RPC服务端,用于服务器端某一个RPC接口的实现的特性(它并不知道自己是一个将要被RPC提供给第三方系统调用的服务)。所以在RPC框架中应该有一种“负责执行RPC接口实现”的角色。包括:管理RPC接口的注册、判断客户端的请求权限、控制接口实现类的执行在内的各种工作。

    • IDL:实际上IDL(接口定义语言)并不是RPC实现中所必须的。但是需要跨语言的RPC框架一定会有IDL部分的存在。这是因为要找到一个各种语言能够理解的消息结构、接口定义的描述形式。如果您的RPC实现没有考虑跨语言性,那么IDL部分就不需要包括,例如JAVA RMI因为就是为了在JAVA语言间进行使用,所以JAVA RMI就没有相应的IDL。

    一定要说明一点,不同的RPC框架实现都有一定设计差异。例如生成Stub的方式不一样,IDL描述语言不一样、服务注册的管理方式不一样、运行服务实现的方式不一样、采用的消息格式封装不一样、采用的网络协议不一样。但是基本的思路都是一样的,上图中的所列出的要素也都是具有的。

    三、影响RPC框架性能的因素

    这里写图片描述

    在物理服务器性能相同的情况下,以下几个因素会对一款RPC框架的性能产生直接影响:

    • 使用的网络IO模型:RPC服务器可以只支持传统的阻塞式同步IO,也可以做一些改进让RPC服务器支持非阻塞式同步IO,或者在服务器上实现对多路IO模型的支持。这样的RPC服务器的性能在高并发状态下,会有很大的差别。特别是单位处理性能下对内存、CPU资源的使用率。

    • 基于的网络协议:一般来说您可以选择让您的RPC使用应用层协议,例如HTTP或者HTTP/2协议,或者使用TCP协议,让您的RPC框架工作在传输层。工作在哪一层网络上会对RPC框架的工作性能产生一定的影响,但是对RPC最终的性能影响并不大。但是至少从各种主流的RPC实现来看,没有采用UDP协议做为主要的传输协议的。

    • 消息封装格式:选择或者定义一种消息格式的封装,要考虑的问题包括:消息的易读性、描述单位内容时的消息体大小、编码难度、解码难度、解决半包/粘包问题的难易度。当然如果您只是想定义一种RPC专用的消息格式,那么消息的易读性可能不是最需要考虑的。消息封装格式的设计是目前各种RPC框架性能差异的最重要原因,这就是为什么几乎所有主流的RPC框架都会设计私有的消息封装格式的原因。dubbo中消息体数据包含dubbo版本号、接口名称、接口版本、方法名称、参数类型列表、参数、附加信息

    • Schema 和序列化(Schema & Data Serialization):序列化和反序列化,是对象到二进制数据的转换,程序是可以理解对象的,对象一般含有 schema 或者结构,基于这些语义来做特定的业务逻辑处理。考察一个序列化框架一般会关注以下几点:
      Encoding format 。是 human readable(是否能直观看懂 json) 还是 binary(二进制)。
      Schema declaration 。也叫作契约声明,基于 IDL,比如 Protocol Buffers/Thrift,还是自描述的,比如 JSON、XML。另外还需要看是否是强类型的。
      语言平台的中立性 。比如 Java 的 Native Serialization 就只能自己玩,而 Protocol Buffers 可以跨各种语言和平台。
      新老契约的兼容性 。比如 IDL 加了一个字段,老数据是否还可以反序列化成功。
      和压缩算法的契合度 。跑 benchmark (基准)和实际应用都会结合各种压缩算法,例如 gzip、snappy。
      性能 。这是最重要的,序列化、反序列化的时间,序列化后数据的字节大小是考察重点。
      序列化方式非常多,常见的有 Protocol Buffers, Avro,Thrift,XML,JSON,MessagePack,Kyro,Hessian,Protostuff,Java Native Serialize,FST 。

    • 实现的服务处理管理方式:在高并发请求下,如何管理注册的服务也是一个性能影响点。您可以让RPC的Selector/Processor使用单个线程运行服务的具体实现(这意味着上一个客户端的请求没有处理完,下一个客户端的请求就需要等待)、您也可以为每一个RPC具体服务的实现开启一个独立的线程运行(可以一次处理多个请求,但是操作系统对于“可运行的最大线程数”是有限制的)、您也可以线程池来运行RPC具体的服务实现(目前看来,在单个服务节点的情况下,这种方式是比较好的)、您还可以通过注册代理的方式让多个服务节点来运行具体的RPC服务实现。

    四、工业界的 RPC 框架一览

    4.1、国内

    Dubbo 。来自阿里巴巴 http://dubbo.I/O/
    Motan 。新浪微博自用 https://github.com/weibocom/motan
    Dubbox 。当当基于 dubbo 的 https://github.com/dangdangdotcom/dubbox
    rpcx 。基于 Golang 的 https://github.com/smallnest/rpcx

    4.2、国外

    Thrift from facebook https://thrift.apache.org
    Avro from hadoop https://avro.apache.org
    Finagle by twitter https://twitter.github.I/O/finagle
    gRPC by Google http://www.grpc.I/O (Google inside use Stuppy)
    Hessian from cuacho http://hessian.caucho.com
    Coral Service inside amazon (not open sourced)
    上述列出来的都是现在互联网企业常用的解决方案,暂时不考虑传统的 SOAP,XML-RPC 等。这些是有网络资料的,实际上很多公司内部都会针对自己的业务场景,以及和公司内的平台相融合(比如监控平台等),自研一套框架,但是殊途同归,都逃不掉刚刚上面所列举的 RPC 的要考虑的各个部分。

    五、如何选择RPC框架

    选择一个rpc框架会基于多方面的考虑: 框架特性、性能、成熟度、技术支持、社区活跃度等多个方面。最重要一点,这也是往往很多技术人员进入的误区,“对于技术,不要为了使用而使用,用最简单合适的技术实现解决问题才是正道”。架构是服务于业务的,能快速方便的满足业务需求的架构才是好的架构。没有最好的,只有适合自己的。

    展开全文
  • 深入浅出 RPC - 深入篇

    万次阅读 多人点赞 2018-10-31 20:14:44
    《深入篇》我们主要围绕 RPC 的功能目标和实现考量去展开,一个基本的 RPC 框架应该提供什么功能,满足什么要求以及如何去实现它?   RPC 功能目标 RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供...

     

    《深入篇》我们主要围绕 RPC 的功能目标和实现考量去展开,一个基本的 RPC 框架应该提供什么功能,满足什么要求以及如何去实现它?

     

    RPC 功能目标

    RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制让使用者不必显式的区分本地调用和远程调用,在前文《浅出篇》中给出了一种实现结构,基于 stub 的结构来实现。下面我们将具体细化 stub 结构的实现。

     

    RPC 调用分类

    RPC 调用分以下两种:

    1. 同步调用
       客户方等待调用执行完成并返回结果。
    2. 异步调用
       客户方调用后不用等待执行结果返回,但依然可以通过回调通知等方式获取返回结果。
       若客户方不关心调用返回结果,则变成单向异步调用,单向调用不用返回结果。
    

    异步和同步的区分在于是否等待服务端执行完成并返回结果。

     

    RPC 结构拆解

    《浅出篇》给出了一个比较粗粒度的 RPC 实现概念结构,这里我们进一步细化它应该由哪些组件构成,如下图所示。

    RPC 服务方通过 RpcServer 去导出(export)远程接口方法,而客户方通过 RpcClient 去引入(import)远程接口方法。客户方像调用本地方法一样去调用远程接口方法,RPC 框架提供接口的代理实现,实际的调用将委托给代理RpcProxy 。代理封装调用信息并将调用转交给RpcInvoker 去实际执行。在客户端的RpcInvoker 通过连接器RpcConnector 去维持与服务端的通道RpcChannel,并使用RpcProtocol 执行协议编码(encode)并将编码后的请求消息通过通道发送给服务方。

    RPC 服务端接收器 RpcAcceptor 接收客户端的调用请求,同样使用RpcProtocol 执行协议解码(decode)。解码后的调用信息传递给RpcProcessor 去控制处理调用过程,最后再委托调用给RpcInvoker 去实际执行并返回调用结果。

     

    RPC 组件职责

    上面我们进一步拆解了 RPC 实现结构的各个组件组成部分,下面我们详细说明下每个组件的职责划分。

    1. RpcServer
       负责导出(export)远程接口
    2. RpcClient
       负责导入(import)远程接口的代理实现
    3. RpcProxy
       远程接口的代理实现
    4. RpcInvoker
       客户方实现:负责编码调用信息和发送调用请求到服务方并等待调用结果返回
       服务方实现:负责调用服务端接口的具体实现并返回调用结果
    5. RpcProtocol
       负责协议编/解码
    6. RpcConnector
       负责维持客户方和服务方的连接通道和发送数据到服务方
    7. RpcAcceptor
       负责接收客户方请求并返回请求结果
    8. RpcProcessor
       负责在服务方控制调用过程,包括管理调用线程池、超时时间等
    9. RpcChannel
       数据传输通道
    

     

    RPC 实现分析

    在进一步拆解了组件并划分了职责之后,这里以在 java 平台实现该 RPC 框架概念模型为例,详细分析下实现中需要考虑的因素。

    导出远程接口

    导出远程接口的意思是指只有导出的接口可以供远程调用,而未导出的接口则不能。在 java 中导出接口的代码片段可能如下:

    DemoService demo   = new ...;
    RpcServer   server = new ...;
    server.export(DemoService.class, demo, options);
    

    我们可以导出整个接口,也可以更细粒度一点只导出接口中的某些方法,如:

    // 只导出 DemoService 中签名为 hi(String s) 的方法
    server.export(DemoService.class, demo, "hi", new Class<?>[] { String.class }, options);
    

    java 中还有一种比较特殊的调用就是多态,也就是一个接口可能有多个实现,那么远程调用时到底调用哪个?这个本地调用的语义是通过 jvm 提供的引用多态性隐式实现的,那么对于 RPC 来说跨进程的调用就没法隐式实现了。如果前面DemoService 接口有 2 个实现,那么在导出接口时就需要特殊标记不同的实现,如:

    DemoService demo   = new ...;
    DemoService demo2  = new ...;
    RpcServer   server = new ...;
    server.export(DemoService.class, demo, options);
    server.export("demo2", DemoService.class, demo2, options);
    

    上面 demo2 是另一个实现,我们标记为 "demo2" 来导出,那么远程调用时也需要传递该标记才能调用到正确的实现类,这样就解决了多态调用的语义。

    导入远程接口与客户端代理

    导入相对于导出远程接口,客户端代码为了能够发起调用必须要获得远程接口的方法或过程定义。目前,大部分跨语言平台 RPC 框架采用根据 IDL 定义通过 code generator 去生成 stub 代码,这种方式下实际导入的过程就是通过代码生成器在编译期完成的。我所使用过的一些跨语言平台 RPC 框架如 CORBAR、WebService、ICE、Thrift 均是此类方式。

    代码生成的方式对跨语言平台 RPC 框架而言是必然的选择,而对于同一语言平台的 RPC 则可以通过共享接口定义来实现。在 java 中导入接口的代码片段可能如下:

    RpcClient client = new ...;
    DemoService demo = client.refer(DemoService.class);
    demo.hi("how are you?");
    

    在 java 中 'import' 是关键字,所以代码片段中我们用 refer 来表达导入接口的意思。这里的导入方式本质也是一种代码生成技术,只不过是在运行时生成,比静态编译期的代码生成看起来更简洁些。java 里至少提供了两种技术来提供动态代码生成,一种是 jdk 动态代理,另外一种是字节码生成。动态代理相比字节码生成使用起来更方便,但动态代理方式在性能上是要逊色于直接的字节码生成的,而字节码生成在代码可读性上要差很多。两者权衡起来,个人认为牺牲一些性能来获得代码可读性和可维护性显得更重要。

    协议编解码

    客户端代理在发起调用前需要对调用信息进行编码,这就要考虑需要编码些什么信息并以什么格式传输到服务端才能让服务端完成调用。出于效率考虑,编码的信息越少越好(传输数据少),编码的规则越简单越好(执行效率高)。我们先看下需要编码些什么信息:

    -- 调用编码 --
    1. 接口方法
       包括接口名、方法名
    2. 方法参数
       包括参数类型、参数值
    3. 调用属性
       包括调用属性信息,例如调用附件隐式参数、调用超时时间等
    
    -- 返回编码 --
    1. 返回结果
       接口方法中定义的返回值
    2. 返回码
       异常返回码
    3. 返回异常信息
       调用异常信息
    

    除了以上这些必须的调用信息,我们可能还需要一些元信息以方便程序编解码以及未来可能的扩展。这样我们的编码消息里面就分成了两部分,一部分是元信息、另一部分是调用的必要信息。如果设计一种 RPC 协议消息的话,元信息我们把它放在协议消息头中,而必要信息放在协议消息体中。下面给出一种概念上的 RPC 协议消息设计格式:

     

    -- 消息头 --
    magic      : 协议魔数,为解码设计
    header size: 协议头长度,为扩展设计
    version    : 协议版本,为兼容设计
    st         : 消息体序列化类型
    hb         : 心跳消息标记,为长连接传输层心跳设计
    ow         : 单向消息标记,
    rp         : 响应消息标记,不置位默认是请求消息
    status code: 响应消息状态码
    reserved   : 为字节对齐保留
    message id : 消息 id
    body size  : 消息体长度
    
    -- 消息体 --
    采用序列化编码,常见有以下格式
    xml   : 如 webservie soap
    json  : 如 JSON-RPC
    binary: 如 thrift; hession; kryo 等
    

    格式确定后编解码就简单了,由于头长度一定所以我们比较关心的就是消息体的序列化方式。序列化我们关心三个方面:

    1. 序列化和反序列化的效率,越快越好。
    2. 序列化后的字节长度,越小越好。
    3. 序列化和反序列化的兼容性,接口参数对象若增加了字段,是否兼容。

    上面这三点有时是鱼与熊掌不可兼得,这里面涉及到具体的序列化库实现细节,就不在本文进一步展开分析了。

    传输服务

    协议编码之后,自然就是需要将编码后的 RPC 请求消息传输到服务方,服务方执行后返回结果消息或确认消息给客户方。RPC 的应用场景实质是一种可靠的请求应答消息流,和 HTTP 类似。因此选择长连接方式的 TCP 协议会更高效,与 HTTP 不同的是在协议层面我们定义了每个消息的唯一 id,因此可以更容易的复用连接。

    既然使用长连接,那么第一个问题是到底 client 和 server 之间需要多少根连接?实际上单连接和多连接在使用上没有区别,对于数据传输量较小的应用类型,单连接基本足够。单连接和多连接最大的区别在于,每根连接都有自己私有的发送和接收缓冲区,因此大数据量传输时分散在不同的连接缓冲区会得到更好的吞吐效率。所以,如果你的数据传输量不足以让单连接的缓冲区一直处于饱和状态的话,那么使用多连接并不会产生任何明显的提升,反而会增加连接管理的开销。

    连接是由 client 端发起建立并维持。如果 client 和 server 之间是直连的,那么连接一般不会中断(当然物理链路故障除外)。如果 client 和 server 连接经过一些负载中转设备,有可能连接一段时间不活跃时会被这些中间设备中断。为了保持连接有必要定时为每个连接发送心跳数据以维持连接不中断。心跳消息是 RPC 框架库使用的内部消息,在前文协议头结构中也有一个专门的心跳位,就是用来标记心跳消息的,它对业务应用透明。

    执行调用

    client stub 所做的事情仅仅是编码消息并传输给服务方,而真正调用过程发生在服务方。server stub 从前文的结构拆解中我们细分了 RpcProcessorRpcInvoker 两个组件,一个负责控制调用过程,一个负责真正调用。这里我们还是以 java 中实现这两个组件为例来分析下它们到底需要做什么?

    java 中实现代码的动态接口调用目前一般通过反射调用。除了原生的 jdk 自带的反射,一些第三方库也提供了性能更优的反射调用,因此 RpcInvoker 就是封装了反射调用的实现细节。

    调用过程的控制需要考虑哪些因素,RpcProcessor 需要提供什么样地调用控制服务呢?下面提出几点以启发思考:

    1. 效率提升
       每个请求应该尽快被执行,因此我们不能每请求来再创建线程去执行,需要提供线程池服务。
    2. 资源隔离
       当我们导出多个远程接口时,如何避免单一接口调用占据所有线程资源,而引发其他接口执行阻塞。
    3. 超时控制
       当某个接口执行缓慢,而 client 端已经超时放弃等待后,server 端的线程继续执行此时显得毫无意义。
    

     

    RPC 异常处理

    无论 RPC 怎样努力把远程调用伪装的像本地调用,但它们依然有很大的不同点,而且有一些异常情况是在本地调用时绝对不会碰到的。在说异常处理之前,我们先比较下本地调用和 RPC 调用的一些差异:

    1. 本地调用一定会执行,而远程调用则不一定,调用消息可能因为网络原因并未发送到服务方。
    2. 本地调用只会抛出接口声明的异常,而远程调用还会跑出 RPC 框架运行时的其他异常。
    3. 本地调用和远程调用的性能可能差距很大,这取决于 RPC 固有消耗所占的比重。

    正是这些区别决定了使用 RPC 时需要更多考量。当调用远程接口抛出异常时,异常可能是一个业务异常,也可能是 RPC 框架抛出的运行时异常(如:网络中断等)。业务异常表明服务方已经执行了调用,可能因为某些原因导致未能正常执行,而 RPC 运行时异常则有可能服务方根本没有执行,对调用方而言的异常处理策略自然需要区分。

    由于 RPC 固有的消耗相对本地调用高出几个数量级,本地调用的固有消耗是纳秒级,而 RPC 的固有消耗是在毫秒级。那么对于过于轻量的计算任务就并不合适导出远程接口由独立的进程提供服务,只有花在计算任务上时间远远高于 RPC 的固有消耗才值得导出为远程接口提供服务。

     

    总结

    至此我们提出了一个 RPC 实现的概念框架,并详细分析了需要考虑的一些实现细节。无论 RPC 的概念是如何优雅,但是“草丛中依然有几条蛇隐藏着”,只有深刻理解了 RPC 的本质,才能更好地应用。

     

    ----------------------------

    我的专栏,欢迎订阅交流

    展开全文
  • RPC的学习总结

    千次阅读 2019-08-20 11:24:46
    这两天看RPC确实有点迷,一些东西看了忘,忘了看!加上还有一些乱七八糟的事,感觉这两天需要整理一下思路,然后根据原理,来实现一个自己的RPC框架。 RPC是什么? RPC即远程过程调用,允许一台计算机调用另一台...
  • HTTP/RPC浅谈

    千次阅读 2019-07-02 17:08:18
    远程调用在平时开发中都经常会用到,一般常用的是http,webservice,rmi等 RPC 方式,我司用的内部RSF方式;下面来详细说一下,http和rpc的区别和联系,网上看了一圈和基于自己的理解。 http和rpc最大的区别:http是...
  • RPC和HTTP

    千次阅读 多人点赞 2018-12-05 20:16:57
    1.1.认识RPC RPC,即 Remote Procedure Call(远程过程调用),是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。说得通俗一点就是:A...
  • RPC服务

    千次阅读 2019-10-21 09:43:39
    很长时间以来都没有怎么好好搞清楚RPC(即Remote Procedure Call,远程过程调用)和HTTP调用的区别,不都是写一个服务然后在客户端调用么?这里请允许我迷之一笑~Naive!本文简单地介绍一下两种形式的C/S架构,先说...
  • RPC 基本原理和实现方式

    千次阅读 2019-09-29 23:08:04
    近几年随着微服务化项目的崛起,逐渐成为许多公司中大型分布式系统架构的主流方式,而今天所说的 RPC 在这其中扮演着至关重要的角色。随着这段日子公司项目微服务化的演进,发现在日常开发中都在隐式或显式的使用 ...
  • 什么是RPC

    千次阅读 多人点赞 2019-06-12 10:03:30
    “老公,什么是RPC呀,为什么你们程序员那么多黑话!”,老婆还是一如既往的好奇。 “RPC,就是Remote Procedure Call的简称呀,翻译成中文就是远程过程调用嘛”,我一边看着书,一边漫不经心的回答着。 “啥?你在...
  • RPC是什么?

    万次阅读 多人点赞 2016-12-04 12:54:32
    RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”。目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用。远程调用的应用场景极其广泛,实现的方式也...
  • RPC服务和HTTP服务对比

    万次阅读 多人点赞 2017-11-28 10:03:55
    很长时间以来都没有怎么好好搞清楚RPC(即Remote Procedure Call,远程过程调用)和HTTP调用的区别,不都是写一个服务然后在客户端调用么?这里请允许我迷之一笑~Naive!本文简单地介绍一下两种形式的C/S架构,先说...
  • RPC原理及实现

    千次阅读 2018-05-30 11:12:54
    为实现该目标,RPC 框架需提供一种透明调用机制让使用者不必显式的区分本地调用和远程调用。2 调用分类RPC 调用分以下两种:同步调用客户方等待调用执行完成并返回结果。异步调用客户方调用后...
  • RPC入门总结(一)RPC定义和原理

    万次阅读 多人点赞 2017-11-20 09:24:01
    转载:深入浅出 RPC - 浅出篇 转载:RPC框架与Dubbo完整使用 转载:深入浅出 RPC - 深入篇 一、RPC 1. RPC是什么 RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上...
  • 出现RPC服务器不可用的解决方法

    万次阅读 2017-01-03 15:47:42
    出现RPC服务器不可用的解决方法 RPC服务器,是指Remote Procedure Call Protocol,中文释义为(RFC-1831)远程过程调用协议:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。 当RPC...
  • 什么是RPC协议? RPC是一种远程过程调用的协议,使用这种协议向另一台计算机上的程序请求服务,不需要了解底层网络技术的协议。 在 RPC 中,发出请求的程序是客户程序,而提供服务的程序是服务器。 HTTP是一种超文本...
  • 使用postman测试RPC接口

    万次阅读 2018-12-27 14:50:51
    一般使用的接口类型都是http协议传输,第一次遇到RPC类型,使用postman进行测试。 请求方式get或者post并不影响, URL是在域名后面加了/rpc,例如,...“jsonrpc”:“2.0”, “method”:“eth_getBalance”, “para...
  • spring cloud和普通rpc框架的区别

    万次阅读 2019-04-19 18:00:06
    spring cloud和普通rpc框架的区别 rpc框架必要因素 spring cloud包括哪些 两个框架的比较
  • RPC的优点和缺点

    千次阅读 2018-09-04 11:30:13
    先说RPC的优点吧: 1. 提升系统可扩展性 2. 提升系统可维护性和持续交付能力 3. 实现系统高可用 RPC的缺点: 1. 一个完善的RPC框架开发难度大 2. RPC框架调用成功率受限于网络状况 3. 调用远程方法对初学者来...
  • JAVA中几种常用的RPC框架介绍

    万次阅读 2017-04-23 15:18:09
    点击打开链接
1 2 3 4 5 ... 20
收藏数 274,494
精华内容 109,797
关键字:

rpc