会鸽项目上的一些坑

Nodejs cyanprobe 7年前 (2017-08-20) 4745次浏览 已收录 1个评论

前言:

公司转栈,已是前端….

正文:

项目的坑如下 巨坑 rethinkdb 真的是学到了,之前都不知道还有这个东西,在并行10做map操作的时候,对一个表进行多次扫描导致连接不能释放cpu压力250%爆炸,对集合进行比较复杂的聚合操作加上并行直接GG 此数据库在集合层面还不能保证原子性,可以说是项目重构的主要原因。 rethinkdb插入查询性能都还可以 1ms以内,复杂聚合需要125ms加上并行扫表聚合和数据集合的庞大(60字段)CPU和内存爆掉。。
并行转串行,串行转并行。在数据库扫表的时候出现一个问题,因为不能保证原子性,要先查再做更改,而扫表的监听操作是不确定的这时候需要放到一个栈里面,然后java架构说不靠谱,挂了岂不是数据就丢失了,好吧,后来设计成redis锁+队列。rabbitmq要设置basic.qos信令 prefetch_count,让消费者一次接受1个,当存在锁的时候使用nack回到队列不标记此消费者失败,也就是当锁阻塞多个消费者的时候,消息之后还可以通过这几个消费者,而不是reject后GG只能走第一个抢占的.

const key                       = "audit-lock-execute";
const ttl                       = 4;
exports.consumeTransactionAudit = async function (message, _channel) {
    try {
        let payloadStr = message.content.toString();
        let unlock     = await  __executeLock(ttl, key);
        if (unlock === 1) {
            return _channel.nack(message, false);// 如果锁被占用,nack回消息
        }
        await exports.auditTransaction(JSON.parse(payloadStr).audit);
        _channel.ack(message);
        unlock();
    } catch (err) {
        logger.error('消费consumeTransactionAudit...出错了,错误信息是', err);
        _channel.reject(message, true);
    }
};

生产者锁保证生产状态意外结束其他进程起来负责生产(只能监听一个扫表行为防止重复)

exports.audit = function () {
    setInterval(function () {
        try {
            alive();
        } catch (err) {
            logger.error('task/audit ', err);
        }
    }, 1000);
};
let status = false;// 进程锁,默认为false代表未锁住
// 更新生存周期,60秒判定失去进程
async function alive(_status) {
    if (status === false) {
        let result = await redisClinet.get('active-audit-lock');
        if (result === null) {
            __processLock();
        }
    }
    if (arguments.length !== 0 || status === true) {
        if (_status === true) {
            status = _status;
        }
        if (status === true) {
            // logger.info(`${process.pid}获得进程锁,锁定60秒...`);
            await redisClinet.set('active-audit-lock', `1`, 'EX', 60);
        }
    }
}
function __processLock() {
    logger.info(`${process.pid}准备争取进程锁...`);
    let key = 'audit-lock';
    let ttl = 61;
    warlock.lock(key, ttl, function (err, unlock) {
        if (err) {
            // Something went wrong and we weren't able to set a lock
            return;
        }
        if (typeof unlock === 'function') {
            if (status === false) {
                require("./process/audit.js");
            }
            alive(true);
        }
    });
}

还有一个电子票的部分,用pantomjs生成的pdf 需要4S左右,用golang纯线条画0.5S都不用还可以并行。而node的并行并状态维护太麻烦。
项目最终用java重构,虽然不是node的锅但还是被甩锅了,java架构问我写不写java,我大概就表示了下java垃圾就像黑我们node一样GG。现在安排在公司写前端,准备放弃,寻找下一个公司。他说了一句话node是前端的东西,尴尬了,从此对java转黑在java这种工业级语言面前我们都是菜鸡….
另外纠正下对JWT的误解,jwt在多个终端时可以保证状态不易被更改,jwt鉴权也学到许多。


CyanProbe , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:会鸽项目上的一些坑
喜欢 (2)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽
  1. 膜拜前端大佬
    姜辰2017-08-22 00:38 回复