Supervisorでamon2アプリのデーモン化 with plenv
使用ツールなど
amon2(flavor=Basic)
perl 5.16.3(plenv 使用)
carton
Supervisor
(一般ユーザー名をhomepageとしている)
今回はデプロイのためにamon2で作ったアプリをデーモン化しようとしたが、-Dオプションでデーモン化ができなかったため、supervisorを導入することにした。
(※概要などはこちらのブログを参考にしてみてください → http://blog.hakutoitoi.com/?p=343)
Supervisorのインストール
# yum install python-setuptools # easy_install pip # pip install supervisor
必要なディレクトリを作成
# mkdir /var/log/supervisord # mkdir /etc/supervisord.d
# vi /etc/supervisord.conf [unix_http_server] file=/var/run/supervisor.sock [supervisord] logfile=/var/log/supervisord.log loglevel=debug pidfile=/var/run/supervisord.pid nodaemon=false minfds=1024 minprocs=200 environment=SHELL="/bin/sh" [supervisorctl] serverurl=unix:///var/run/supervisor.sock history_file=~/.sc_history [include] files=/etc/supervisord.d/*.ini [rpcinterface:supervisor] supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
# vi /etc/supervisord.d/supervisord.ini [group:supervisord] programs=サービス名(カンマ区切りでいくつも追加可能) [program:サービス名] command=bash アプリルートまでの絶対path/hoge.sh numprocs=1 autostart=true autorestart=true startsecs=5 user=homepage redirect_stderr=true stdout_logfile=/var/log/supervisord/サービス名_out.log stdout_logfile_maxbytes=0 stdout_logfile_backups=0 stderr_logfile=/var/log/supervisord/サービス名_err.log stderr_logfile_maxbytes=0 stderr_logfile_backups=0 environment=HOME="/home/homepage",USER="homepage", PATH="$HOME/.plenv/bin:$PATH" directory=アプリルートまでの絶対path
今回はplenvを使っているので普通に起動するとシステムのperlを見に行ってplenvでの設定が適用されず、エラーになりまくる。なのでまずはパスを設定しておくことが重要。
[program:サービス名]以下のcommand=の部分は実際に実行するコマンドを設定するのだが、この時にそのコマンド自体のパスを指定してやらなければならない。今回はそこをshellスクリプトでまとめてアプリのルートディレクトリに置いている。
# アプリのルートディレクトリ/hoge.sh #!/bin/bash export PATH="$HOME/.plenv/bin:$PATH" eval "$(plenv init -)" exec plenv exec carton exec plackup app.psgi
このhoge.shに設定を色々書いているのだがここでplenvのパスを通しておく(設定しておく)ことが超重要!
3行目に起動コマンドを記述している。
"plenv exec"でplenvのperlを使うことを指定、"carton exec"でcartonのcpanを使用することを指定している。1行目のexecは全体の実行。これがないとsupervisorをリスタートさせた時にうまくいかない。
Upstart経由でsupervisorを起動
# vi /etc/init/supervisord.conf description "supervisord" start on runlevel [2345] stop on runlevel [!2345] respawn exec /usr/bin/supervisord -n
Supervisorのイニシャルスタート
# initctl start supervisord
エラーが出た後は基本的には、supervisorctl reload → supervisorctl statusしてエラーログみての繰り返しで解決しましょう。
下記、簡単にですがこの作業途中に使ったsupervisorのコマンド一覧
☁ ~homepage supervisorctl reload ☁ ~homepage supervisorctl status ☁ ~homepage supervisorctl restart グループ名:サービス名
僕の場合、start出来たもののrestartをかけるとうまくプロセスを殺してくれないというエラーにも遭遇しました。
☁ ~homepage supervisorctl restart supervisord:サービス名 supervisord:サービス名: stopped supervisord:サービス名: ERROR (abnormal termination)
これは上のhoge.shの3行目に書いてある起動コマンドの先頭にexecをつけていないために起こったようです。なので上のとおりやっていれば起こらないと思いますが一応念の為にメモ。
☁ ~homepage supervisorctl restart supervisord:サービス名 supervisord:サービス名: stopped supervisord:サービス名: started
これで成功です。ブラウザからアクセスしてみてください。(plackだと5000番ポートがデフォルトなのでlocalhost:5000などで。)
-----------------------------------
Supervisor導入途中でいろいろ出たエラー(・∀・)
hoge.sh: line 2: carton: command not found hoge.sh: line 1: plenv: command not found hoge.sh: line 2: carton: command not found hoge.sh: line 1: plenv: command not found hoge.sh: line 2: carton: command not found hoge.sh: line 1: plenv: command not found hoge.sh: line 2: carton: command not found
これはcartonとplenvのパスが通っていないため。上述したように、これらのパスを指定することがまず重要。plenvを使っている際はcrontabなどでも同じようなエラーにぶち当たることがあるようなので注意。(※自戒も込めて)
/usr/bin/env: bash: No such file or directory /usr/bin/env: bash: No such file or directory /usr/bin/env: bash: No such file or directory /usr/bin/env: bash: No such file or directory /usr/bin/env: bash: No such file or directory /usr/bin/env: bash: No such file or directory /usr/bin/env: bash: No such file or directory
これは僕の環境ではoh-my-zshを使用しているため、zshを使っているのですが、supervisorの設定をbashとしていたことを失念していたことによりエラー。ということで、command=bash ~~とした。
以上です。導入するのは大変ですが、一度入れてしまうと超便利かと。先輩に教わりながら進めていったのですが、自分の知識不足と能力不足がまた改めて顕になりました。。。引き続きがんばります!
CSVファイルをmysqlにインポートした時のエラー対応 ーー Incorrect integer value: '1' for column 'num' at row 1
mysqlにCSVファイルをインポートしようとした時にエラーがでまくったところから解決までのメモメモ。。
CSVを普通に入れてみた
mysql> load data local infile '/home/user/Category.csv' into table categories fields terminated by ',' (num, name);
エラーでまくったのでエラー文言みてみると・・
mysql> show warnings; Incorrect integer value: '1' for column 'num' at row 1
半角数字の1が入っているはずなのにintegerじゃないと怒られる。
(数字やろなんやねんふざけんなとか言いながらすすめる・・・)
なんか一応データは入ってるみたい。
mysql> select * from categories; +----+------+---------------------+ | id | num | name | +----+------+---------------------+ || ラーメン |肉 |3 | ハンバーグ |食 |華 |ば |司 |喫茶店 |カレー |親子丼 | 11 | うどん・そば |うどん |3 | イタリアン || ラーメン |肉 |3 | ハンバーグ |食 |華 |ば |司 |喫茶店 |カレー |親子丼 | 11 | うどん・そば |うどん |3 | イタリアン +----+------+---------------------+ 26 rows in set (0.00 sec)
でもぐちゃぐちゃ。。
mysql> select * from categories\G;
でやると綺麗にデータが見えるという謎。。
文字コードの問題かと思ったので調べてみた。
➜ ~ nkf --guess RestaurantCategory.csv UTF-8 (CR)
大丈夫そう。
改行コードとか?
➜ ~ file Category.csv Category.csv: UTF-8 Unicode (with BOM) text, with CRLF line terminators
お?CRLFってWindowsの改行コードだよな。ってことでUnixの改行コードに変更する。
➜ ~ tr -d \\r
<Category.csv> LF_Category.csv
でもまだできず・・・。で、もう無理かと思ったところ
BOMありが原因になることあるよねーという記事を何処かで見つけて
あれ?確かwith BOMって、、
ってことでみてみると
➜ ~ file LF_Category.csv LF_Category.csv: UTF-8 Unicode (with BOM) text
やっぱり。
ってことでuconvコマンドで変更できるみたいなので
コマンドがあるか確認。
➜ ~ uconv zsh: correct 'uconv' to 'ujconv' [nyae]? n zsh: command not found: uconv
ない。
入れてみる。
➜ ~ sudo yum install uconv -y
そんなのない
なんかicuで全部入ってくるみたいなので入れてみる
➜ ~ sudo yum install icu -y
➜ ~ uconv -f utf-8 -t utf-8 --remove-signature LF_Category.csv > no_bom_Category.csv
➜ ~ file no_bom_RestaurantCategory.csv no_bom_RestaurantCategory.csv: UTF-8 Unicode text
うまくいった。
で、あとは
mysql> load data local infile '/home/user/Category.csv' into table categories fields terminated by ',' (num, name); mysql> select * from categories; +----+------+--------------------+ | id | num | name | +----+------+--------------------+ | 1 | 1 | ラーメン | | 2 | 2 | 焼肉 | | 3 | 3 | ハンバーグ | | 4 | 4 | 定食 | | 5 | 5 | 中華 | | 6 | 6 | そば | | 7 | 7 | 寿司 | | 8 | 8 | 喫茶店 | | 9 | 9 | カレー | | 10 | 10 | 親子丼 | | 11 | 11 | うどん・そば | | 12 | 12 | うどん | | 13 | 13 | イタリアン | +----+------+--------------------+ 13 rows in set (0.00 sec)
きれいにできました。
この辺の知識なくてかなり手こずりましたが無事完了(・∀・)
【CentOS6.4】はじめの環境構築 ... plenv, rbenv, tmux, oh-my-zsh
サーバーをいちからやり直さなければならない機会があったのでメモ。
いつもやってる自分の設定をとりあえず入れようかなという感じです。
まず最低限必要な物をyumで入れちゃう。
# yum install -y gcc make wget git zsh openssl-devel # useradd homepage # passwd homepage # su homepage $ chsh homepage のシェルを変更します。 パスワード: 新しいシェル [/bin/bash]: /bin/zsh シェルを変更しました。
oh-my-zshのインストール
これは補完機能とかが優れていて便利です。ちなみにさっきシェルを変更したのはoh-my-zshを使用するためです。
# curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh # exec $SHELL
plenvでperl環境構築
ここからはperlの環境を作る。普段perlbrewよりもplenvを使っているのでそちらで。
$ git clone git://github.com/tokuhirom/plenv.git ~/.plenv $ echo 'export PATH="$HOME/.plenv/bin:$PATH"' >> ~/.zshrc $ echo 'eval "$(plenv init -)"' >> ~/.zshrc $ exec $SHELL $ plenv available $ plenv install 5.16.3 $ plenv global 5.16.3 $ plenv local 5.16.3
一回再起動したら反映されてるはず。
cpanmもついでに入れちゃう。
$ plenv install-cpanm
tmux
下記の記事の通りに。screenみたいなやつですね。
http://tech-mr-myself.hatenablog.com/entry/2013/04/13/235458
rbenvでruby環境構築
ruby環境を整える。rbenvはこの辺を参考に。
http://qiita.com/items/1cb882b48b1a827a420d
私の場合、この後rbenv -v, ruby -v, gem -vはきちんと表示されたのですが、
gem install railsとした際に、
# gem install rails ERROR: Loading command: install (LoadError) cannot load such file -- zlib ERROR: While executing gem ... (NameError) uninitialized constant Gem::Commands::InstallCommand
というエラーが出ました。
なので、
# yum install readline-devel # wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
yamlは./configure→make→make install→make cleanでインストール。
その後、rbenv install 1.9.3-p396という感じでもう一度インストール。
# gem install rails .... file 'lib' not found
またエラーがでました。うぅぅ・・・。萎えますがあとひと踏ん張り。
# gem install rdoc # gem install rails # rails -v Rails 3.2.13
成功です!
以上、駆け足でしたが最低限の環境構築。また何か追加があれば記述します。
tmuxインストール
OS... CentOS_6.4(32bit)
とりあえずmakeコマンドも無かったのでyumで入れちゃう
# yum install -y make
tmuxインストールのためにlibeventが必要なのだがCentOSのlibeventのバージョンは1で、tmuxはバージョン2を要求してくるため、ソースからmakeする。
# wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz # tar zxvf libevent-2.0.21-stable.tar.gz # cd libevent-2.0.21-stable # ./configure # make # make install
pathを指定する必要があるためlibevent.confをつくる
# vim /etc/ld.so.conf.d/libevent.conf
そのなかにhttp://libevent-2.0.so .5のインストールされた場所のパスを書く。
/usr/local/libなど
tmuxをインストール
# wget http://downloads.sourceforge.net/tmux/tmux-1.8.tar.gz # tar zxvf tmux-1.8.tar.gz # cd tmux-1.8 # ./configure # make # make install
さきほどのlibeventの設定を活かすためにldconfigコマンドを。
# ldconfig
以上でtmuxコマンドでtmuxが立ち上がるようになるかと思います。
「勝負」について。
少し前に「勝ち続ける意志力」という本を読みました。
著者は一般的には少し変わった職業と思われる「プロ・ゲーマー」である梅原大吾さんという方です。私はこの方を本を読むまだ知りませんでしたし、ゲームもまったくしないのですが、非常に感銘を受けました。
読み終えてひとつ思ったことが、「自分は高校卒業までサッカーを真剣にやってきた。振り返って辛かったり、苦労したり、感極まる思いをしたり、栄光を掴んだ瞬間を味わったり。だから、この“勝負の世界”というものが何たるかは、彼と同じレベルではないにしても理解することが出来る。頭ではなく全身で。ただ、そういう経験のない人にとてはどうなのだろう?」と。
ふたパターンあると思います。
真剣な勝負をしてきた人生。そうでない人生。
そうでない人生というとマイナスイメージがつくかもしれませんが、真剣勝負が起こらなかった人生といってもいいかもしれません。
そしてこれから書くことは後者を否定することではなくて、ただ前者を選んできて良かったなというだけのお話です。
私はプログラマーの端くれなのでたまに思うことがあるのです。小さい頃からプログラミングばかりしておけば技術が高くなるからそっちのほうが良かったのかなと。でもそうばかりではないと。
ITの世界というのは他産業とは比べ物にならないくらい開けた世界だと思います。オープンソースが前提のような考えであり、大小様々な勉強会やコミュニティーがあり、相互に様々な人が助けあい、教え合っています。
そんな中でずっと育っていけば、確かに楽しいかもしれません。でもその中にギリギリの真剣勝負というのは生まれないと思うのです。
プログラマーとしての仕事もまさにそうだと思います。日々技術を磨いたり、良いサービスをつくるための努力というのはもちろんあります。非常にそれが大変だったり苦労が伴うというのはわかっています。でもその中に勝負はない。
梅原さんの幼少期の回想部分の記述で、秀才のお姉さんに絶望感にも似た感情を抱いた後の場面、
先に鉄棒から手を離せば、先にプールから顔を上げれば、この先の人生で姉のような人物に出会ったとき、いつも頭を下げなくてはいけない。それは絶対に嫌だった。死んでも先に音を上げるわけにはいかなかった。
というシーン。こういう気持ちって限界の勝負をしてきた人にしか真に感じることができなくて、例えばビジネス上の複雑な利害関係であったり駆け引きであったり、はたまたみんなでいいもの作ろうよ!というような場所では経験できないのではないかと思うのです。別にそれが悪いとか良いとかと言っているのではありません。
“勝負”について思うこと。
上で挙げたような場面では真剣勝負はあまり起こり得ないといいましたが、日常の中ではそれが“自分との戦い”として何度も何度も訪れます。
それは日々幾度と無く訪れる決断の場面、自分のチャレンジの過程の中でです。
例えば、何かを選択する際に自分の限界よりちょっと低めのうまくいきそうなものを選びそうになる、自分で選択したもののうまくいかず外部要因のせいにしてしまいそうになる。つまり負の思考が生まれる瞬間です。
この“負の思考が生まれる瞬間”は人が本当に弱くなる瞬間です。そうした場面で最終的にどうできるかはそれが生まれた瞬間の自分との真剣勝負に勝てるかどうかにかかっています。そして今までの人生でそうした真剣勝負をしてきた人間はその最も難しい勝負に勝てる可能性が高いと思うのです。
最後に。私が一番感動し、心に留めておきたいと思った一文です。
険しい道を選べるかどうかは、打ち込んでいるものが本人にとってどれだけ大事かに掛かっていると思う。
ゲーマーという特殊な、時には周りの人から嘲笑されるような立場であった梅原さんの言葉だからこそ、心が動かされました。