10分钟解决高并发:Egg.js+Redis缓存与分布式锁实战

10分钟解决高并发:Egg.js+Redis缓存与分布式锁实战

【免费下载链接】egg 🥚 Born to build better enterprise frameworks and apps with Node.js & Koa 【免费下载链接】egg 项目地址: https://gitcode.com/gh_mirrors/egg11/egg

你还在为接口响应慢、数据库压力大而烦恼吗?当用户量激增时,重复查询数据库导致系统性能急剧下降,甚至出现超卖等数据一致性问题。本文将带你通过Egg.js与Redis集成,仅需3步即可实现高效缓存和分布式锁,彻底解决这些痛点。读完本文你将掌握:Redis缓存策略设计、分布式锁实现方案、Egg.js插件最佳实践。

为什么选择Egg.js+Redis架构

Egg.js作为企业级Node.js框架,提供了强大的插件机制和规范的项目结构。Redis作为高性能的内存数据库,完美解决缓存和分布式协调问题。二者结合能显著提升系统吞吐量,实验数据显示可降低90%的数据库访问压力。

Egg.js的分层架构确保了缓存逻辑的可维护性: Egg.js框架架构

环境准备与插件配置

安装egg-redis插件

npm i egg-redis --save

启用插件

// config/plugin.js
exports.redis = {
  enable: true,
  package: 'egg-redis',
};

配置Redis连接

// config/config.default.js
exports.redis = {
  client: {
    host: '127.0.0.1',
    port: 6379,
    password: '',
    db: 0,
  },
};

缓存实现:提升接口响应速度

基础缓存策略

在Service层实现缓存逻辑,以用户信息查询为例:

// app/service/user.js
module.exports = app => {
  class UserService extends app.Service {
    async getUserById(id) {
      const cacheKey = `user:${id}`;
      
      // 尝试从缓存获取
      const cachedUser = await this.app.redis.get(cacheKey);
      if (cachedUser) {
        this.ctx.logger.info(`[缓存命中] 用户${id}`);
        return JSON.parse(cachedUser);
      }
      
      // 缓存未命中,查询数据库
      const user = await this.app.mysql.get('users', { id });
      if (user) {
        // 设置缓存,过期时间10分钟
        await this.app.redis.setex(cacheKey, 600, JSON.stringify(user));
      }
      return user;
    }
  }
  return UserService;
};

缓存更新策略

数据更新时同步更新缓存:

async updateUser(id, data) {
  // 更新数据库
  const result = await this.app.mysql.update('users', { id, ...data });
  
  // 清除缓存
  const cacheKey = `user:${id}`;
  await this.app.redis.del(cacheKey);
  
  return result;
}

分布式锁:解决并发资源竞争

基于Redis的分布式锁实现

// app/service/lock.js
module.exports = app => {
  class LockService extends app.Service {
    async acquireLock(resource, timeout = 5000) {
      const lockKey = `lock:${resource}`;
      const lockValue = Date.now() + timeout;
      const acquired = await this.app.redis.set(lockKey, lockValue, 'NX', 'PX', timeout);
      
      if (acquired) {
        return lockValue;
      }
      
      // 检查锁是否过期
      const currentValue = await this.app.redis.get(lockKey);
      if (currentValue && currentValue < Date.now()) {
        // 尝试获取过期锁
        const oldValue = await this.app.redis.getset(lockKey, lockValue);
        if (oldValue === currentValue) {
          return lockValue;
        }
      }
      
      return null;
    }
    
    async releaseLock(resource, lockValue) {
      const lockKey = `lock:${resource}`;
      const currentValue = await this.app.redis.get(lockKey);
      
      if (currentValue === lockValue) {
        await this.app.redis.del(lockKey);
        return true;
      }
      return false;
    }
  }
  return LockService;
};

库存扣减场景应用

// app/service/inventory.js
module.exports = app => {
  class InventoryService extends app.Service {
    async deductProductStock(productId, quantity) {
      const lockKey = `product:${productId}`;
      
      // 获取锁
      const lockValue = await this.ctx.service.lock.acquireLock(lockKey);
      if (!lockValue) {
        throw new Error('获取锁失败,请重试');
      }
      
      try {
        // 查询库存
        const inventory = await this.app.mysql.get('inventory', { product_id: productId });
        if (!inventory || inventory.stock < quantity) {
          throw new Error('库存不足');
        }
        
        // 扣减库存
        return await this.app.mysql.update('inventory', {
          id: inventory.id,
          stock: inventory.stock - quantity
        });
      } finally {
        // 释放锁
        await this.ctx.service.lock.releaseLock(lockKey, lockValue);
      }
    }
  }
  return InventoryService;
};

最佳实践与注意事项

缓存设计原则

  1. 合理设置过期时间:根据数据更新频率调整TTL,避免缓存雪崩
  2. 缓存穿透防护:对空结果也进行缓存,设置较短过期时间
  3. 缓存预热:系统启动时加载热点数据到缓存

分布式锁注意事项

  1. 设置合理超时时间:避免死锁
  2. 保证锁的原子性:使用Redis的SETNX命令
  3. 业务幂等性设计:即使锁失效也不会导致数据不一致

总结

通过Egg.js与Redis的集成,我们实现了高效的缓存策略和可靠的分布式锁机制。缓存显著提升了系统响应速度,分布式锁则解决了分布式环境下的资源竞争问题。这些技术的应用,为构建高并发、高可用的企业级应用提供了有力保障。

完整代码示例可参考:

【免费下载链接】egg 🥚 Born to build better enterprise frameworks and apps with Node.js & Koa 【免费下载链接】egg 项目地址: https://gitcode.com/gh_mirrors/egg11/egg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值