标签: grpc-go

GRPC 消息结构

我正在将遗留应用程序(一些微服务和整体应用程序)迁移到使用 GRPC。目前整个代码库都在 GO 中。

我已经开始对我的消息进行建模,它们看起来与我在应用程序代码中使用的结构非常相似。我定义了两次相同的对象似乎很奇怪,但使用消息对象作为核心结构也似乎很奇怪。不过,似乎我会有大量的内存密集型数据整理。下面是消息和结构的示例以及它们的相似之处。

对于决定如何对我的消息进行建模,是否有任何建议/最佳实践?它们应该与我的核心结构保持一致吗?我是否应该不关心从 Golang 结构到消息的所有编组?

如果我问这样一个基本问题,请原谅我,因为我对协议缓冲区和 GRPC 非常陌生。

消息原型定义:

message Profile {
    string UID = 1;
    string ContactEmail = 2;
    google.protobuf.Timestamp DateOfBirth = 3;
    float WeightInKilos = 4;
    string Gender = 5;
    string Unit = 6;
    string CurrentStatus = 7;
    string Country = 8;
    string ExperienceType = 9;
    google.protobuf.Timestamp DateJoined = 10;
    repeated Ability Abilities = 11;
    repeated Role Roles = 12;
    repeated TermsAndConditionsAcceptance TermsAndConditionsAcceptances = 13;
    string TimeZone = 14;
    repeated BaselineTestResults BaselineTests =15;
    //Excluded UpdatedDate …
Run Code Online (Sandbox Code Playgroud)

go protocol-buffers grpc grpc-go

7
推荐指数
1
解决办法
2308
查看次数

使用 WithDetails() 从 gRPC 状态包传递自定义原型消息

我最近一直在尝试 gRPC 错误处理,并希望将我自己的原始消息传递给客户端(定义我自己的错误详细信息和内部错误代码)。经过搜索后,发现了几个使用 gRPC 状态包中的 WithDetails() 来附加自定义元数据的示例。我开始实施相同的如下

gRPC 原型消息

message ErrorInfo {
    int64 error_code = 1;
    string error_message = 2;
    string resource_name = 3;
}
Run Code Online (Sandbox Code Playgroud)

服务器端实现

// Frame the error message
        st := status.New(codes.NotFound, "object not found")
        errInfo := &api.ErrorInfo {
            ErrorCode: 100,
            ErrorMessage: "Fetching credential failed",
            ResourceName: req.GetBackupLocation().GetCloudCredential(),
        }
        var err error
        st, err = st.WithDetails(errInfo)
        if err != nil {
            // If this errored, it will always error
            // here, so better panic so we can figure
            // …
Run Code Online (Sandbox Code Playgroud)

go grpc grpc-go

7
推荐指数
1
解决办法
3181
查看次数

将 C# GRPC 客户端连接到 Go Server

我正在尝试从 C# 客户端连接到 Go GRPC 服务器,但客户端通道无法连接到服务器。

我希望连接到由 Go 编写和托管的 GRPC 服务器以及用 C# 编写的客户端时应该没有问题。


我的 Go Server 连接是这样设置的:

lis, err := net.Listen("tcp", ":50051")
if err != nil {
    log.Fatalf("Failed to listen: %v", err)
}

s := grpc.NewServer()

pb.Register**ServiceServer(s, &server{})
reflection.Register(s)
if err := s.Serve(lis); err != nil {
    log.Fatalf("Failed to serve: %v", err)
}
Run Code Online (Sandbox Code Playgroud)

这是相当标准的,我知道我的服务器正在工作,因为我能够使用提供的端口与 Go 客户端连接:

conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用 C# 客户端使用Grpc.Net.Client包进行连接时:

var channel = GrpcChannel.ForAddress(@"http://localhost:50051", new GrpcChannelOptions
{
   Credentials = ChannelCredentials.Insecure
});
Run Code Online (Sandbox Code Playgroud)

我得到一个Grpc.Core.RpcException: …

c# go grpc grpc-go

7
推荐指数
1
解决办法
1066
查看次数

为什么grpc-go可以在相同的地址和端口运行grpc服务器和http服务器,但grpc-node不能

我读过这个答案:/sf/answers/3986064001/,它说无法使用grpc-nodepackage.json 在相同的地址和端口运行 gRPC 服务器和 HTTP 服务器。

但我可以使用 package.json 在相同的地址和端口(例如都使用localhost:3000)创建 gRPC 服务器和 HTTP 服务器grpc-go。这是一个示例: https: //github.com/mrdulin/grpc-go-cnode/blob/master/cmd/server/main.go#L79

那么,为什么 grpc-node 和 grpc-go 的行为不一致。这有道理吗?

我期望的结果是,无论grpc中实现什么语言,行为都应该是一致的。所以grpc服务器应该能够与同一系统进程中的Node标准库http创建的服务器共享相同的端口。

grpc grpc-node grpc-go

7
推荐指数
2
解决办法
5043
查看次数

protoc-gen-go 和 protoc-gen-go-grpc 的区别

我对protoc-gen-govs有点困惑protoc-gen-go-grpc。我知道:

  • protoc-gen-go 包含用于 protobuf 消息序列化/反序列化的代码
  • protoc-gen-go-grpc 包含 gRPC 服务器和客户端的代码

但是,我正在使用以下命令

protoc -I $protodir --go_out=plugins=grpc:./genproto/ $protodir/v1/foo.proto
Run Code Online (Sandbox Code Playgroud)

并且生成的foo.pb.go包含用于消息序列化gRPC 服务器/客户端的代码。另外,我只protoc-gen-go安装在我的系统上。

我有一种感觉,这是在 GO 中进行 gRPC旧方法,新方法protoc --go_out=. --go-grpc_out=.

问题:

  1. 为什么这仅适用于protoc --go_out=.(为什么它还生成 gRPC 客户端/服务器代码?)
  2. 使用一种方法与另一种方法相比有什么优势?

谢谢,直流

grpc-go

7
推荐指数
1
解决办法
1668
查看次数

gRPC 上下文取消传播

我试图了解 Go 上下文取消在客户端服务通信(例如任何 gRPC API 调用)中是如何工作的。

假设客户端取消了上下文。这是否会导致向服务器发出新的 HTTP 请求,并取消先前/正在进行的 gRPC 请求的上下文?服务器如何知道客户端是否取消了上下文?

go grpc grpc-go

7
推荐指数
1
解决办法
5204
查看次数

如何在 Golang gRPC 中获取客户端 IP 地址和用户代理?

我设置了一系列 gRPC 请求和响应,它们都可以正常工作,但是当我尝试获取客户端 IP 地址和调用我的 gRPC API 的用户代理时,我卡住了。

我阅读了 Go gRPC 文档和其他来源,但没有找到太多有价值的信息。他们中很少有人谈论 Golang 中的 gRPC。

在设置 gRPC API 时,我应该设置一个键值来在上下文中存储 IP 地址吗?

go grpc grpc-go

6
推荐指数
1
解决办法
6139
查看次数

如何在 gRPC 中识别断开连接的客户端?

我正在使用 gRPC 构建 API,并且在服务器端,我想在客户端断开连接时收到通知,识别它并基于此执行一些任务。

到目前为止,我能够使用grpc.StatsHandlermethod检测客户端断开连接HandleConn。我尝试使用上下文传递值,但无法从服务器端访问它们。

客户端:

conn, err := grpc.DialContext(
    context.WithValue(context.Background(), "user_id", 1234),
    address,
    grpc.WithInsecure(),
)
Run Code Online (Sandbox Code Playgroud)

服务器端:

// Build stats handler
type serverStats struct {}

func (h *serverStats) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context {
    return ctx
}

func (h *serverStats) HandleRPC(ctx context.Context, s stats.RPCStats) {}

func (h *serverStats) TagConn(ctx context.Context, info *stats.ConnTagInfo) context.Context {
    return context.TODO()
}

func (h *serverStats) HandleConn(ctx context.Context, s stats.ConnStats) {
    fmt.Println(ctx.Value("user_id")) // Returns nil, can't access the value

    switch s.(type) { …
Run Code Online (Sandbox Code Playgroud)

go grpc grpc-go

6
推荐指数
1
解决办法
3737
查看次数

gRPC 可以实现 nil 服务器消息吗?

在下面的gRPC-client代码中,第二个是if必要的吗?

status, err := cli.GetStatus(ctx, &empty.Empty{})
if err != nil {
    return err
}

if status == nil {
    // this should NEVER happen - right?
    return fmt.Errorf("nil Status result returned") 
}
Run Code Online (Sandbox Code Playgroud)

go 直觉上,为了以防万一,应该始终检查 nil 。但是,有一个运行时检查来捕获任何客户端到服务器的nil使用情况,例如

status, err := cli.GetStatus(ctx, nil) // <- runtime error

if err != nil {
    // "rpc error: code = Internal desc = grpc: error while marshaling: proto: Marshal called with nil"
    return err
}
Run Code Online (Sandbox Code Playgroud)

那么是否存在类似的服务器到客户端运行时保证,从而消除检查的需要status == …

go grpc grpc-go

6
推荐指数
1
解决办法
5609
查看次数

Go GRPC 双向流性能

我们正在开发一个高频交易平台,并且在我们的一个组件中,我们已经使用 golang 实现了 grpc。我们需要在我们的一个用例中使用双向流,我们制作了一个示例实现,如下面的代码,但是当我们通过检查日志时间戳之间的差异来测试代码的性能时

Recv Time %v Index: %v Num: %v
Send Time %v, Index: %v, Num: %v
Run Code Online (Sandbox Code Playgroud)

我们发现从客户端调用流的.Send方法并通过在服务器端调用.Recv接收相同的数据大约需要 400-800 微秒,这对我们来说太低了。我们需要最大 10-50 微秒的性能,当我们阅读指南时,我们看到如果客户端和服务器在同一台计算机上,grpc 可以达到纳秒(这正是我们的情况)

所以我认为我们缺少一些选项或一些关于它的性能技巧。有谁知道我们可以做些什么来增加这个性能问题

客户代码:

package main

import (
    "context"
    "log"
    "math/rand"

    pb "github.com/pahanini/go-grpc-bidirectional-streaming-example/src/proto"

    "time"

    "google.golang.org/grpc"
)

func main() {
    rand.Seed(time.Now().Unix())

    // dail server
    conn, err := grpc.Dial(":50005", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("can not connect with server %v", err)
    }

    // create stream
    client := pb.NewMathClient(conn)
    stream, err := client.Max(context.Background())
    if err != …
Run Code Online (Sandbox Code Playgroud)

go grpc grpc-go

6
推荐指数
0
解决办法
1312
查看次数

标签 统计

grpc-go ×10

grpc ×9

go ×8

c# ×1

grpc-node ×1

protocol-buffers ×1