zoukankan      html  css  js  c++  java
  • 使用redis实现nodejs并发服务

    const redisClient = require('redis').createClient(6379, '127.0.0.1');
    const crypto = require('crypto')
    
    const lockScript = 'return redis.call("set", KEYS[1], ARGV[1], "NX", "PX", ARGV[2])'
    const unlockScript = 'if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end'
    
    redisClient.set("num","0")
    
    
    for(let i=0;i<1000;i++) add()
    for(let i=0;i<1000;i++) add()
    for(let i=0;i<1000;i++) add()
    
    
    async function add() {
        let resourse = "lock:num"
        let uniqueStr = crypto.randomBytes(10).toString('hex')
    
        await attemplock(resourse, uniqueStr)
        let nowCityNum = Number(await get('num'))
        num++
        await set('num', String(num))
        await unlock(resourse, uniqueStr)
    }
    
    async function loop(resourse, uniqueStr, ttl) {
        return new Promise((resolve, reject) => {
            setTimeout(async () => {
                let result = await lock(resourse, uniqueStr, ttl)
                resolve(!!result)
            }, 10)
        })
    }
    
    async function attemplock(resourse, uniqueStr, ttl) {
        let result = await loop(resourse, uniqueStr, ttl)
        if (result) {
            return true
        } else {
            return attemplock(resourse, uniqueStr, ttl)
        }
    }
    
    async function lock(resourse, uniqueStr, ttl) {
        ttl = ttl ? ttl : "30000"
        return new Promise((resolve, reject) => {
            redisClient.eval(lockScript, 1, resourse, uniqueStr, ttl, (err, reply) => {
                if (err) {
                    console.error(err)
                    reject(err)
                }
    
                resolve(reply)
            })
        })
    }
    
    async function unlock(resourse, uniqueStr) {
        return new Promise((resolve, reject) => {
            redisClient.eval(unlockScript, 1, resourse, uniqueStr, (err, reply) => {
                if (err) {
                    console.error(err)
                    reject(err)
                }
    
                resolve(reply)
            })
        })
    }
    
    
    async function get(key) {
        return new Promise((resolve, reject) => {
            redisClient.get(key, (err, reply) => {
                if (err) {
                    console.error(err);
                    reject(err)
                }
                resolve(reply)
            })
        })
    }
    
    async function set(key, value) {
        return new Promise((resolve, reject) => {
            redisClient.set(key, value, (err, reply) => {
                if (err) {
                    console.error(err)
                    reject(err)
                }
                resolve(reply)
            })
        })
    }
    async function setnx(key, value) {
        return new Promise((resolve, reject) => {
            redisClient.setnx(key, value, (err, reply) => {
                if (err) {
                    console.error(err)
                    reject(err)
                }
                resolve(reply)
            })
        })
    }
  • 相关阅读:
    Centos7 安装 MySQL5.7
    搭建Harbor企业级docker仓库
    HAProxy安装文档
    mysqlbinlog查看 binlog日志报错mysqlbinlog: unknown variable 'default-character-set=utf8mb4'
    mysql删除数据库报错及解决方法
    服务器流量异常排查步骤(查看进程的流量)
    基于Docker Hub镜像的ProxySQL容器化部署与运行
    ProxySQL环境下,快速处理异常会话的方法(黑名单、KILL)
    DB2 SQL 错误(SQLCODE:-964,SQLSTATE:57011)处理方法
    pg_hba.conf、pool_hba.conf 以及 pool_passwd 三者间的关系
  • 原文地址:https://www.cnblogs.com/BlackFungus/p/12329521.html
Copyright © 2011-2022 走看看