前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nodejs服务全局超时回调里取不到process.domain问题

nodejs服务全局超时回调里取不到process.domain问题

原创
作者头像
蒙古上单2
修改2023-04-13 16:16:02
1.1K0
修改2023-04-13 16:16:02
举报
文章被收录于专栏:第二蒙古上单

我们的服务器出现了一个问题,当触发了express的全局超时后,在server.setTimeout的回调里,process.domain是undefined。

由于我们将每次访问产生的reqId、用户id等信息保存在process.domain里。如果取不到process.domain,我们就很难在海量的日志里找出这次的错误日志,给排查线上问题造成了困难。

下面是简化后的代码:

代码语言:javascript
复制
const domain = require('domain');
const express = require('express');
const app = express();
const http = require('http');
const sleep = (ts) => (new Promise(resolve => setTimeout(resolve, ts)))

app.use((req, res, next) => {
    const d = domain.create();
    d.id = 999999;
    d.add(req);
	d.add(res);
	d.run(next);
});

let testRouter = express.Router();
testRouter.get('/', async function (req, res) {
    await sleep(2000);//等2秒,让程序必定进入全局超时逻辑
    res.send('hello world!');
});
app.use('/test', testRouter);

const server = http.createServer(app).listen(3000, '127.0.0.1', () => {});

server.setTimeout(1000, (socket) => {
    console.log(process.domain);//这里的结果是undefined
});

在stackoverflow里,看到有个老哥说这是domain作用域的问题,必须要将正确的作用域挂载到domain里。我试了一下,找到了解决方法。

原来我们写的是:

代码语言:javascript
复制
d.add(req);
d.add(res);

解决方案是将req.socket也加到domain作用域里去,即下面的写法:

代码语言:javascript
复制
d.add(req);
d.add(res);
d.add(req.socket);

我还没搞懂这个domain作用域到底是咋回事,以后再继续研究一下domain组件的源码:

https://github.com/nodejs/node/blob/master/lib/domain.js

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档