Skip to content

Instantly share code, notes, and snippets.

@matsumotory
Created February 16, 2018 12:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matsumotory/72bb2bb8c9a29741dfde03b1968b8ba0 to your computer and use it in GitHub Desktop.
Save matsumotory/72bb2bb8c9a29741dfde03b1968b8ba0 to your computer and use it in GitHub Desktop.

async sleepの実装と既存のテストを全て通せた

従来のsleep

worker_processes  1;
events {
    worker_connections  200;
}

daemon off;
master_process off;

        location /async_sleep {
            mruby_rewrite_handler_code '
              sleep 3
              Nginx.rputs "body"
              Nginx.return Nginx::HTTP_OK
            ';
        }
[ubuntu@ubuntu-xenial:~/DEV/ngx_mruby]$ for i in `seq 1 3`; do time curl localhost:58080/async_sleep & done
[1] 25513
[2] 25515
[3] 25516
[ubuntu@ubuntu-xenial:~/DEV/ngx_mruby]$ body
real    0m3.018s
user    0m0.004s
sys     0m0.000s
body
real    0m6.020s
user    0m0.004s
sys     0m0.000s
body
real    0m9.023s
user    0m0.000s
sys     0m0.004s

[1]   Done                    time curl localhost:58080/async_sleep
[2]-  Done                    time curl localhost:58080/async_sleep
[3]+  Done                    time curl localhost:58080/async_sleep

このように、ひとつのプロセスでsleepを実行すると、シーケンシャルにsleep実行、完了後に次のリクエストのsleepを実行しており、大量にアクセスが集中すると処理が待たされる問題があった。

async sleep

worker_processes  1;
events {
    worker_connections  200;
}

daemon off;
master_process off;

        location /async_sleep {
            mruby_rewrite_handler_code '
              Nginx::Async.sleep 3000
              Nginx.rputs "body"
              Nginx.return Nginx::HTTP_OK
            ';
        }

このようにプロセスが一つなのにリクエスト単位でsleepがnonblockingに実行される

[ubuntu@ubuntu-xenial:~/DEV/ngx_mruby]$ for i in `seq 1 3`; do time curl localhost:58080/async_sleep & done
[1] 25436
[2] 25437
[3] 25439
[ubuntu@ubuntu-xenial:~/DEV/ngx_mruby]$ body
real    0m3.015s
user    0m0.004s
sys     0m0.000s
body
real    0m3.014s
user    0m0.004s
sys     0m0.000s
body
real    0m3.013s
user    0m0.004s
sys     0m0.000s

[1]   Done                    time curl localhost:58080/async_sleep
[2]-  Done                    time curl localhost:58080/async_sleep
[3]+  Done                    time curl localhost:58080/async_sleep

全体のmruby実行環境をFiberで書き換えて、async sleepも同じ方式で動くように実装した。これにより、一つのプロセスで複数のsleepがノンブロッキングにできるようになる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment