教程|构建gRPC-Web和Istio无缝集成的云原生应用

Posted ServiceMesher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了教程|构建gRPC-Web和Istio无缝集成的云原生应用相关的知识,希望对你有一定的参考价值。

gRPC-Web使Web应用能够通过类似于Envoy的代理访问gRPC后端。Envoy是Istio的默认代理,因此,我们可以利用Istio的EnvoyFilter构件来创建无缝连接的云原生应用。

教程|构建gRPC-Web和Istio无缝集成的云原生应用 教程|构建gRPC-Web和Istio无缝集成的云原生应用

介绍

在这篇文章中,我将引导你构建一个简单的Web应用,使用emoji替换用户输入文本中的关键字,并使用gRPC-Web和Istio与gRPC后端进行通信。

以下是我们创建emoji应用的步骤大纲:

  1. 使用Protobuf定义协议格式;

  2. 编译Protobuf定义文件,来生成Go和javascript文件;

  3. 构建并测试基于Go的gRPC服务,该服务使用emoji替换输入文本中的关键字;

  4. 使用gRPC-Web为emoji服务创建Web界面;

  5. 配置EnvoyFilter并通过Istio部署后端;

  6. 部署Web应用程序并测试我们的emoji服务。

架构

让我们进一步理解emoji服务的最终架构是什么样子。

教程|构建gRPC-Web和Istio无缝集成的云原生应用

简而言之,只要用户提供一些文本,Web应用就会利用gRPC-Web库向Istio Gatway发送HTTP请求。然后,Istio网关将HTTP请求路由到emoji服务旁运行的Proxy sidecar,后者使用Envoy的gRPC-Web filter将HTTP调用转换成gRPC调用。

定义协议格式

首先,让我们使用Protobuf定义协议格式。

 
   
   
 
  1. syntax = "proto3";


  2. package emoji;


  3. service EmojiService {

  4.  rpc Emojize (EmojizeRequest) returns (EmojizeReply);

  5. }


  6. message EmojizeRequest {

  7.  string text = 1;

  8. }


  9. message EmojizeReply {

  10.  string emojized_text = 1;

  11. }

我们定义一个名为 EmojiServiceservice,处理名为 Emojizerpc调用,该调用接受 EmojizeRequest对象参数并返回一个 EmojizeReply实例。

EmojizeRequest消息参数包含一个名为 textstring类型的字段,表示用户输入的文本。同样, EmojizeReply包含一个名为 emojized_textstring类型的字段,表示最终输出的字符,也即服务端将emoji关键字替换为emoji表情符号的输出内容。

编译Protobuf定义文件

我们先创建一个名为 grpc-web-emoji/emoji/的项目目录结构,然后把前面的定义内容写入名为 emoji.proto的文件。

然后编译emoji.proto文件并生成所需要的Go文件。

 
   
   
 
  1. $ protoc -I emoji/ emoji/emoji.proto --go_out=plugins=grpc:emoji

同样,我们也生成JavaScript文件。

 
   
   
 
  1. $ protoc -I emoji/ emoji/emoji.proto --js_out=import_style=commonjs:emoji

  2.         --grpc-web_out=import_style=commonjs,mode=grpcwebtext:emoji

此时,您将获得如下所示的目录结构。

 
   
   
 
  1. ── grpc-web-emoji

  2.   └── emoji

  3.       ├── emoji.pb.go

  4.       ├── emoji.proto

  5.       ├── emoji_grpc_web_pb.js

  6.       └── emoji_pb.js

构建和测试Go后端程序

现在让我们创建一个实现 EmojiService API的Go程序。为此,我们使用以下内容创建一个名为 main.go的文件。

 
   
   
 
  1. package main


  2. import (

  3.    "context"

  4.    "log"

  5.    "net"


  6.    proto "github.com/venilnoronha/grpc-web-emoji/emoji"

  7.    "google.golang.org/grpc"

  8.    "google.golang.org/grpc/reflection"

  9.    emoji "gopkg.in/kyokomi/emoji.v1"

  10. )


  11. // server is used to implement the EmojiService interface

  12. type server struct{}


  13. // Emojize takes a input string via EmojizeRequest, replaces known keywords with

  14. // actual emoji characters and returns it via a EmojizeReply instance.

  15. func (s *server) Emojize(c context.Context, r *proto.EmojizeRequest)

  16.            (*proto.EmojizeReply, error) {

  17.    return &proto.EmojizeReply{EmojizedText: emoji.Sprint(r.Text)}, nil

  18. }


  19. func main() {

  20.    // listen to TCP requests over port 9000

  21.    lis, err := net.Listen("tcp", ":9000")

  22.    if err != nil {

  23.        log.Fatalf("failed to listen: %v", err)

  24.    }

  25.    log.Printf("listening on %s", lis.Addr())


  26.    // register the EmojiService implementation with the gRPC server

  27.    s := grpc.NewServer()

  28.    proto.RegisterEmojiServiceServer(s, &server{})

  29.    reflection.Register(s)

  30.    if err := s.Serve(lis); err != nil {

  31.        log.Fatalf("failed to serve: %v", err)

  32.    }

  33. }

我已经使用 kyokomi/emoji 库来完成繁重的工作,即将输入文本中的关键字转换为表情符号。

启动服务后如下所示:

 
   
   
 
  1. $ go run -v main.go

  2. 2018/11/12 10:45:12 listening on [::]:9000

我们创建一个名为emoji_client.go的客户端,来实现通过程序测试emoji服务。

 
   
   
 
  1. package main


  2. import (

  3.    "log"

  4.    "time"


  5.    proto "github.com/venilnoronha/grpc-web-emoji/emoji"

  6.    "golang.org/x/net/context"

  7.    "google.golang.org/grpc"

  8. )


  9. func main() {

  10.    // connect to the server

  11.    conn, err := grpc.Dial("localhost:9000", grpc.WithInsecure())

  12.    if err != nil {

  13.        log.Fatalf("could not connect to the service: %v", err)

  14.    }

  15.    defer conn.Close()


  16.    // send a request to the server

  17.    ctx, cancel := context.WithTimeout(context.Background(), time.Second)

  18.    defer cancel()


  19.    c := proto.NewEmojiServiceClient(conn)

  20.    resp, err := c.Emojize(ctx, &proto.EmojizeRequest{

  21.        Text: "I like :pizza: and :sushi:!",

  22.    })

  23.    if err != nil {

  24.        log.Fatalf("could not call service: %v", err)

  25.    }

  26.    log.Printf("server says: %s", resp.GetEmojizedText())

  27. }

我们现在可以运行emoji服务客户端,如下所示。

 
   
   
 
  1. $ go run emoji_client.go

  2. 2018/11/12 10:55:52 server says: I like

    以上是关于教程|构建gRPC-Web和Istio无缝集成的云原生应用的主要内容,如果未能解决你的问题,请参考以下文章

    微服务网格:Istio高级特性

    如何使用 grpc-web 构建 react-redux 应用程序?

    jenkins 入门教程

    Istio路由基础教程

    微服务治理 Istio 1.6部署和应用

    Spring Boot+gRPC构建微服务并部署到Istio(详细教程)