如何处理GO GRPC中的背压?

zfycwa2u  于 2023-01-22  发布在  Go
关注(0)|答案(2)|浏览(187)

我有一个场景,客户机可以通过GRPC连接到服务器,我希望在其上实现背压,这意味着我希望接受许多并发请求10000,但只有50个并发线程执行这些请求(这是受ApacheTomcatNIO接口行为的启发)。我还希望通信是异步的,以一种React的方式,这意味着客户端发送请求但不等待它,并且服务器稍后发回响应,然后客户端执行注册要执行的某个功能。
我怎样在GOGRPC中做到这一点?我应该使用流吗?有例子吗?

hmae6n7t

hmae6n7t1#

GoLang API是一个同步API,这就是GoLang通常的工作方式。你在while true循环中阻塞,直到一个事件发生,然后你继续处理那个事件。至于有更多的线程同时执行请求,我们不在客户端控制。在客户端gRPC之上的应用层,你可以派生更多的Goroutine,服务器端已经为每个接受的连接甚至连接上的流派生了一个goroutine,所以服务器端已经存在固有的多线程。

qjp7pelc

qjp7pelc2#

注意go中没有线程,我们使用goroutine。
所描述的行为已内置到GRC服务器中。例如,请参阅此选项。

// NumStreamWorkers returns a ServerOption that sets the number of worker
// goroutines that should be used to process incoming streams. Setting this to
// zero (default) will disable workers and spawn a new goroutine for each
// stream.
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
// later release.
func NumStreamWorkers(numServerWorkers uint32) ServerOption {
    // TODO: If/when this API gets stabilized (i.e. stream workers become the
    // only way streams are processed), change the behavior of the zero value to
    // a sane default. Preliminary experiments suggest that a value equal to the
    // number of CPUs available is most performant; requires thorough testing.
    return newFuncServerOption(func(o *serverOptions) {
        o.numServerWorkers = numServerWorkers
    })
}

工作线程在某个时刻被初始化。

// initServerWorkers creates worker goroutines and channels to process incoming
// connections to reduce the time spent overall on runtime.morestack.
func (s *Server) initServerWorkers() {
    s.serverWorkerChannels = make([]chan *serverWorkerData, s.opts.numServerWorkers)
    for i := uint32(0); i < s.opts.numServerWorkers; i++ {
        s.serverWorkerChannels[i] = make(chan *serverWorkerData)
        go s.serverWorker(s.serverWorkerChannels[i])
    }
}

我建议您自己阅读服务器代码,了解更多信息。

相关问题