固定Golang goroutine或频道以请求/响应

时间:2018-10-26 00:46:54

标签: go

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

在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做类似的事情?

2 个答案:

答案 0 :(得分:3)

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

net / http服务器恢复每个连接goroutine的崩溃。这就是the documentation says about it

  

如果ServeHTTP出现紧急情况,则服务器(ServeHTTP的调用方)将假定紧急情况的影响与活动请求无关。它恢复紧急状态,将堆栈跟踪记录到服务器错误日志中,然后关闭网络连接或发送HTTP / 2 RST_STREAM,具体取决于HTTP协议。要中止处理程序,以便客户端看到中断的响应,但服务器不会记录错误,请惊慌于ErrAbortHandler值。

请求处理程序可以与中间件包装在一起,以使用应用程序提供的逻辑来恢复紧急情况。 Gorilla handlers package是如何执行此操作的一个示例。

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

答案 1 :(得分:2)

是的,您可以从goroutine恐慌中恢复过来。大猩猩的middleware可以做到,但您自己也很容易。基本上,这只是将处理程序包装在一个函数中,该函数推迟调用recover()并从那里处理紧急情况。