[SOLVED]nodejs 写的定时脚本脚本,老卡死不执行,求解。
发布于 3年前 作者 lanisle 2781 次浏览

标准输出没有内容,cron日志显示都有定时执行,早上上班的时候发现多条记录卡死,下面是清理后运行一会又卡死的进程

ps -ef | grep node

root     25651 25650  0 10:46 ?        00:00:00 /bin/sh -c
/opt/nodejs/bin/node /web/hosts/services/main.js
root     25652 25651  0 10:46 ?        00:00:00 /opt/nodejs/bin/node
/web/hosts/services/nba_programs/main.js

代码内有三个同步执行的外部请求,用于抓取服务需要的内容。

main.js

var fs = require('fs')
  , jsdom = require('jsdom')
  , Memcached = require('memcached');

var qqnba = require('./qqnba')
  , ppnba = require('./ppnba');

var logpath = __dirname + '/run.log';

var pplive = {}, qqlive = {}, qqreview = [];

ppnba.load(function(live) {
    pplive = live;
    console.log('ppnba loaded.');
    
    qqnba.load(function(live, review) {
        qqlive = live;
        qqreview = review;
        console.log('qqnba loaded.');
        
        console.log('grabing programs.');
        grabPrograms();
    });
});

function grabPrograms()
{
    jsdom.env('http://www.zhibo8.com/', ['https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'],
    function(errors, window) {
        var $ = window.$;

        var days = [];
        var boxes = $('#left > .box');

        var istoday = true;
        boxes.each(function(index) {
            var day = { date: null, programs: []};
            var box = $(this);
            // dom 分析
        }

        var cache = JSON.stringify(days);
        //fs.writeFile(cachepath, cache);

        var m = new Memcached('127.0.0.1:11211');
        m.set('nba_programs', cache, 10000, function(error, result) {
            m.end();
        });

        writeLog('Size: ' + cache.length);

        console.log('Done.');
    });
}

function writeLog(content)
{
    var d = new Date();
    var prefix = '[' + d.getFullYear() + '-' +  d.getMonth() + '-'  + d.getDate() + ' ' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + ']';

    content = prefix + ' ' + content + '\n';

    fs.open(logpath, 'a+', 0666, function(error, fd) {
        fs.write(fd, new Buffer(content), 0, content.length, null, function(error, written) {
            fs.close(fd);
        })
    });
}

qqnba.js

var iconv = require('iconv');
var request = require('request');

var headers = {
    //...
}

function qqnba() {}

qqnba.load = function(callback) {
    var live = {}, review = [];
    
    request({ uri:'http://sports.qq.com/c/today_schedules_new.htm', headers: headers }, function(error, response, body) {
        body = (new iconv.Iconv('GBK','UTF-8//TRANSLIT//IGNORE')).convert(new Buffer(body)).toString();
        body = body.substr(0, body.length - 64);
        // JSON 分析
        callback(live, review);
    });
}

module.exports = qqnba;

ppnba.js

var fs = require('fs');
var iconv = require('iconv');
var jsdom = require('jsdom');
var request = require('request');

function ppnba() {}

ppnba.load = function(callback) {
    var programs = {};

    request({uri: 'http://www.ppnba.com/', encoding: 'binary'},
        function(error, response, body) {
            body = new Buffer(body, 'binary');
            conv = new iconv.Iconv('gbk', 'utf8');
            body = conv.convert(body).toString();

            jsdom.env({
                html: body,
                src: [fs.readFileSync('./jquery.min.js').toString()],
                done: function(error, window) {
                    // dom 分析
                    callback(programs);
                }
            });
        }
    );
}

module.exports = ppnba;

function fetchURL(raw)
{
    var matches = /ppnba=(http.*)/.exec(raw);
    return matches[1];
}
6 回复

具体代码能贴出来分析下吗?

不好意思,刚才觉得太长就没发,现在把dom和json分析的去掉后发出来了。

贴上代码,shell手动执行都很OK。

一些细节:

cron文件一直在执行,但是log文件的mtime停留在最后一次执行成功的时候 使用>>输出到debug.log,这个文件内容始终为0(脚本是有输出调试信息到&1的),mtime也停留在最后一次执行成功的时候

fs.readFileSync('.jquery.min.js').toString()

解决了,是working directory不对导致本地的jquery载入失败的问题,加了__dirname就好了。

烦空白输出……

相对路径操作文件都会有风险,要和当前路径绑定死。看代码好像在做一些很神奇的爬虫。。。

@suqian 就抓NBA的节目直播表,谢谢指点,:)

回到顶部