• [技术干货] ServerSocket实现RPC的方式
    Java RPC(远程过程调用)是一种允许程序在不同的计算机上调用另一个程序的共享功能的方法。在Java中,RPC是通过使用网络通信协议(如HTTP、TCP等)实现的。Java RPC的调用方式主要包括以下几个步骤:定义服务接口:首先需要定义一个接口,该接口包含了客户端需要调用的服务方法。这些方法应该使用简单的数据类型和void返回值。例如,我们可以定义一个简单的计算器接口,包含加法和减法方法:public interface Calculator { int add(int a, int b); int subtract(int a, int b); }实现服务端:接下来,需要实现这个接口,并在服务器端提供一个实例。服务器端的实现可以是一个独立的类,也可以是一个模块。在这个例子中,我们将实现一个简单的Calculator类:public class CalculatorImpl implements Calculator { @Override public int add(int a, int b) { return a + b; } @Override public int subtract(int a, int b) { return a - b; } }创建服务器:然后,需要创建一个服务器来监听客户端的请求。这可以通过使用Java的网络编程功能来实现。在这个例子中,我们将创建一个基于TCP的简单服务器:import java.io.*; import java.net.*; public class RpcServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8080); System.out.println("Server is listening on port 8080"); while (true) { Socket socket = serverSocket.accept(); System.out.println("New client connected"); InputStream inputStream = socket.getInputStream(); ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream()); outputStream.writeObject(new CalculatorImpl()); outputStream.flush(); socket.close(); } } }启动服务器:运行RpcServer类的main方法,启动服务器并监听8080端口。客户端可以通过连接到这个端口来调用远程服务。创建客户端:在客户端,我们需要创建一个代理对象,用于封装与服务器之间的通信。这个代理对象将负责将客户端的方法调用转换为服务器端的方法调用。在这个例子中,我们将创建一个CalculatorProxy类:import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.*; import java.io.*; public class RpcClient { public static void main(String[] args) throws IOException, ClassNotFoundException { Socket socket = new Socket("localhost", 8080); System.out.println("Connected to the server"); InputStream inputStream = socket.getInputStream(); ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream()); outputStream.writeObject(new CalculatorImpl()); outputStream.flush(); socket.close(); Calculator calculator = (Calculator)Proxy.newProxyInstance(Calculator.class.getClassLoader(), new Class[]{Calculator.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (args[0] instanceof Integer && args[1] instanceof Integer) { System.out.println("Calling " + method.getName() + " with arguments " + args[0] + ", " + args[1]); return method.invoke(((CalculatorImpl)args[0]), args[1], args[2]); } else { throw new IllegalArgumentException("Invalid arguments"); } }}); // 使用代理对象调用远程方法 System.out.println("Result: " + calculator.add(1, 2)); // 输出:Result: 3 System.out.println("Result: " + calculator.subtract(5, 3)); // 输出:Result: 2 } }运行客户端:运行RpcClient类的main方法,将连接到服务器并调用远程服务。客户端和服务器之间的通信可以通过网络套接字进行。在这个例子中,我们使用了一个简单的命令行界面来显示结果。
  • [技术干货] RESTful和RPC的区别
    PRC:Remote Procedure Call,远程过程调用RESTful:Representational State Transfer,表征状态转移RPC和RESTful都是远程调用接口,它们之间到底有什么区别的呢?1、从本质区别上看,RPC是基于TCP实现的,RestFul是基于HTTP来实现的。2、从传输速度上来看,因为HTTP封装的数据量更多所以数据传输量更大,所以RPC的传输速度是比RestFul更快的。3、因为HTTP协议是各个框架都普遍支持的。在toC情况下,因为不知道情况来源的框架、数据形势是什么样的,所以在网关可以使用RestFul利用http来接收。而在微服务内部的各模块之间因为各协议方案是公司内部自己定的,所以知道各种数据方式,可以使用TCP传输以使各模块之间的数据传输更快。所以可以网关和外界的数据传输使用RestFul,微服务内部的各模块之间使用RPC。4、RestFul的API的设计上是面向资源的,对于同一资源的获取、传输、修改可以使用GET、POST、PUT来对同一个URL进行区别,而RPC通常把动词直接体现在URL上。
  • [行业资讯] gRPC 1.45.1发布,跨语言RPC框架
    gRPC是可以在任何环境中运行的现代开源高性能RPC框架。gRPC 1.45.1现已发布,主要功能更新有两部分,一个是Core,涉及切换到epoll1作为Linux的默认轮询引擎 ( #29239 )与XDS相关的各种修复(#29240、#29242、 #29243、 #29244、#29280);另一个是Python,恢复“从setup.py中删除 GRPC_ENABLE_FORK_SUPPORT”(#29230)详情可查看:https://github.com/grpc/grpc/releases/tag/v1.45.1转载于CSDN微信公众号
  • [技术干货] RPC、gRPC与K8S CRI
    ### 一、什么是PRC ? ### 1.1 **定义** RPC(Remote Procedure Call),**远程过程调用**。是一个计算机通信协议,该协议允许运行于一台计算机的程序调用另一个地址空间(通常为另一台开放网络的计算机)的子程序。而在开发人员的视角看来,该调用过程和调用本地过程一样,无需额外编程。在这个过程中,RPC也可以轻易的进行跨语言调用。 **举例来说**:存在两台服务器A,B,在A服务器上部署了一个应用程序,该应用程序需要调用在B服务器上应用提供的函数/方法。RPC的作用,就是让A可以通过网络跨内存空间调用B上的函数/方法。 **为什么不用Restful接口要提出RPC?** Restful接口每次调用时,都需要编写http请求。RPC能做到的,是像本地调用一样去发起远程调用而**让使用者对远程调用无感知**。 ### 1.2 组件 + **Server**:RPC服务的提供者,上述例子中为服务器B。 + **Client**:RPC服务的调用方,上述例子中的服务器A。 + **Client Stub**:存放Server的地址信息,再将服务端的请求打包成网络消息,通过网络远程发送给服务方。 + **Server stub**:接收客户端发送过来的消息,将消息解包,并调用本地的方法。 ### 1.3 RPC调用过程 **(1)** 客户端(client)以本地调用方式(即以接口的方式)调用服务; **(2)** 客户端存根(client stub)接收到调用后,负责将方法、参数等组装成能够进行网络传输的消息体(将消息体对象序列化为二进制); **(3)** 客户端通过sockets将消息发送到服务端; **(4)** 服务端存根( server stub)收到消息后进行解码(将消息对象反序列化); **(5)** 服务端存根( server stub)根据解码结果调用本地的服务; **(6)** 本地服务执行并将结果返回给服务端存根( server stub); **(7)** 服务端存根( server stub)将返回结果打包成消息(将结果消息对象序列化); **(8)** 服务端(server)通过sockets将消息发送到客户端; **(9)** 客户端存根(client stub)接收到结果消息,并进行解码(将结果消息发序列化); **(10)** 客户端(client)得到最终结果。 RPC将中间过程封装起来,使用户无感知。 ### 二、什么是GRPC? **gRPC** (Google Remote Procedure Calls) 是Google发起的一个开源远程过程调用 (Remote procedure call) 系统。该系统基于 HTTP/2 协议传输,使用Protocol Buffers 作为接口描述语言。 **gRPC是RPC系统的一种。** 其基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特性。 ### 2.1 Protocol Buffers Protocol Buffers是一种序列化数据结构的协议。其包含一个接口描述语言用来描述一些方法与数据结构,并可以通过一些工具来将这些描述转化为代码。具体的Protocol语法这里不谈,接下来用一个Python gRPC例子说明gRPC基础概念。 ### 2.2 gRPC Python示例 (参考:[daydaygo](https://www.jianshu.com/p/43fdfeb105ff)) 通过代码往往能加深理解! **环境需求**:Python3、Proto3、pip包:grpcio、grpc-tools。 + 编写`.proto` 文件:定义**服务** `Greeter` 和 **API** `SayHello`。定义请求和回复message格式。 ```protobuf // helloworld.proto syntax = "proto3"; service Greeter { rpc SayHello(HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; } ``` + 通过grpc-tools编译protocol文件 ```shell python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. helloworld.proto ``` >+ `python -m grpc_tools.protoc`: python 下的 protoc 编译器通过 python 模块(module) 实现, 所以说这一步非常省心 >+ `--python_out=.` : 编译生成处理 protobuf 相关的代码的路径, 这里生成到当前目录 >+ `--grpc_python_out=.` : 编译生成处理 grpc 相关的代码的路径, 这里生成到当前目录 >+ `-I. helloworld.proto` : proto 文件的路径, 这里的 proto 文件在当前目录 ​ 编译后生成两个Python模块 >+ `helloworld_pb2.py`: 用来和 protobuf 数据进行交互 > >+ `helloworld_pb2_grpc.py`: 用来和 grpc 进行交互 + gRPC Server实现 ```python from concurrent import futures import time import grpc import helloworld_pb2 import helloworld_pb2_grpc # 实现 proto 文件中定义的 GreeterServicer class Greeter(helloworld_pb2_grpc.GreeterServicer): # 实现 proto 文件中定义的 rpc 调用 def SayHello(self, request, context): return helloworld_pb2.HelloReply(message = 'hello {msg}'.format(msg = request.name)) def serve(): # 注册启动 rpc 服务 server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() try: while True: time.sleep(60*60*24) # one day in seconds except KeyboardInterrupt: server.stop(0) if __name__ == '__main__': serve() ``` server端提供了 rpc服务的实现并注册开启rpc服务。 + gRPC Client实现 ```python import grpc import helloworld_pb2 import helloworld_pb2_grpc def run(): # 连接 rpc 服务器 channel = grpc.insecure_channel('localhost:50051') # 调用 rpc 服务 stub = helloworld_pb2_grpc.GreeterStub(channel) response = stub.SayHello(helloworld_pb2.HelloRequest(name='czl')) print("Greeter client received: " + response.message) if __name__ == '__main__': run() ``` ## 三、K8S CRI接口 ### 3.1 CRI是什么? CRI(Container Runtime Interface)容器运行时接口,定义了**容器**和**镜像**的服务的接口。因为容器运行时与镜像的生命周期是彼此隔离的,因此需要定义两个服务。该接口使用Protocol Buffer,基于gRPC。使用CRI接口,我们可以通过rpc的方式调用管理k8s集群容器。 ### 3.2 iSula CRI ISulad使用CRI接口,实现了和kubernetes 的对接。接下来演示python iSula CRI接口的调用。 首先需要通过grpc-io工具编译CRI proto文件生成核心python模块并开启iSulad-CRI服务。 ```python import grpc import api_pb2_grpc import api_pb2 if __name__ == '__main__': # connect to rpc service channel = grpc.insecure_channel('unix:///var/run/isulad.sock') # rpc server: container and image server runtime_stub = api_pb2_grpc.RuntimeServiceStub(channel) image_stub = api_pb2_grpc.ImageServiceStub(channel) # get iSulad version response = runtime_stub.Version(api_pb2.VersionRequest()) print(response) ``` 其余CRI API调用方式类似,具体参考其proto文件。
  • [技术干货] 配置nfs服务
    首先我们来了解下什么是nfs?NFS (Network File System,网络文件系统)是一种基于网络的文件系统。NFS的第一个版本是Sun Microystems在20世纪80年代开发的。它可以将远端服务器文件系统的目录加袭到本地文件系统的目录上,允许用户或者应用程序像访问本地文件系统的目录结构一样,访问远端服务器文件系统的目录结构,而无须理会远端服务器文件系统和本地文件系统的具体类型非常方便地实现了目录和文件在不同计算机上共享。NPS作为一个文件系统,几乎具备了一个传统桌面文件系统最基本的结构特征和访问特征,不同之处在于它的数据存储于远端服务器上,而不是本地设备上。NFS需要将本地操作转换为网络操作,并在远端服务器上实现,最后返回操作的结果。因此, NFS更像是远端服务器文件系统在1本地的一个文件系统代理,用户或者应用程序通过访问文件系统代理来访问真实的文件系统。NFS允许计算的客户一服务器模型如图3-1所示。服务器实施共享文件系统,以及客户端所连接的存储。客户端实施用户接口来共享文件系统,并加载到本地文件空间当中。为了实现平台无关性, NFS基于OSI底层实现。基于会话层的远程过程调用(Remote Prorcedure Call, RPC)和基于表示层的外部数据表示(External Data Representation, XDR)为NFS提供所需的网络连接,并解释基于这些连接发送的数据格式,它们使NES可正常工作于不同RPC运行于OSI模型的会话层,它提供一组过程,使远程计算机系统可以像调用本地过程一样调用这些过程。使用RPC,本地计算机或应用程序可调用位于远程计算机上的服务。RPC提供一组过程库,高层应用可以调用这些库而无须了解远程系统的底层细节。因为RPC的抽象使得NFS与平台无关。外部数据表示库负责在不同的计算机系统间转换RPC数据,XDR设计了一种标准的数据表示,使得所有计算机均可理解NFS文件系统可使用两种方式加载:硬加载和软加载。当NFS服务器或资源不可用时硬加载资源将导致不断尝试RFC调用。一旦服务器响应, RPC调用成功且进入下一个执行过程。如果服务器或网络问题持续,硬加载将引起持续等待状态,使NFS客户端应用挂起。用户可以指定属性使硬加载可中断。使用软加载资源时, RPC调用失败将导致NFS客户应用同时失败,最终使数据不可用。此种方法不可用于可写的文件系统或读取关键数据及可执行程序。硬加载的可靠性高,适用于加载可写资源或访问关键的文件和程序。如果资源被硬加载,一旦服务器崩溃或网络连接异常,程序(或用户)访问将被挂起,这将导致不可预见的结果。默认情况下NFS资源均采用硬加载。作者:仙女本仙
  • [技术干货] 什么是RPC?
    RPC是远程过程调用(Remote Procedure Call)的缩写形式。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。
  • [交流分享] Centos7.6 nfs部署-分布式
    NFS介绍        NFS 是Network File System的缩写,即网络文件系统。一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布。功能是通过网络让不同的机器、不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。  NFS 的基本原则是“容许不同的客户端及服务端通过一组RPC分享相同的文件系统”,它是独立于操作系统,容许不同硬件及操作系统的系统共同进行文件的分享。  NFS在文件传送或信息传送过程中依赖于RPC协议。RPC,远程过程调用 (Remote Procedure Call) 是能使客户端执行其他系统中程序的一种机制。NFS本身是没有提供信息传输的协议和功能的,但NFS却能让我们通过网络进行资料的分享,这是因为NFS使用了一些其它的传输协议。而这些传输协议用到这个RPC功能的。可以说NFS本身就是使用RPC的一个程序。或者说NFS也是一个RPC SERVER。所以只要用到NFS的地方都要启动RPC服务,不论是NFS SERVER或者NFS CLIENT。这样SERVER和CLIENT才能通过RPC来实现PROGRAM PORT的对应。可以这么理解RPC和NFS的关系:NFS是一个文件系统,而RPC是负责负责信息的传输。环境系统平台:CentOS release 5.6 (Final)NFS Server IP:xxx.xxx.xxx.xxx防火墙已关闭/iptables: Firewall is not running.SELINUX=disabled1、安装服务器 (1) nfs-utils-* :包括基本的NFS命令与监控程序     yum install  -y  nfs-utils.aarch64        //开机启动 # systemctl enable rpcbind     //启动 # systemctl start rpcbind     //重启 # systemctl status rpcbind (2) NFS 服务器配置          /etc/exports                           NFS服务的主要配置文件         /usr/sbin/exportfs                   NFS服务的管理命令          /usr/sbin/showmount              客户端的查看命令          /var/lib/nfs/etab                      记录NFS分享出来的目录的完整权限设定值           /var/lib/nfs/xtab                      记录曾经登录过的客户端信息          NFS服务的配置文件为 /etc/exports,这个文件是NFS的主要配置文件,不过系统并没有默认值,所以这个文件不一定会存在,可能要使用vim手动建立,然后在文件里面写入配置内容。          a. 输出目录:输出目录是指NFS系统中需要共享给客户机使用的目录;b. 客户端:客户端是指网络中可以访问这个NFS输出目录的计算机客户端常用的指定方式指定ip地址的主机:192.168.0.200指定子网中的所有主机:192.168.0.0/24 192.168.0.0/255.255.255.0指定域名的主机:david.bsmart.cn指定域中的所有主机:*.bsmart.cn所有主机:*c. 选项:选项用来设置输出目录的访问权限、用户映射等。NFS主要有3类选项:访问权限选项用户映射选项其它选项(3)启动/关闭 nfs 服务secure:限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置);insecure:允许客户端从大于1024的tcp/ip端口连接服务器;sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;async:将数据先保存在内存缓冲区中,必要时才写入磁盘;wdelay:检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率(默认设置);no_wdelay:若有写操作则立即执行,应与sync配合使用;subtree:若输出目录是一个子目录,则nfs服务器将检查其父目录的权限(默认设置);no_subtree:即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;all_squash:将远程访问的所有普通用户及所属组都映射为匿名用户或用户组(nfsnobody);no_all_squash:与all_squash取反(默认设置);root_squash:将root用户及所属组都映射为匿名用户或用户组(默认设置);no_root_squash:与rootsquash取反;anonuid=xxx:将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx);anongid=xxx:将远程访问的所有用户组都映射为匿名用户组账户,并指定该匿名用户组账户为本地用户组账户(GID=xxx);设置输出目录只读:ro设置输出目录读写:rw          systemctl start  nfs          systemctl status nfs3、客户端安装     (1) 安装nfs           yum install  -y  nfs-utils.aarch64        (2) 启动 rpcbind          //开机启动 # systemctl enable rpcbind           //启动 # systemctl start rpcbind          //重启 # systemctl status rpcbind实例:1、服务端nfs 配置        systemctl restart nfs 2、客户端挂载(可以挂多个)   showmount  -e  xxx.xxx.xxx.xxx(ip)(查看服务端可挂载对象范围)   mkdir -p  /mnt/data   mount -t nfs   xxx.xxx.xxx.xxx(服务端ip):/mnt/data   /mnt/dataFAQ1、如果出现下列问题,挂载失败     mount.nfs: access denied by server while mounting 10.71.232.55:/mnt/hgfs    可尝试修改服务端exports  文件中共享目录权限     
  • [问题求助] RPC调用报错:NotSslRecordException,message:not an SSL/TLS record
    edge未开启ssl&http2,后端微服务M开启了ssl&http2edge通过RPC方式调用后端微服务M时,微服务M报错:NotSslRecordException,message:not an SSL/TLS record
  • [技术干货] HBase学习之:HBase RPC
    RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。详情请点击博文链接:https://bbs.huaweicloud.com/blogs/173527
  • [典型案例] Windows下RPC动态端口没有开全导致虚拟机发放失败
    【关 键 词】:发放失败、端口【适用版本】:FusionAccessR5\R6【故障模式】:虚拟机发放【案例密级】:访客公开级【问题现象】: 发放虚拟机过程中,在添加用户权限的时候提示失败,如下图:【分析过程】:(1)  从发放过程看,虚拟机已经加域完成,在添加域用户到虚拟机本地权限组时失败。(2)  在虚拟机本地用户和组中手动添加用户名时,提示搜索不到该用户。(3) 根据问题现象,应该是RPC动态端口没有通。和客户确认,客户开放的RPC动态端口为50152-51151,但是其实AD是客户已有的AD,并没有做安全加固。(4)让客户重新配置防火墙,放开RPC端口49152-65535。重新发放虚拟机,正常。【解决方法1】:重新配置防火墙,放开RPC端口49152-65535【解决方法2】:如果虚拟机加域成功,但是添加用户到本地组失败,基本就是RPC动态端口的问题,如果无法确定,可以通过抓包进一步分析。
  • [技术干货] 每日分享:HBase学习之:HBase RPC
    原文地址:https://bbs.huaweicloud.com/blogs/173527学习HBase的RPC可以为学HBase打好基础,因为RPC是HMaster,RegionServer和Client通信的纽带1.1      1 RPCRPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。    首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。交互过程如下图所示:1.2      HBase.ipc1.2.1        2.1 ServerRPC Server实现了一种抽象的RPC服务,同时提供Call队列。Ø  RPC Server结构 结构 (类)功能 HBaseServer.ListenerRPC Server的监听者,用来接收RPC Client的连接请求和数据,其中数据封装成Call后PUSH到Call队列。HBaseServer.HandlerRPC Server的Call处理者,和Server.Listener通过Call队列交互。HBaseServer.ResponderRPC Server的响应者。HBaseServer.Handler按照异步非阻塞的方式向RPC Client发送响应,如果有未发送出的数据,交由HBaseServer.Responder来完成。HBaseServer.ConnectionRPC Server数据接收者。提供接收数据,解析数据包的功能。HBaseServer.Call持有客户端的Call信息。 Ø  RPC Server主要流程 RPC Server作为服务提供者由两个部分组成:接收Call调用和处理Call调用。接收Call调用负责接收来自RPC Client的调用请求,编码成Call对象后放入到Call队列中。这一过程由Listener线程完成。具体步骤:1.   Listener线程监视RPC Client发送过来的数据。2.   当有数据可以接收时,Listener启动Reader线程,reader线程调用Connection的readAndProcess方法接收并处理数据。3.   Connection边接收边对数据进行处理,如果接收到一个完整的Call包,则构建一个Call对象PUSH到Call队列中,由Handler线程来处理Call队列中的所有Call。4.   Handler线程监听Call队列,如果Call队列非空,按FIFO规则从Call队列取出Call。5.   将Call交给RPC.Server处理。(在WritableRpcEngine.Server类中,该类是HBaseServer的子类)。6.   借助JDK提供的Method,完成对目标方法的调用,目标方法由具体的业务逻辑实现。7.   返回响应HBaseServer.Handler按照异步非阻塞的方式向RPC Client发送响应,如果有未发送出的数据,则交由Server.Responder来完成。1.2.2        ClientRPC Client是Client的实现和入口类。Ø  RPC Client结构 结构 功能 HBaseClient.ConnectionId到RPC Server对象连接的标识。HBaseClient.CallCall调用信息。HBaseClient.ParallelResultsCall响应。WritableRpcEngine.Invoker对InvocationHandler的实现,提供invoke方法,实现RPC Client对RPC Server对象的调用。Invocation用来序列化和反序列化RPC Client的调用信息。(主要应用JAVA的反射机制和InputStream/OutputStream)Ø  RPC Client主要流程 每一个Call都是由RPC Client发起。步骤说明:1.   RPC Client发起RPC Call,通过JAVA反射机制转化为对Client.call调用。2.   调用getConnection得到与RPC Server的连接。每一个RPC Client都维护一个HashMap结构的到RPC Server的连接池。具体建立连接的流程见下图。3.   通过Connection将序列化后的参数发送到RPC服务端。4.   阻塞方式等待RPC服务端返回响应。1.2.3        同步客户端发起的RPC调用是同步的,而服务端处理RPC调用是异步的。客户端调用线程以阻塞同步的方式发起RPC连接及RPC调用,将参数等信息发送给Listener,然后等待Connection接收响应返回。Listener负责接收RPC连接和RPC数据,当一个Call的数据接收完后,组装成Call,并将Call放入由Handler提供的Call队列中。Handler线程监听Call队列,如果Call队列不为空,则按FIFO方式取出Call,并转为实际调用,以非阻塞方式将响应发回给Connection,未发送完毕的响应交给Responder处理。
  • [技术干货] ServiceComb Java SDK 直接调用RPC 服务端
    # RPC Server 端支持使用 POSTMAN 直接调用 > 如果服务端 是使用 Java Chassis **RPC 风格开发的**, 如果想是用 `postman` 等工具直接调用时, 需要根据 swagger 契约查找 调用路径 ### 示例 ```java @RpcSchema(schemaId = "test") @SwaggerDefinition(basePath = "/pojo/rest") public class CodeFirstPojo { public Person sayHello(Person user) { user.setName("hello " + user.getName()); return user; } public String sayHi(String name) { return "hello " + name; } } ``` ### POSTMAN 调用 要想知道调用路径, 需要查看 **契约**. > 契约可以在 `日志` 中查看, 也可以在 `服务中心` 中查找. ```yaml swagger: "2.0" info: version: "1.0.0" title: "swagger definition for org.apache.servicecomb.demo.pojo.server.CodeFirstPojo" x-java-interface: "gen.swagger.CodeFirstPojoIntf" basePath: "/pojo/rest" schemes: - "http" consumes: - "application/json" produces: - "application/json" paths: /sayHello: post: operationId: "sayHello" parameters: - in: "body" name: "user" required: false schema: $ref: "#/definitions/Person" responses: "200": description: "response of 200" schema: $ref: "#/definitions/Person" /sayHi: post: operationId: "sayHi" parameters: - in: "body" name: "name" required: false schema: $ref: "#/definitions/sayHiBody" responses: "200": description: "response of 200" schema: type: "string" definitions: Person: type: "object" properties: name: type: "string" x-java-class: "org.apache.servicecomb.demo.compute.Person" sayHiBody: type: "object" properties: name: type: "string" ``` > 根据 `basePath` 和 `path` 进行拼接. 例如 我想调用 **sayHi()** 请求路径是 `/pojo/rest/sayHi` , 调用方法是 `post` ![rpc_1.PNG](https://bbs-img-cbc-cn.obs.cn-north-1.myhuaweicloud.com/data/attachment/forum/202004/07/224719zyb4ccgyo9m5ki5m.png) ![rpc_2.PNG](https://bbs-img-cbc-cn.obs.cn-north-1.myhuaweicloud.com/data/attachment/forum/202004/07/224729b3tkutusxtruwtln.png)
  • [技术干货] rpc通信问题,两次请求返回的结果不一样
    如图所示,实例确定就是一个,在请求的时候 一次是map 一次是user对象,当是map的时候,就不能转成user,然后就报错了,不知道是哪里的问题java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.bud.common.entity.system.permission.Userat com.bud.business.ctrl.login.LoginCtrl.getUser(LoginCtrl.java:57)at com.bud.business.ctrl.login.LoginCtrl$$FastClassBySpringCGLIB$$e11fb510.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:84)
  • [技术干货] 后端存在rest和rpc时,edge service转发异常
    请问一下: 当前后端微服务同时开了Rest和RPC接口,Edge Service转发规则是什么?问题现象:后端微服务开放了rest和rpc,客户端通过edge service调用后端服务,调用某个api时,edge service打印日志,发现轮询了rest和higway,导致返回的数据异常。返回的异常数据参考 https://bbs.huaweicloud.com/forum/thread-35443-1-1.html
  • [技术干货] RPC如何支持灰度分流
    router.yaml定义分流策略是按header做分流的。RPC怎么分流?
总条数:20 到第
上滑加载中