微服务系列(二)GRPC的介绍与安装
微服务系列(二)GRPC的介绍与安装
1.GPRC简介
GRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架。GRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,对于移动设备更加友好。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.
在 gRPC里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC系统类似, gRPC也是基于以下理念:
定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。
在服务端实现这个接口,并运行一个 gRPC服务器来处理客户端调用。
在客户端拥有一个存根能够像服务端一样的方法。 gRPC客户端和服务端可以在多种环境中运行和交互 -从 google内部的服务器到你自己的笔记本,并且可以用任何 gRPC支持的语言 来编写。
所以,你可以很容易地用 Java创建一个 gRPC服务端,用 Go、 Python、Ruby来创建客户端。此外, Google最新 API将有 gRPC版本的接口,使你很容易地将 Google的功能集成到你的应用里。
参考资料
gRPC 官方文档中文版:http://doc.oschina.net/grpc?t=60133
gRPC官网:https://grpc.io
再详细了解使用GRPC之前先来了解一下上面定义中的一些关键词。
首先我们来看一下HTTP/2是什么内容?
其实本质上就是http2.0版本,http目前为止主要有四个版本,分别为http1.0、http1.1、http2.0、https。
http1.0是最原始的版本,不支持持久连接,效率也比较低
http1.1针对http1.0版本做了优化,可以连接一次,多次使用,效率比http1.0高
http2.0实现了多路复用,对http1.1再次进行了优化。http2.0也被称为下一代http协议,是在2013年8月进行首次测试,所以现在用的不是很广。
https其实是在http协议上多加了一层SSL协议,具体如下图:
所以本质上,http1.0、http1.1、http2.0都可以添加SSL协议。
2. grpc环境安装
官方推荐安装方法:
go get -u -v google.golang.org/grpc
但是由于墙原因,不能直接访问google官网,所以只能曲线救国了
通过github下载各种依赖库,然后配置。
git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net
git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text
git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto cd $GOPATH/src/
go install google.golang.org/grpc
网络畅通可以用上述方法,但如果网速较慢,我们也可以选择离线安装方法。
用
x.zip
和google.golang.org.zip
两个离线包来安装。#将x.zip 解压到 $GOPATH/src/golang.org/x 目录下
$ unzip x.zip -d $GOPATH/src/golang.org/x
#将google.golang.org.zip 解压到 $GOPATH/src/google.golang.org 目录下
$ unzip google.golang.org.zip -d $GOPATH/src/google.golang.org
#然后进入到$GOPATH/src/google.golang.org/grpc下面执行go install
$ go install
点击此处获取两个离线压缩包
3.GRPC使用
如果从Protobuf的角度看,GRPC只不过是一个针对service接口生成代码的生成器。接着我们来学习一下GRPC的用法。这里我们创建一个简单的proto文件,定义一个HelloService接口:
文件名称为person.proto
syntax = "proto3";
package pb; // 后期生成go的文件包名
option go_package = "../pb"; // go 1.14后需要指定导出的路径
// 消息体 -- 一个package中,不允许定义同名的消息体
message Teacher {
int32 age = 1;
string name = 2;
}
// 定义服务
service SayName {
rpc SayHello(Teacher) returns (Teacher);
}
对proto文件进行编译:
protoc --go_out=plugins=grpc:./ person.proto
编译后生成person.pb.go
文件
GRPC插件会为服务端和客户端生成不同的接口:
//客户端接口
type SayNameClient interface {
SayHello(ctx context.Context, in *Teacher, opts ...grpc.CallOption) (*Teacher, error)
}
//服务器接口
type SayNameServer interface {
SayHello(context.Context, *Teacher) (*Teacher, error)
}
我们接着可以基于他们给的服务端接口重新实现SayHello服务:
// 定义一个结构体 不一定非得是Teacher
type Children struct {
}
// 接口去绑定类方法
func (c *Children) SayHello(ctx context.Context,t *pb.Teacher) (*pb.Teacher, error) {
t.Name += "is teaching"
return t,nil
}
GRPC的启动流程和RPC的启动流程类似,代码如下:
func main(){
// 1. 初始一个grpc对象
grpcServer := grpc.NewServer()
// 2.注册服务
pb.RegisterSayNameServer(grpcServer,new(Children))
// 3.设置监听并建立连接,指定IP port
listener ,err := net.Listen("tcp","127.0.0.1:8080")
if err!=nil{
fmt.Printf("监听失败:%v",err)
return
}
defer listener.Close()
fmt.Println("正在监听127.0.0.1:8080 ...")
// 4.启动服务 ... Serve()
grpcServer.Serve(listener)
}
然后我们就可以通过客户端来连接GRPC服务了:
func main(){
// 1.连接grpc服务
grpcConn,err := grpc.Dial("127.0.0.1:8080",grpc.WithInsecure()) // 第二个参数以一个安全的形式进行编译
if err!=nil{
fmt.Printf("连接拨号失败:%v",err)
return
}
defer grpcConn.Close()
// 2.初始化grpc客户端
grpcClient := pb.NewSayNameClient(grpcConn) // 传入Dail函数的返回值
// 创建并初始化Teacher对象
var teacher pb.Teacher
teacher.Name = "小宝"
teacher.Age = 24
// 3.调用远程服务
t,err := grpcClient.SayHello(context.TODO(),&teacher) /*context.TODO()表示空对象,可以简单理解我们不清楚要使用哪个上下文、或者还没有可用的上下文时的占位符*/
if err!=nil{
fmt.Printf("调用远程服务失败:%v",err)
return
}
fmt.Println(t)
}
微服务系列(二)GRPC的介绍与安装的更多相关文章
- go微服务系列(四) - gRPC入门
1. 前言 2. gRPC与Protobuf简介 3. 安装 4. 中间文件演示 4.1 编写中间文件 4.2 运行protoc命令编译成go中间文件 5. 创建gRPC服务端 5.1 新建Produ ...
- go微服务系列(二) - 服务注册/服务发现
目录 1. 服务注册 1.1 代码演示 1.2 在go run的时候传入服务注册的参数 2. 服务发现均衡负载 2.1 均衡负载算法 2.2 服务发现均衡负载的演示 1. 服务注册 1.1 代码演示 ...
- 【微服务】之二:从零开始,轻松搞定SpringCloud微服务系列--注册中心(一)
微服务体系,有效解决项目庞大.互相依赖的问题.目前SpringCloud体系有强大的一整套针对微服务的解决方案.本文中,重点对微服务体系中的服务发现注册中心进行详细说明.本篇中的注册中心,采用Netf ...
- 微服务系列(二):使用 API 网关构建微服务
编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第二篇,本文将探讨:微服务架构是如何影响客户端到服务端的通信,并提出一种使用 API 网关的方法. 作者介绍:Chris Richardso ...
- 【转】「Chris Richardson 微服务系列」微服务架构的优势与不足
Posted on 2016年5月4日 编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战. 作者介绍:Chris Ric ...
- spring cloud微服务实践二
在上一篇,我们已经搭建了spring cloud微服务中的注册中心.但只有一个注册中心还远远不够. 接下来我们就来尝试提供服务. 注:这一个系列的开发环境版本为 java1.8, spring boo ...
- 带你十天轻松搞定 Go 微服务系列(一)
本文开始,我们会出一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建(本文) 服务拆分 用户服务 产品服务 订单服务 支付服务 RPC 服务 Au ...
- 从零开始,轻松搞定SpringCloud微服务系列
本系列博文目录 [微服务]之一:从零开始,轻松搞定SpringCloud微服务系列–开山篇(spring boot 小demo) [微服务]之二:从零开始,轻松搞定SpringCloud微服务系列–注 ...
- 微服务系列实践 .NET CORE
从事这个行业转眼已经6年了,从当初刚毕业的在北京朝八晚十,从二环到五环,仍每天精力充沛的小愤青:再到深圳一点一滴的辛勤在软件行业的耕种,从当初单体应用架构到现在微服务架构的经历,回想起来自己的收获倒是 ...
随机推荐
- Mysql之Mycat读写分离及分库分表
## 什么是mycat ```basic 1.一个彻底开源的,面向企业应用开发的大数据库集群 2.支持事务.ACID.可以替代MySQL的加强版数据库 3.一个可以视为MySQL集群的企业级数据库,用 ...
- Day12_62_线程的生命周期
线程的生命周期 要实现多线程,必须在主线程中创建新的线程对象. 任何线程一般都具有五种状态,即创建,就绪,运行,阻塞,终止(消亡) 新建状态:在程序中创建了一个新的线程对象后,新的线程对象便处于新建状 ...
- python 函数基本内容
1.什么是函数? 函数就是盛放代码的容器,把实现某一功能的一组代码丢到一个函数中就做成了一个小工具具备某一功能的工具->函数事先准备工具的过程->函数的定义遇到应用场景拿来就用->函 ...
- 各种数据类型是否可进入if判断
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Docker用Commit给容器做快照
关于 commit 镜像是容器的基础,每次执行 docker run 的时候都会指定哪个镜像作为容器运行的基础. 镜像是多层存储,每一层是在前一层的基础上进行修改:而容器同样也是多层存储,是在以镜像为 ...
- pr中打开Audition编辑剪辑?
前景 现在一般的adobe全家桶都是一键安装破解. 天翼网盘链接,下载不限速,没有账号就现注册一个即可. https://cloud.189.cn/t/UZRjuqAZ3E7r (访问码:8ago) ...
- PHP + JQuery 实现多图上传并预览
简述 PHP + JQuery实现 前台:将图片进行base64编码,使用ajax实现上传 后台:将base64进行解码,存储至文件夹,将文件名称入库 效果图 功能实现 html <!DOCTY ...
- 10.qml-组件、Loader、Component介绍
1.组件介绍 一个组件通常由一个qml文件定义(单独文件定义组件), 实际也可以在qml里面通过Component对象来嵌入式定义组件 (4小节讲解). Component对象封装的内容默认不会显示, ...
- 使用DevExpress的GridControl实现多层级或无穷级的嵌套列表展示
在我早期的随笔<在GridControl表格控件中实现多层级主从表数据的展示>中介绍过GridControl实现二级.三级的层级列表展示,主要的逻辑就是构建GridLevelNode并添加 ...
- IOCP实现高并发以及与传统socke编程的对比
前言 传统socket编程中服务端一般为每一个客户端创建一个线程(一对一).这样虽然可以使程序的结构简单明了并且方便对数据处理,但是这些都是建立在创建多个线程的基础上,也就是以牺牲线程为代价.一旦有大 ...