谈谈RPC——golang中jsonrpc和grpc的使用

前言

不知从什么时候rpc这个东西开始进入我们的视野,一开始做开发的时候经常使用的都是http,偶尔使用的是socket进行通信,使用的是restful的方式。但是,一次偶然的机会你会发现RPC这个东西进入了你的视野,而且由于微服务的兴起然他迅速被人们所知,那么它是什么,又如何使用呢?

RPC定义

RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样。
说的再实际一点:
如果我们之前使用UserService.getUser(1)这样的方式调用本地服务,而rpc就是要让调用远程服务也是这样。

jsonrpc

其实说多了也没用,还是直接上代码,让我实际来看看使用方式你就瞬间明白了。
首先举个jsonrpc的例子。
golang自带了"net/rpc/jsonrpc"的库,所以我们利用它来做。
首先是我们需要调用的服务
?
非常简单的一个定义,定义了一个获取用户的服务,返回用户信息。
其中需要说明的是,入参是需要遵循jsonrpc的一个定义规范,将返回值以指针的方式传入。
注册和启动服务
?
注册我们刚才写好的服务,然后监听一个端口,并且准备接受请求。

最后最重要的就是我们的客户端调用
?
我们通过连接对应端口,通过Call方法调用对应服务的方法,传入对应的参数和返回值。
我们看到,虽然这个rpc服务没有写在我们本地,但是我们看到使用UserService.GetUser这样的写法调用这个服务,这其实就是所谓的rpc

对比http来看,http服务你需要给出对应的接口地址,需要定义http method,等等。从我个人的看法来说:rpc更像是熟人之间的对话,http更多的陌生人之间的约定 因为rpc调用的时候,我都知道你的方法命名和位置,对你很了解;而http调用的时候我必须按照文档的定义。所以rpc多用于微服务之间的调用也是有道理的。

grpc

上面我们看到jsonrpc的实现还是比较简单的,只需要把对应的服务进行注册即可调用,而grpc会稍微复杂一些,不过grpc也被更多人所知道,因为它的性能和语言支持,grpc支持各种语言哦。

由于国内某些你懂的原因,grpc安装使用go get会有问题,下面是我的安装步骤,可以参考

grpc的安装

首先需要一些依赖
cd $GOPATH/src/golang.org/x
git clone https://github.com/golang/net.git
git clone https://github.com/golang/text.git
git clone https://github.com/golang/crypto.git

mkdir -p \(GOPATH/src/google.golang.org/
cd \)GOPATH/src/google.golang.org
git clone https://github.com/Agzs/grpc grpc

cd $GOPATH/src/
go install google.golang.org/grpc

如果没有任何提示,证明安装完成,如果提示问题,查询一下应该可以解决

如果你懂一点shell可以直接运行下面的脚本进行安装这些依赖

#!/bin/bash
MODULES="crypto net oauth2 sys text tools"
for module in ${MODULES}
do
wget https://github.com/golang/${module}/archive/master.tar.gz -O ${GOPATH}/src/golang.org/x/${module}.tar.gz
cd ${GOPATH}/src/golang.org/x && tar zxvf ${module}.tar.gz && mv ${module}-master/ ${module}
done

wget https://github.com/google/go-genproto/archive/master.tar.gz -O ${GOPATH}/src/google.golang.org/genproto.tar.gz
cd ${GOPATH}/src/google.golang.org && tar zxvf genproto.tar.gz && mv go-genproto-master genproto

protocol-buffer的安装

grpc的使用还需要这个东西的帮忙
官网:https://developers.google.com/protocol-buffers/
我的安装方式:
首先:
https://github.com/protocolbuffers/protobuf/releases
在这里下载需要的版本
?
然后下载完成之后找到

?
将protoc拷贝到环境变量PATH中的一个目录下就可以了

可以放在/usr/local/sbin,我就偷懒喜欢放在gopath下的bin里面

然后在命令行输入

protoc --version

libprotoc 3.7.1
看到这个提示证明安装成功

grpc的使用

1、首先编写一个proto文件,用于定义你的服务接口
syntax = "proto3";

package grpc_demo;

message Request {
int64 a = 1;
int64 b = 2;
}

message Response {
int64 result = 1;
}

service AddService {
rpc Add (Request) returns (Response);
}

2、然后使用命令生成对应的pb文件
protoc -I ./ ./demo.proto --go_out=plugins=grpc:./

3、然后编写服务端
?
可以看到这里的写法和jsonrpc是类似的,但是因为生成了pb文件的原因,所以不可能写错,都是引用的代码,需要注意的是,这个的Add方法就是实现了我们在protoc文件中定义的接口。

4、最后编写客户端
?
在这里我们明显可以看出,在grpc中的写法更加的稳一些,不容易出错。调用的入参和出参都非常的明确。

