openrestyでmysqlをいじる

https://github.com/wyukawa/yanagishima
は認証、認可機能はないんですが、まあ実際問題必要なのでそこは別の仕組みでやってたりします。

認証は社内のシステムにのっかっていて、認可はnginxでリバースプロキシしてそこでluaでやってました。

nginx + lua環境って実は作るのが面倒で、どのぐらい面倒かというと下記のような感じです。
Cent OS(6.4)にNginx + lua-nginx-moduleをインストール - ゆく河の流れは絶えずして...

面倒なんだけど、上記ブログの通りに環境作って運用してました。


ただluaでif文羅列して権限管理するのも辛くなってきたので、そこは一部DB管理にして管理画面も作った方がよかろうということでやりました。

今までの環境だとDBさわれないんで、この機会に全部入りのopenrestyを試そう、そうしようということで試しました。やっと本題に入りました。


openrestyに入っているcomponentは下記の通り
https://openresty.org/en/components.html

yumでインストールできればよかったんですけど、別途モジュールをバインドする必要がありソースビルドしました。

標準だとhttp_stub_status_moduleが入ってないのでそれも追加して下記のようにconfigureしてmakeすればOK

./configure --add-module=... --with-http_stub_status_module

ただそのままだと下記のようにエラーになります。

$ /usr/local/openresty/bin/openresty -h
/usr/local/openresty/bin/openresty: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory

なので、

$ export LD_LIBRARY_PATH=/usr/local/openresty/luajit/lib:$LD_LIBRARY_PATH

すると

$ /usr/local/openresty/bin/openresty -h
nginx version: openresty/1.11.2.4
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: /usr/local/openresty/nginx/)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

nginx 1.12系かと思ったら1.11系なのか。

まあ下記によれば1.11をforkしたのが1.12なので機能的には遜色なさそう。
NGINX 1.12 and 1.13 Released


起動スクリプト
https://gist.github.com/vdel26/8805927
をコピペして上記のLD_LIBRARY_PATH設定を追加しました。


lua+mysqlのコードは nginx実践入門 (WEB+DB PRESS plus) を参考にして下記のようなイメージです。
DBのところをIPアドレスで書いているのはホスト名だと「failed to connect: no resolver defined to resolve」のようにエラーになったためです。

local mysql = require "resty.mysql"
local cjson = require "cjson"

local db, err = mysql:new()
if not db then
  ngx.log(ngx.ERR, "failed to instantiate mysql: ", err)
  return
end

db:set_timeout(1000)

local ok, err, errno, sqlstate = db:connect{
  host = "192.168.0.1",
  port = 3306,
  database = "...",
  user = "...",
  password = "..."
}

if not ok then
  ngx.log(ngx.ERR, "failed to connect: ", err, ": ", errno, " ", sqlstate)
  return
end

local sql = "SELECT ..."
res, err, errno, sqlstate = db:query(sql)
if not res then
  ngx.log(ngx.ERR, "bad result: ", err, ": ", errno, ": ", sqlstate, ".")
  return
end

ngx.say(cjson.encode(res))

local max_idle_timeout = 10000
local pool_size = 50
local ok, err = db:set_keepalive(max_idle_timeout, pool_size)
if not ok then
  ngx.log(ngx.ERR, "failed to set keepalive", err)
  return
end

そんな感じです。

nginx 1.12を網羅したnginx実践入門第二版が欲しいなってちょっと思いました。