教程|构建gRPC-Web和Istio无缝集成的云原生应用
Posted ServiceMesher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了教程|构建gRPC-Web和Istio无缝集成的云原生应用相关的知识,希望对你有一定的参考价值。
gRPC-Web使Web应用能够通过类似于Envoy的代理访问gRPC后端。Envoy是Istio的默认代理,因此,我们可以利用Istio的EnvoyFilter构件来创建无缝连接的云原生应用。
介绍
在这篇文章中,我将引导你构建一个简单的Web应用,使用emoji替换用户输入文本中的关键字,并使用gRPC-Web和Istio与gRPC后端进行通信。
以下是我们创建emoji应用的步骤大纲:
使用Protobuf定义协议格式;
编译Protobuf定义文件,来生成Go和javascript文件;
构建并测试基于Go的gRPC服务,该服务使用emoji替换输入文本中的关键字;
使用gRPC-Web为emoji服务创建Web界面;
配置EnvoyFilter并通过Istio部署后端;
部署Web应用程序并测试我们的emoji服务。
架构
让我们进一步理解emoji服务的最终架构是什么样子。
简而言之,只要用户提供一些文本,Web应用就会利用gRPC-Web库向Istio Gatway发送HTTP请求。然后,Istio网关将HTTP请求路由到emoji服务旁运行的Proxy sidecar,后者使用Envoy的gRPC-Web filter将HTTP调用转换成gRPC调用。
定义协议格式
首先,让我们使用Protobuf定义协议格式。
syntax = "proto3";
package emoji;
service EmojiService {
rpc Emojize (EmojizeRequest) returns (EmojizeReply);
}
message EmojizeRequest {
string text = 1;
}
message EmojizeReply {
string emojized_text = 1;
}
我们定义一个名为 EmojiService
的 service
,处理名为 Emojize
的 rpc
调用,该调用接受 EmojizeRequest
对象参数并返回一个 EmojizeReply
实例。
EmojizeRequest
消息参数包含一个名为 text
的 string
类型的字段,表示用户输入的文本。同样, EmojizeReply
包含一个名为 emojized_text
的 string
类型的字段,表示最终输出的字符,也即服务端将emoji关键字替换为emoji表情符号的输出内容。
编译Protobuf定义文件
我们先创建一个名为 grpc-web-emoji/emoji/
的项目目录结构,然后把前面的定义内容写入名为 emoji.proto
的文件。
然后编译emoji.proto文件并生成所需要的Go文件。
$ protoc -I emoji/ emoji/emoji.proto --go_out=plugins=grpc:emoji
同样,我们也生成JavaScript文件。
$ protoc -I emoji/ emoji/emoji.proto --js_out=import_style=commonjs:emoji
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:emoji
此时,您将获得如下所示的目录结构。
── grpc-web-emoji
└── emoji
├── emoji.pb.go
├── emoji.proto
├── emoji_grpc_web_pb.js
└── emoji_pb.js
构建和测试Go后端程序
现在让我们创建一个实现 EmojiService
API的Go程序。为此,我们使用以下内容创建一个名为 main.go
的文件。
package main
import (
"context"
"log"
"net"
proto "github.com/venilnoronha/grpc-web-emoji/emoji"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
emoji "gopkg.in/kyokomi/emoji.v1"
)
// server is used to implement the EmojiService interface
type server struct{}
// Emojize takes a input string via EmojizeRequest, replaces known keywords with
// actual emoji characters and returns it via a EmojizeReply instance.
func (s *server) Emojize(c context.Context, r *proto.EmojizeRequest)
(*proto.EmojizeReply, error) {
return &proto.EmojizeReply{EmojizedText: emoji.Sprint(r.Text)}, nil
}
func main() {
// listen to TCP requests over port 9000
lis, err := net.Listen("tcp", ":9000")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
log.Printf("listening on %s", lis.Addr())
// register the EmojiService implementation with the gRPC server
s := grpc.NewServer()
proto.RegisterEmojiServiceServer(s, &server{})
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
我已经使用 kyokomi/emoji
库来完成繁重的工作,即将输入文本中的关键字转换为表情符号。
启动服务后如下所示:
$ go run -v main.go
2018/11/12 10:45:12 listening on [::]:9000
我们创建一个名为emoji_client.go的客户端,来实现通过程序测试emoji服务。
package main
import (
"log"
"time"
proto "github.com/venilnoronha/grpc-web-emoji/emoji"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
func main() {
// connect to the server
conn, err := grpc.Dial("localhost:9000", grpc.WithInsecure())
if err != nil {
log.Fatalf("could not connect to the service: %v", err)
}
defer conn.Close()
// send a request to the server
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
c := proto.NewEmojiServiceClient(conn)
resp, err := c.Emojize(ctx, &proto.EmojizeRequest{
Text: "I like :pizza: and :sushi:!",
})
if err != nil {
log.Fatalf("could not call service: %v", err)
}
log.Printf("server says: %s", resp.GetEmojizedText())
}
我们现在可以运行emoji服务客户端,如下所示。
$ go run emoji_client.go
2018/11/12 10:55:52 server says: I like
以上是关于教程|构建gRPC-Web和Istio无缝集成的云原生应用的主要内容,如果未能解决你的问题,请参考以下文章