到这里,grpc的使用就完成了。我们也明显可以对比出两者的区别。同时你也发现,如果是一些复杂的服务情况对于grpc的proto你需要更加的了解。

详细了解可以查看
https://blog.didiyun.com/index.php/2018/12/12/grpc-golang-1/
https://blog.didiyun.com/index.php/2018/12/29/grpc-golang-2/

总结

实际我们可以看到,其实rpc没有我们想的很复杂,它与http的使用上面差别也不是很大,但是从服务的角度来说,确实rpc更多适用于内部服务的调用,这样服务的调用会非常方便,就像在使用本地服务一样。同时我们也对比了jsonrpc和grpc从实现的角度上面来说jsonrpc实现起来更加方便一些,不过grpc从性能和使用的角度来说更加稳健一些。

原文地址:https://www.cnblogs.com/linkstar/p/10895791.html

时间: 2024-08-30 15:57:46

谈谈RPC——golang中jsonrpc和grpc的使用的相关文章

golang中的rpc包用法

RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服务之间的沟通越来越频繁,就希望可以做成用rpc来做内部的通讯,对外依然用Restful.于是就想到了golang标准库的rpc包和google的grpc. 这篇文章重点了解一下golang的rpc包. 介绍 golang的rpc支持三个级别的RPC:TCP.HTTP.JSONRPC.但Go的RPC包

Golang中多用途的defer

defer顾名思义就是延迟执行,那么defer在Golang中该如何使用以及何时使用呢? A "defer" statement invokes a function whose executionis deferred to the moment the surrounding function returns, Golang的官方时这么定义的. 1.那么在什么情况下会调用defer延迟过的函数呢? 从文档中可以知道主要有两种情况: 当函数执行了return 语句后 当函数处于pan

Golang中使用log(一):Golang 标准库提供的Log

Golang的标准库提供了log的机制,但是该模块的功能较为简单(看似简单,其实他有他的设计思路).不过比手写fmt. Printxxx还是强很多的.至少在输出的位置做了线程安全的保护.其官方手册见Golang log (天朝的墙大家懂的).这里给出一个简单使用的例子: package main import ( "log" ) func main(){ log.Fatal("Come with fatal,exit with 1 \n") } 编译运行后,会看到程

Go_18: Golang 中三种读取文件发放性能对比

Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提供的 read 方法进行读取 下面通过代码来验证这三种方式的读取性能,并总结出我们平时应该使用的方案,以便我们可以写出最优代码: package main import ( "os" "io" "bufio" "io/ioutil"

【原】谈谈对Objective-C中代理模式的误解

[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective-C中的delegate大部分用法属于委托模式.全文有些抠概念,对实际开发没有任何影响. 前段时间看到的一篇博客iOS开发——从一道题看Delegate,和这篇博客iOS APP 架构漫谈解决的问题类似.两篇blog都写得很不错,都是为了解决两个页面之间的数据传递问题: A页面中有一个UILabel

谈谈Runtime类中的freeMemory,totalMemory,maxMemory等几个方法

谈谈Runtime类中的freeMemory,totalMemory,maxMemory等几个方法 Java虚拟机threadJVM 最近在网上看到一些人讨论到java.lang.Runtime类中的freeMemory(),totalMemory(),maxMemory ()这几个方法的一些问题,很多人感到很疑惑,为什么,在java程序刚刚启动起来的时候freeMemory()这个方法返回的只有一两兆字节,而随着 java程序往前运行,创建了不少的对象,freeMemory()这个方法的返回有

Go_14:GoLang中 json、map、struct 之间的相互转化

1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母必须为大写.请看下面的例子: package commontest import ( "testing" "encoding/json" ) type Person struct { name string age int } func TestStruct2Json(

golang中使用selenium进行爬虫

selenium本来是用来做自动测试,但是因为可以模拟浏览器操作,所以也可以用来做爬虫(尤其是一些比较变态登陆网站,又不会模拟登陆的),只是速度会比较慢. 转载请注明出处:http://www.cnblogs.com/SSSR/p/6390229.html 经验总结: 1.火狐浏览器在运行较长时间后,会导致内存泄露,但是Google浏览器不会,所以如果长时间运行还是使用Google浏览器比较好. 2.截图方面选择火狐浏览器,Google浏览器无法截全部页面,即使设置了页面大小也不行. 3.Fir

谈谈MVC项目中的缓存功能设计的相关问题

本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据库),我们一般会考虑将一些更新不是很频繁的,可以重用的数据,通过一定的方式临时地保存起来,后续的请求根据情况可以直接访问这些保存起来的数据.这种机制就是所谓的缓存机制. 根据缓存的位置不同,可以区分为: 1.客户端缓存(缓存在用户的客户端,例如浏览器) 2.服务器断货(缓存在服务器中,可以缓存在内存