LuaのWeb Frameworkの需要はほとんどないと思いますが、LapisというFrameworkを見かけたので触ってみました。
LuaのWeb Frameworkといえば、OrbitやTirがありますが、いずれも開発は止まっていて寂しい限りでした。そこへ最近になって現れたのがLapisです。
Lapisのホームページの頭には、MoonScriptとOpenRestyのWeb Frameworkと書かれています。
MoonScriptはCoffeeScriptにインスパイアされて作られた言語で、CoffeeScriptがJavaScriptに変換されるように、Luaに変換することができます。
また、OpenRestyはNginxに拡張モジュールを入れたもので、コアはNginxそのものです。
インストール
moonscriptとlapisはluarocksでインストールできます。
1 2 |
$ sudo luarocks install moonscript $ sudo luarocks install lapis |
openrestyはtarballをダウントードしてmakeします。
1 2 3 4 5 |
$ tar xzvf ngx_openresty-1.2.8.6.tar.gz $ cd ngx_openresty-1.2.8.6 $ ./configure --with-luajit $ make $ sudo make install |
Lapisプロジェクト
Lapisプロジェクトを作成します。空のディレクトリで以下のコマンドを実行します。生成されるファイルは2つのみです。
1 2 3 4 |
$ lapis new lapis new -> wrote nginx.conf -> wrote mime.types |
サーバーを起動
以下のコマンドでopenrestyが起動します。デフォルトで8080ポートで起動します。
1 |
$ lapis server |
コマンドを実行するとディレクトリやファイルが追加されて以下のような構成になります。この状態でhttp://localhost:8080/にアクセスするとInternal Server Errorとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ tree . ├── client_body_temp ├── fastcgi_temp ├── logs │ ├── access.log │ ├── error.log │ └── nginx.pid ├── mime.types ├── nginx.conf ├── nginx.conf.compiled ├── proxy_temp ├── scgi_temp └── uwsgi_temp |
Hello World!
Hello World!を書いてみます。
デフォルトのnginx.conf設定では、DocumentRootにアクセスした時にweb.luaというファイルを読みにいきます。Luaのコードを書いてもよいのですが、MoonScriptを使ってみます。
web.moon
1 2 3 |
lapis = require "lapis" lapis.serve class extends lapis.Application "/": => "Hello World!" |
以下のコマンドを実行すると、web.luaというファイルが生成されMoonScriptからLuaのコードに変換されます。
1 |
$ moonc web.moon |
web.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
local lapis = require("lapis") return lapis.serve((function() do local _parent_0 = lapis.Application local _base_0 = { ["/"] = function(self) return "Hello World!" end } _base_0.__index = _base_0 setmetatable(_base_0, _parent_0.__base) local _class_0 = setmetatable({ __init = function(self, ...) return _parent_0.__init(self, ...) end, __base = _base_0, __name = nil, __parent = _parent_0 }, { __index = function(cls, name) local val = rawget(_base_0, name) if val == nil then return _parent_0[name] else return val end end, __call = function(cls, ...) local _self_0 = setmetatable({}, _base_0) cls.__init(_self_0, ...) return _self_0 end }) _base_0.__class = _class_0 if _parent_0.__inherited then _parent_0.__inherited(_parent_0, _class_0) end return _class_0 end end)()) |
http://localhost:8080/にアクセスするとHello World!が表示されればOKです。
Tips
MonnScriptを編集するたびにLuaのコードに変換するのは面倒なので、以下のコマンドでmooncを常駐させておくことができます。mooncはカレントディレクトリ以下の.moonファイルの監視していて、更新されるとLuaのコードに変換してくれます。
1 |
$ moonc -w . |
ベンチマーク
apache benchをとってみました。キャッシュを有効にすることで劇的に処理能力が向上します。
キャッシュ無効(lua_code_cache off)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: ngx_openresty/1.2.8.6 Server Hostname: localhost Server Port: 8080 Document Path: / Document Length: 104 bytes Concurrency Level: 1 Time taken for tests: 3.338 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 256000 bytes HTML transferred: 104000 bytes Requests per second: 299.61 [#/sec] (mean) Time per request: 3.338 [ms] (mean) Time per request: 3.338 [ms] (mean, across all concurrent requests) Transfer rate: 74.90 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 3 3 0.9 3 14 Waiting: 3 3 0.9 3 14 Total: 3 3 0.9 3 14 Percentage of the requests served within a certain time (ms) 50% 3 66% 3 75% 3 80% 3 90% 3 95% 3 98% 3 99% 9 100% 14 (longest request) |
キャッシュ有効(lua_code_cache on)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: ngx_openresty/1.2.8.6 Server Hostname: localhost Server Port: 8080 Document Path: / Document Length: 104 bytes Concurrency Level: 1 Time taken for tests: 0.221 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 256000 bytes HTML transferred: 104000 bytes Requests per second: 4521.18 [#/sec] (mean) Time per request: 0.221 [ms] (mean) Time per request: 0.221 [ms] (mean, across all concurrent requests) Transfer rate: 1130.30 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 0 0 0.1 0 1 Waiting: 0 0 0.1 0 1 Total: 0 0 0.1 0 1 Percentage of the requests served within a certain time (ms) 50% 0 66% 0 75% 0 80% 0 90% 0 95% 0 98% 1 99% 1 100% 1 (longest request) |
おまけ
前回紹介しましたPHPのフレームワークPhalconでHello World!のベンチマークをとってみました。WebサーバーはApache、PHPにはAPCを入れています。
Lapis(Nginx+Lua)速いです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking phalcon.local (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: Apache/2.2.22 Server Hostname: phalcon.local Server Port: 80 Document Path: /hello/ Document Length: 117 bytes Concurrency Level: 1 Time taken for tests: 1.984 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 345000 bytes HTML transferred: 117000 bytes Requests per second: 503.97 [#/sec] (mean) Time per request: 1.984 [ms] (mean) Time per request: 1.984 [ms] (mean, across all concurrent requests) Transfer rate: 169.79 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 1 2 0.7 2 3 Waiting: 1 2 0.7 2 3 Total: 1 2 0.7 2 3 Percentage of the requests served within a certain time (ms) 50% 2 66% 2 75% 2 80% 2 90% 3 95% 3 98% 3 99% 3 100% 3 (longest request) |