繁体   English   中英

将 Golang goroutine 或通道固定到请求/响应

[英]Pin Golang goroutine or channel to request/response

据我所知,默认的 http 路由器以及 gorilla/mux 路由器将每个传入的 HTTP 请求入口点放在自己的 goroutine 上。 像 Node.js 域一样,我们可以在其中将请求固定到域,我们是否可以将 Golang 中的请求固定到 goroutine,如果 goroutine 中出现任何 panic,我们会以错误响应而不是关闭服务器?

在 node.js 中,它可能看起来像:

const domain = require('domain');
const http = require('http');

const server = http.createServer((req,res) => {

  const d = domain.create();

  d.once('error', e =>{
     res.json({error:e}); // check res.headersSent to see if already sent
  });

  res.once('finish', () => {
     d.removeAllListeners(); // prevent memory leak
  });

  d.run(() => {
     handleRequest(req,res);
  });


});

有没有办法用 Golang 中的 goroutines 做类似的事情?

net/http 服务器为每个连接启动一个 goroutine 并调用该 goroutine 上的根处理程序。 我所知道的所有路由器都在调用路由器的 goroutine 上调用已注册的处理程序。 通常在 net/http 服务器上启动的 goroutine 上调用一种或另一种处理程序。 请求的所有执行都在该 goroutine 上执行,除非请求处理程序直接或间接启动另一个 goroutine 来代表请求处理程序执行工作。 由于请求处理程序控制所使用的 goroutine,因此无需将 goroutine 固定到请求中。

net/http 服务器恢复每个连接 goroutine 上的恐慌。 以下是文档对此的说明

如果 ServeHTTP 崩溃,则服务器(ServeHTTP 的调用者)假定恐慌的影响与活动请求隔离。 它恢复恐慌,将堆栈跟踪记录到服务器错误日志,并根据 HTTP 协议关闭网络连接或发送 HTTP/2 RST_STREAM。 要中止处理程序以便客户端看到中断的响应但服务器不记录错误,请使用值 ErrAbortHandler 恐慌。

请求处理程序可以用中间件包装,以使用应用程序提供的逻辑恢复恐慌。 Gorilla 处理程序包是如何执行此操作的一个示例。

如果请求处理程序确实启动了一个 goroutine 来代表请求执行工作,则请求处理程序有责任在该 goroutine 中建立恢复。

是的,你可以从 goroutine panic 中恢复。 这个来自 gorilla 的中间件可以做到这一点,但你自己也很容易做到。 它基本上只是将您的处理程序包装在一个函数中,该函数推迟调用recover()并从那里处理恐慌。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM