一、rpc
1、概念
rpc:(Remote Procedure Call)远程过程调用,是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用。
远程过程调用是一个分布式计算的客户端-服务器(Client/Server)的例子,它简单而又广受欢迎。远程过程调用总是由客户端对服务器发出一个执行若干过程请求,并用客户端提供的参数。执行结果将返回给客户端。由于存在各式各样的变体和细节差异,对应地派生了各式远程过程调用协议,而且它们并不互相兼容。
从通信协议的层面,大致可以分为:
基于HTTP协议的(例如基于文本的SOAP(XML)、Rest(JSON),基于二进制Hessian(Binary))
基于TCP协议的(通常会借助Mina、Netty等高性能网络框架)
从不同的开发语言和平台层面,分为:
单种语言或平台特定支持的通信技术(例如Java平台的RMI、.NET平台Remoting)
支持跨平台通信的技术(例如HTTP Rest、Thrift等)
从调用过程来看,分为:
同步通信调用(同步RPC)
异步通信调用(MQ、异步RPC)
常见的几种通信方式
1. 远程数据共享(例如:共享远程文件,共享数据库等实现不同系统通信)
2. 消息队列
3. RPC(远程过程调用)
序列化/反序列化
只有二进制数据才能在网络中传输,序列化和反序列化的定义是:
将对象转换成二进制流的过程叫做序列化,
将二进制流转换成对象的过程叫做反序列化。
应用级的服务框架:
Dubbo/Dubbox、ZeroICE、GRpc、Spring Boot/Spring Cloud
基础通信框架:
Protocol Buffers、Thrift
远程通信协议:
RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)
影响RPC性能的主要在几个方面:
1.序列化/反序列化的框架 2.网络协议,网络模型,线程模型等
二、jsonrpc:
1、概念:
JSON-RPC,是一个无状态且轻量级的远程过程调用(RPC)传送协议,其传递内容通过 JSON 为主。相较于一般的 REST 通过网址(如 GET /user)调用远程服务器,JSON-RPC 直接在内容中定义了欲调用的函数名称或参数。
2、远程调用分服务端,客户端和要被访问的对象:
被访问的对象
type DemoService struct {
}
type Args struct {
A, B int
}
//只有满足如下标准的方法才能用于远程访问。
//DemoService是远程访问的对象,Div是远程访问的对象的函数
//args是远程访问所带的参数
//result是远程访问的结果
func (DemoService) Div(args Args,result *float64) error {
if args.B == 0 {
return errors.New("division by zero")
}
*result = float64(args.A) / float64(args.B)
return nil
}
服务端要做如下工作:
1)、服务端需要注册可以被远程访问的对象
2)、创建网络监听器,等待发过来的请求
3)、获取发送来的请求
4)、处理发送来的请求
代码:
func main() {
//1、服务端需要注册可以被远程访问的对象,之后这个对象就可以被远程访问了
rpc.Register(rpcDemo.DemoService{})
//2、创建网络监听器,等待发过来的请求
listener,err := net.Listen("tcp",":2222")
if err != nil {
panic(err)
}
for {
//3、获取发送来的请求
//Accept接收监听器l获取的连接
conn,err := listener.Accept()
if err != nil {
log.Printf("accept error: %v",err)
continue
}
//4、异步处理发送来的请求
go jsonrpc.ServeConn(conn)
}
}
客户端要做如下工作:
1)、创建连接
2)、创建客户端
3)、客户端通过连接向服务端发送请求
代码:
//客户端要呼叫服务端
func main() {
//1、创建连接
//Dial在指定的网络和地址与RPC服务端连接
conn,err := net.Dial("tcp",":2222")
if err != nil {
panic(err)
}
//2、创建客户端
client:=jsonrpc.NewClient(conn)
var result float64
//3、客户端通过连接向服务端发送请求
err = client.Call("DemoService.Div",
rpc.Args{10,3},&result)
fmt.Println(result,err)
}