当我使用 grpc 编写服务时,我尝试通过服务器端推送机制将 http/2 与 websocket 进行比较。
我知道对于 websocket,客户端将向服务器发送带有 Upgrade: WebSocket 和 Connection: Upgrade 标头的请求并建立长期连接。连接建立后,服务器将自由发送数据。
但对于 grpc,由于它是在 http/2 上路由的,来自 wiki 页面https://en.wikipedia.org/wiki/HTTP/2_Server_Push,它表示服务器需要预测客户端将发送的潜在请求,并尽早发送 PUSH_PROMISE 帧。
这是我的两个问题:
这是否意味着服务器还需要从客户端接收相应的响应(请求)来响应此 PUSH_PROMISE 标头,以决定客户端是否想要接收或拒绝特定推送?
在 Grpc 中,如果我有服务器端流,请说每 1 秒从服务器发送一条消息。这是否意味着服务器需要每 1 秒或至少在服务器推送到客户端的每个数据帧之前向客户端发送 PUSH_PROMISE?
我有一个grpc基准测试代码,该代码使用一个函数使用for-select子句将数百个goroutine通道合并到一个通道。代码是这样的
func (b *B) merge(
ctx context.Context,
nodes ...<-chan *pb.Node,
) chan *pb.Node {
allNodes := make(chan *pb.Node)
var wg sync.WaitGroup
wg.Add(len(nodes))
for _, n := range nodes {
go func(n <-chan *pb.Node) {
defer wg.Done()
for {
select {
case <-ctx.Done():
return
case val, ok := <-n:
if ok {
allNodes <- val
}
}
}
}(n)
}
go func() {
wg.Wait()
close(allNodes)
}()
return allNodes
}
Run Code Online (Sandbox Code Playgroud)
当我在ubuntu 16.04中通过top命令监视代码时,我看到2核服务器变得疯狂,超过了CPU使用率的196%。
然后,我使用pprof包分析了我的代码,它说98%的cpu旋转了此函数,并且top函数生成了这样的结果
flat flat% sum% cum cum%
1640ms 5.78% 5.78% 27700ms …Run Code Online (Sandbox Code Playgroud)