Can't set headers after they are sent,几个客户端并发访问必现 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lupo

Can't set headers after they are sent,几个客户端并发访问必现

  •  
  •   lupo 2018 年 3 月 5 日 5593 次点击
    这是一个创建于 2973 天前的主题,其中的信息可能已经有所发展或是发生改变。
    router.get('/', function (req, res, next) {
    MongoClient.connect(url, function (err, db) {
    if (err) {
    console.log('connect error');
    throw err;
    }
    console.log('connect success');
    db.collection('live_collection').find().toArray(function(err, result) {
    if (err) {
    console.log('find error');
    db.close();
    throw err;
    }
    console.log('query success');
    db.close();
    // console.log(result);
    return res.json({message: 'request for live success', ret: 0, match: result});
    })
    })
    });

    return res.json({message: 'request for live success', ret: 0, match: result});这里出错,网上搜的说法和我这个都不一样,我这个用法很简单,应该不会存在 callback 被调用两次的情况。但据我抓包看,出错的时候服务会发送一个 404,这个应该是 express 自己发的,我的代码里面没有这样的逻辑。不知道为什么会有这样错误,折腾很久了也没找出原因,求大神帮助。。
    8 条回复    2018-03-12 09:00:31 +08:00
    yimity
        1
    yimity  
       2018 年 3 月 5 日 via Android
    每个分支都 return 一下。
    e8c47a0d
        2
    e8c47a0d  
       2018 年 3 月 7 日
    请注意 return 是写在回调里的,这个请求到最后都没有回复任何内容。另外用 async await 来简化代码把,还有 db 不需要每个请求都去连接,可以在 node 启动时连接,然后设置 global.db = db。

    router.get('/', async (req, res) => {
    try {
    await db.collection('live_collection')
    .find().toArray()
    }
    catch (e) {

    }
    res.json(...)
    })
    e8c47a0d
        3
    e8c47a0d  
       2018 年 3 月 7 日
    请求在 res.json 执行前已经被切断了
    e8c47a0d
        4
    e8c47a0d  
       2018 年 3 月 7 日
    注意 MongoDB 如果写入操作失败不会 throw 错误,而是会返回一个 writeResult,需要自己 throw。
    lupo
        5
    lupo  
    OP
       2018 年 3 月 8 日
    @e8c47a0d 谢谢大佬帮助,但这个问题不是必现的,只有在并发多的时候才出现,感觉不像是你说的那样。我是个 node.js 小白,感觉 node.js 比较轻量用来写一个 web API 服务,但这个问题一直没搞定。。。
    从 console.log 的输出情况来看,出错的时候 mongodb 的接口并没有出错。。
    e8c47a0d
        6
    e8c47a0d  
       2018 年 3 月 8 日
    很有可能是并发的时候,建立了太多 db 实例,到一定上限的时候被 mongo 驳回了……
    lupo
        7
    lupo  
    OP
       2018 年 3 月 8 日
    @e8c47a0d 我的并发也不多,4~5 个客户端就出现了每个客户端 5 秒请求一次。。。实在不行,就换 python 或者 go 了
    wotemelon
        8
    wotemelon  
       2018 年 3 月 12 日
    不需要每个请求都去 connect 一遍
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1409 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 40ms UTC 17:02 PVG 01:02 LAX 10:02 JFK 13:02
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86