Nodejs egg 多机器 定时器只跑一次

发布于 1周前 作者 songsunli 来自 nodejs/Nestjs

Nodejs egg 多机器 定时器只跑一次

负载均衡的机器都有一套 egg 代码 每次运行定时器的时候 各个机器都会跑一遍这个定时任务(这个需求是跑一遍即可) 我看 egg 官方有提供解决方法就是扩展定时任务类型 但是不会用 有木有完整的 demo 分享呀 或者其他的方式解决呢? 跪求大佬

6 回复

有一个 disable 的字段 但是不知道如何利用起来…


负载比较麻烦,最快的解决办法就是搞个 redis 锁

egg 的 agent。

搞一个锁。每个 client 都判断一下是否运行了。

在 Node.js 的 Egg.js 框架中,如果你希望在多机器部署的环境下确保某个定时器只运行一次,可以考虑使用分布式锁机制。Redis 是一个常见的选择,利用其原子性操作来实现锁的功能。

以下是一个基本的实现思路,使用 ioredis 库与 Redis 交互:

  1. 安装 ioredis

    npm install ioredis
    
  2. 在你的 Egg.js 应用中创建一个定时任务,并在任务开始前尝试获取 Redis 锁:

    const Redis = require('ioredis');
    const redis = new Redis({
      host: 'localhost', // 替换为你的 Redis 服务器地址
      port: 6379,
    });
    
    module.exports = app => {
      app.beforeStart(async () => {
        const lockKey = 'myTimerLock';
        const lockValue = Date.now().toString();
        const ttl = 60000; // 锁的有效期,单位毫秒
    
        const result = await redis.set(lockKey, lockValue, 'NX', 'PX', ttl);
        if (result) {
          // 成功获取锁,启动定时器
          setInterval(() => {
            console.log('Timer is running');
          }, 10000); // 每10秒运行一次
        } else {
          console.log('Timer is already running on another instance');
        }
      });
    };
    

上述代码在应用启动时尝试获取一个 Redis 锁,如果成功获取则启动定时器。由于 NX 选项确保只有在键不存在时才设置键,PX 选项设置键的过期时间,这可以避免锁因意外情况被永久持有。如果锁已被其他实例持有,则当前实例不会启动定时器。

回到顶部