gRPC
gRPC 是一个高性能、通用的开源 RPC 框架,其由 Google 主要面向移动应用开发并基于 HTTP/2 协议标准而设计,基于 ProtoBuf(Protocol Buffers) 序列化协议开发,且支持众多开发语言。
本篇内容演示了如何在 Midway 体系下,提供 gRPC 服务,以及调用 gRPC 服务的方法。
Midway 当前采用了最新的 gRPC 官方推荐的 @grpc/grpc-js 进行开发,并提供了一些工具包,用于快速发布服务和调用服务。
我们使用的模块为 @midwayjs/grpc
,既可以独立发布服务,又可以接入其它框架调用 gRPC 服务。
相关信息:
提供服务
描述 | |
---|---|
可用于标准项目 | ✅ |
可用于 Serverless | ❌ |
可用于一体化 | ✅ |
调用服务
描述 | |
---|---|
可用于标准项目 | ✅ |
可用于 Serverless | ✅ |
可用于一体化 | ✅ |
其他
描述 | |
---|---|
可作为主框架独立使用 | ✅ |
可独立添加中间件 | ✅ |
安装依赖
$ npm i @midwayjs/grpc@3 --save
$ npm i @midwayjs/grpc-helper --save-dev
或者在 package.json
中增加如下依赖后,重新安装。
{
"dependencies": {
"@midwayjs/grpc": "^3.0.0",
// ...
},
"devDependencies": {
"@midwayjs/grpc-helper": "^1.0.0",
// ...
}
}
开启组件
不 管是提供服务还是调用服务,都需要开启组件。
@midwayjs/grpc
可以作为独立主框架使用。
// src/configuration.ts
import { Configuration } from '@midwayjs/core';
import * as grpc from '@midwayjs/grpc';
@Configuration({
imports: [grpc],
// ...
})
export class MainConfiguration {
async onReady() {
// ...
}
}
也可以附加在其他的主框架下,比如 @midwayjs/koa
。
// src/configuration.ts
import { Configuration } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
import * as grpc from '@midwayjs/grpc';
@Configuration({
imports: [koa, grpc],
// ...
})
export class MainConfiguration {
async onReady() {
// ...
}
}
目录结构
大致的目录结构如下,src/provider
是提供 gRPC 服务的目录。
.
├── package.json
├── proto ## proto 定义文件
│ └── helloworld.proto
├── src
│ ├── configuration.ts ## 入口配置文件
│ ├── interface.ts
│ └── provider ## gRPC 提供服务的文件
│ └── greeter.ts
├── test
├── bootstrap.js ## 服务启动入口
└── tsconfig.json
定义服务接口
在微服务中,定义一个服务需要特定的接口定义语言(IDL)来完成,在 gRPC中 默认使用 Protocol Buffers 作为序列化协议。
序列化协议独立于语言和平台,提供了多种语言的实现,Java,C++,Go 等等,每一种实现都包含了相应语言的编译器和库文件。所以 gRPC 是一个提供和调用都可以跨语言的服务框架。
一个gRPC服务的大体架构可以用官网上的一幅图表示。
Protocol Buffers 协议的文件,默认的后缀为 .proto
。.proto后缀的IDL文件,并通过其编译器生成特定语言的数据结构、服务端接口和客户端Stub代码。
由于 proto 文件可以跨语言使用,为了方便共享,我们一般将 proto 文件放在 src 目录外侧,方便其他工具复制分发。
下面是一个基础的 proto/helloworld.proto
文件。
syntax = "proto3";
package helloworld;
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
proto3 表示的是第三版的 protobuf 协议,是 gRPC 目前推荐的版本,“语法简单,功能更全”。
我们可以用 service
格式,定义服务体,其中可以包含方法。同时,我们可以更加细致的通过 message
描述服务具体的请求参数和响应参数。
我们可以从 Google 的官网文档 中查看更多细节。
大家会看到,这和 Java 中的 Class 非常相像,每个结构就相当于 Java 中的一个类。
编写 proto 文件
现在我们再来看之前的服务,是不是就很好理解了。
syntax = "proto3";
package helloworld;
// 服务的定义
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 服务的请求参数
message HelloRequest {
string name = 1;
}
// 服务的响应参数
message HelloReply {
string message = 1;
}
我们定义了一个名为 Greeter
的服务,包含一个 HelloRequest
结构的请求体,以及返回 HelloReply
结构的响应体。
接下去,我们将对这个服务给大家做演示。