什么是GRPC?
如果您喜欢我,您可能甚至从未听说过GRPC,更不用说知道它的一些优势和缺点是什么。 GRPC是代表 grpc远程过程调用的递归首字母缩写词。它是HTTP 2.0协议和协议缓冲区的组合,也称为Protobufs。
GRPC有益什么?
GRPC的主要优点是它是一种通用通信协议,因为原始缓冲区被编码为二进制(您可以比这更简单!)。因此,它非常适合分布式计算和交换以不同语言或框架编写但仍需要进行交流的系统之间的消息。尽管诸如HTTP协议之类的东西也可以用于此跨系统通信,但这是每个系统还必须让服务器公开具有有效端点等的某种类型的REST或REST样服务的开销。 Protobufs虽然在某些层面上比在HTTP上更严格,但代码中的代码可能与单线一样容易。
GRPC的速度也比传统的HTTP快得多,这要归功于传输消息的二进制格式。这使其非常适合服务之间的低延迟通信。
GRPC的缺点
就像技术中的所有内容一样,没有什么是银色子弹,即使有令人印象深刻的好处,GRPC也不例外。截至2022年6月13日,当这篇文章发表时,GRPC(所有客户端问题,尤其是Web)有关键的缺点:
-
A proxy is required to communicate from web clients to a server running gRPC,此代理只有两种选择: The Improbable gRPC-Web client或b。 The Google gRPC-Web client
-
目前,neither implementation conforms completely to the full gRPC specification。
(顺便说一句,如果您想知道要选择哪个,只有Improbable gRPC-Web client目前支持双向流,它更接近GRPC的完整规格。)
开始
后端实现
首先,我从GRPC推荐学习GRPC的入门存储库,their **helloworld **example, which is a part of the official gRPC repository。
使用该代码,我在GO中添加了一种新的实用方法,称为 reververs :
package utils
// Reverse returns its argument string reversed rune-wise left to right.
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
并修改了 sayhello 函数的原始实现,以使用此反向函数:
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
log.Printf("Returning: %v", utils.Reverse(in.GetName()))
return &pb.HelloReply{Message: utils.Reverse(in.GetName())}, nil
}
前端实现
我用 create-react-app 脚手架,删除了所有额外的绒毛(样式,图像等),并添加了一些描述文本,并带有 。
现在很酷的部分:我决定使用自定义式钩子来控制消息的状态,响应,和与GRPC调用交互。挂钩聆听用户提供的消息的值,并且每当更改时,都会调用GRPC方法Reverser Service。这很简洁地作为一个钩子,我称 usegreeterservice :
import { useEffect, useState } from "react";
import { sayHello } from "../services/greeterService";
export const useGreeterService = (): [
string,
React.Dispatch<React.SetStateAction<string>>,
string
] => {
const [message, setMessage] = useState("");
const [responseMessage, setResponseMessage] = useState("");
useEffect(() => {
sayHello(message, setResponseMessage);
}, [message]);
return [message, setMessage, responseMessage];
};
请注意 sayhello 呼叫的微妙力量 - 单线!否提取,没有配置标头,cookie,http方法或构建一些自定义API服务-GRPC为我们摘要所有这些。
用法 usegreeterservice app.tsx 看起来像这样:
import { useState } from "react"
import { useGreeterService } from "./hooks/useGreeterService";
const App = () => {
const [message, setMessage, responseMessage] = useGreeterService();
return (
<>
<h1>Simple message reverser over gRPC</h1>
<p>(Don't ask me why you would actually want to reverse a string server-side, this is just for fun!</p>
<label title="Type a message in realtime over the gRPC wire">Type a message in realtime over the gRPC wire:</label>
<br/>
<textarea value={message} onChange={(event) => setMessage(event.target.value)}/>
<p>And see the response message here: {responseMessage}</p>
</>
);
}
export default App;
GRPC Web代理
一旦您的后端和前端启动并运行,仍然需要添加一个项目:GRPC代理。幸运的是,我们有不可能使用的代理。首先,使用:
安装
GOPATH=~/go ; export GOPATH
git clone https://github.com/improbable-eng/grpc-web.git $GOPATH/src/github.com/improbable-eng/grpc-web
cd $GOPATH/src/github.com/improbable-eng/grpc-web
dep ensure # after installing dep
go install ./go/grpcwebproxy # installs into $GOPATH/bin/grpcwebproxy
然后以:
运行它
GOPATH=~/go ; export GOPATH
$GOPATH/bin/grpcwebproxy \
--backend_addr=localhost:50051 \
--run_tls_server=false \
--use_websockets \
--allow_all_origins
注意:在我的原始实验中,我想将Websocket用作运输层以达到最佳性能。但是,在对GRPC进行进一步审查(以及上述)后,使用WebSocket作为传输层仍然是实验功能,因此我建议从上面的命令中删除* - use_websockets ** flag在生产中运行网络代理。
(尽管我不清楚使用Websocket作为运输层的实验性是什么。对于这个简单的例子,我没有遇到任何问题!)
示例代码
code from this little experiment can be found on GitHub。读书我可以为您提供有关如何启动和运行的更多详细信息。
我不得不说,从我最初的愚弄之后,我对所看到的表演感到惊讶。从我的角度来看,我无法告诉您,我发现每次击键的客户端的 string.redverse() >进行往返 - 首先使用字符串调用服务器,然后用反向字符串响应服务器! (当然,这一切都在Localhost上运行,因此我不确定这在真实服务器上的外观,但我可以想象它几乎一样快)。但是就像我说的那样,从最初的感觉开始,它确实会感觉 fast !
谢谢!
如果您想潜入GRPC世界,我希望这篇文章说服您尝试展示带有完整的堆栈GRPC呼叫的启动和运行的容易!
欢呼! ð»
-Chris
我的任务是教授1,000,000个新兴开发人员现实世界中的软件!查看我的博客以获取更多信息:
和我的Udemy个人资料和课程: