>  기사  >  백엔드 개발  >  Laravel 지연 대기열 구현의 Lua 스크립트 분석

Laravel 지연 대기열 구현의 Lua 스크립트 분석

不言
不言원래의
2018-04-16 14:29:122502검색

이 글은 주로 Laravel 지연 대기열 구현에 대한 Lua 스크립트 분석을 소개합니다. 이제 이를 공유합니다. 도움이 필요한 친구들이 참고할 수 있습니다.

Laravel은 Redis 지연 대기열을 구현할 때 Lua 스크립트를 사용합니다. 서로 다른 대기열 간의 작업 원자성을 보장합니다
Laravel5.1에서는 서로 다른 대기열의 작업의 원자성을 보장하기 위해 주로 네 가지 Lua 스크립트 메서드가 사용됩니다.

1 대기열 작업 수를 계산하는 방법

1.llen 개수 계산 of list queues

2. zcard는 zset 대기열 데이터 볼륨을 계산합니다

    /**
     * Get the Lua script for computing the size of queue.
     *
     * KEYS[1] - The name of the primary queue
     * KEYS[2] - The name of the "delayed" queue
     * KEYS[3] - The name of the "reserved" queue
     *
     * @return string
     */
    public static function size()
    {
        return <<<&#39;LUA&#39;
             return redis.call(&#39;llen&#39;, KEYS[1]) + redis.call(&#39;zcard&#39;, KEYS[2]) + 
             redis.call(&#39;zcard&#39;, KEYS[3])
        LUA;
    }

2. 팝 대기열 작업을 예약 대기열에 넣습니다

    /**
     * Get the Lua script for popping the next job off of the queue.
     *
     * KEYS[1] - The queue to pop jobs from, for example: queues:foo
     * KEYS[2] - The queue to place reserved jobs on, for example: queues:foo:reserved
     * ARGV[1] - The time at which the reserved job will expire
     *
     * @return string
     */
    public static function pop()
    {
      return <<<&#39;LUA&#39;
          -- Pop the first job off of the queue...
         local job = redis.call(&#39;lpop&#39;, KEYS[1])
         local reserved = false

         if(job ~= false) then
            -- Increment the attempt count and place job on the reserved queue...
            reserved = cjson.decode(job)
            reserved[&#39;attempts&#39;] = reserved[&#39;attempts&#39;] + 1
            reserved = cjson.encode(reserved)
            redis.call(&#39;zadd&#39;, KEYS[2], ARGV[1], reserved)
         end
        return {job, reserved}
      LUA;
    }

3. 예약 대기열의 작업을 지연 대기열에 추가합니다

    /**
     * Get the Lua script for releasing reserved jobs.
     *
     * KEYS[1] - The "delayed" queue we release jobs onto, for example: queues:foo:delayed
     * KEYS[2] - The queue the jobs are currently on, for example: queues:foo:reserved
     * ARGV[1] - The raw payload of the job to add to the "delayed" queue
     * ARGV[2] - The UNIX timestamp at which the job should become available
     *
     * @return string
     */
    public static function release()
    {
        return <<<&#39;LUA&#39;
           -- Remove the job from the current queue...
           redis.call(&#39;zrem&#39;, KEYS[2], ARGV[1])
           -- Add the job onto the "delayed" queue...
           redis.call(&#39;zadd&#39;, KEYS[1], ARGV[2], ARGV[1])
           return true
        LUA;
    }

4. 시간에 맞는 예약된 대기열의 작업 실행 대기열에 병합됨

    /**
     * Get the Lua script to migrate expired jobs back onto the queue.
     *
     * KEYS[1] - The queue we are removing jobs from, for example: queues:foo:reserved
     * KEYS[2] - The queue we are moving jobs to, for example: queues:foo
     * ARGV[1] - The current UNIX timestamp
     *
     * @return string
     */
    public static function migrateExpiredJobs()
    {
        return <<<&#39;LUA&#39;
        -- Get all of the jobs with an expired "score"...
           local val = redis.call(&#39;zrangebyscore&#39;, KEYS[1], &#39;-inf&#39;, ARGV[1])

        -- If we have values in the array, we will remove them from the first queue
        -- and add them onto the destination queue in chunks of 100, which moves
        -- all of the appropriate jobs onto the destination queue very safely.
           if(next(val) ~= nil) then
             redis.call(&#39;zremrangebyrank&#39;, KEYS[1], 0, #val - 1)

             for i = 1, #val, 100 do
               redis.call(&#39;rpush&#39;, KEYS[2], unpack(val, i, math.min(i+99, #val)))
             end
           end
          return val
        LUA;
}

                                                                                                                                       ’

위 내용은 Laravel 지연 대기열 구현의 Lua 스크립트 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.