チャットを面白おかしくするおもちゃ箱
Skype や IRCなど、チャットツールは
サービス開発のコミュニケーションツールとしては無くてはならないものである。
しかし時として、場の空気が重くなることもあるだろう。
そんな時、一筋の光をもたらすようなbotがいたなら。。。
時に笑いを提供し、時には場の空気を読まない悪戯小僧のような存在。
そんなライブラリ書いた。
リポジトリ
https://github.com/toritori0318/p5-toy
基本的には「おもしろ画像URL」をランダムに返すだけのライブラリなので、
どのチャットツールでもご利用可能です。
unazusanを利用していれば、exampleをコピペするだけですぐに投入できるでしょう。
プルリクも大歓迎!
画像取得用サービス一覧
*1:エロ的な意味で
M3インスタンスを使わない手はない
最近、また新たにEC2のインスタンスサイズが増えましたね。
【AWS発表】M3インスタンスの新サイズおよび新機能 + EBSの値下げ + S3の値下げ
M3インスタンスはM1インスタンスの後継にあたる汎用インスタンスです。
今回新たに追加された m3.medium / m3.large は価格帯も性能もバランスよく、
非常に使いやすいインスタンスなのではないでしょうか。
本題
ふとM1/M3の料金表を見比べてみたんですが、
同じグレードで比較するとM3の方が料金安いんですよね。
しかも数値上はM3の方が性能も高そうです。
比較表にしてみましょう。*1 *2
インスタンス | vCPU | ECU | RAM(GB) | インスタンスストレージ (GB) | EBS 最適化 | ネットワークパフォーマンス | 時間あたりの料金(東京リージョン) |
---|---|---|---|---|---|---|---|
m3.medium | 1 | 3 | 3.75 | 1 x 4 SSD | - | 中 | $0.171 |
m1.medium | 1 | 2 | 3.75 | 1 x 410 | - | 中 | $0.175 |
インスタンス | vCPU | ECU | RAM(GB) | インスタンスストレージ (GB) | EBS 最適化 | ネットワークパフォーマンス | 時間あたりの料金(東京リージョン) |
---|---|---|---|---|---|---|---|
m3.large | 2 | 6.5 | 7.5 | 1 x 32 SSD | - | 中 | $0.342 |
m1.large | 2 | 4 | 7.5 | 2 x 420 | 可 | 中 | $0.350 |
インスタンス | vCPU | ECU | RAM(GB) | インスタンスストレージ (GB) | EBS 最適化 | ネットワークパフォーマンス | 時間あたりの料金(東京リージョン) |
---|---|---|---|---|---|---|---|
m3.xlarge | 4 | 13 | 15 | 2 x 40 SSD | 可 | 中 | $0.684 |
m1.xlarge | 4 | 8 | 15 | 4 x 420 | 可 | 高 | $0.700 |
まとめ
M1シリーズ、大容量のインスタンスストレージが欲しい以外は
選択する意味があまり無さそうですね。
これはもう「M1を捨ててM3を使え」というAmazonさんからのメッセージと受け取って
M3を使いまくりましょう〜
*1:表はこちらから抜粋させて頂いております http://aws.amazon.com/ec2/instance-types/ http://aws.amazon.com/ec2/pricing/
*2:比較する対象のないm1.smallとm3.2xlargeは除外しています
pip1.5に注意
とある日、素のインスタンスにchef走らせたらpip installで何故かエラーになりました。
デプロイ周りで特にレシピ変更してないし全く身に覚えがない。。。
差分chefインストールだとpipエラー出ないし何でだー?とトレース追ってみると
argparse==1.2.1
でエラってる。そんなバージョンないよって言われる。
pipのバージョン
いろいろ調査した結果、pipのバージョンが怪しいということになって
確認してみると確かに違う。エラーが出るのはpipバージョン1.5だ。
どうやらpip1.5では外部にホストされているモジュールは
デフォルトでインストール出来なくなっているようである。*1
回避策
pip installのオプションで
--allow-all-externalを付けるとうまくインストールされました。
--allow-external PROJECT_NAME で個別にURLを指定することもできるようです。
ということで
pipの最新バージョンを使うと
デフォルトの挙動が変わってしまうので注意しましょう、というお話でした。
他にもいくつか下位互換が失われている変更があるようです。
http://www.pip-installer.org/en/latest/news.html#id1
つかリリース日2014/1/1って。。。
*1:確かに、argparseの1.2.1だけgooglecodeに置かれてる。https://pypi.python.org/simple/argparse/
2013年振り返りと2014年
年末年始バタバタしてたので今頃振り返ってみます。
仕事
DevOps頑張ってた。
監視自動化とか、開発運用共通化とか。
改善前は各モジュールで独自の開発フローや秘伝のタレ化したデプロイツールなど、
担当者がいないと誰も管理できなくなってしまうという
「担当者SPOF」になってしまっていて、
それを改善したいなーと思い
「vagrant + chef + cloudformation」という構成で
インフラ構築/運用/開発フローを共通化するためにいろいろ頑張ってた。
現在はこれを拡張して
- AMIの作成
- image-idを自動でcloudformationのテンプレートに適用
- そのままcloudformationのstack作成/更新/削除
という一連のフローを同じrakeタスクで実行できるようにした。
その結果、どのシステムでも全く同じ手順で
- デプロイ
- インフラ構築
- クラスタ構築
- スケールアウト/スケールイン/スケールアップ/スケールダウン
などが実現できるようになった。
これ実現出来たのは地味にでかいと思ってる。
趣味コーディング
ひょんなことからCPAN Authorになれた。嬉しい。
しかし書きたかったコードはたくさんあったんだけど
それほど書けてなかったような気がする。
プライベート
上の子が幼稚園に入った。
いまだに朝嫌がることはあるが、実際に登園すると普通に楽しんでるようなのであんまり心配してない。女の子にモテてるらしい。くやしい。
下の子はどんどんかわいくなってる。うへぇ
あと結婚10周年でした。美味しいもの食べた。
2014年
仕事関係ではソケットサーバパワーアップさせないと辛いなーって感じになってきてるので
本気でチューニング始める予定。予定は未定。
あと気になってるソリューションがたくさんあるので
徐々に勉強復活させたい。
以下とか。イミュータボー?
- Docker
- Serf
- Mesos
- Graphite
- Sensu
yogaコマンドも追加機能したいタスクがどんどん溜まってきてるので消化したい。
やりたい。やらねば。
nginx-lua-moduleでLuaスクリプト書いてみた
プロダクトでWebサーバ上の現在時刻出したい要件がありました。
これぐらいの処理ならアプリケーション介さずともnginxだけでやりたいですね。
現在時刻ヘッダーにつけるならnginx標準機能で出来そうなんですが、
深淵なる理由からコンテンツとして欲しいとのこと。
今後、Nginx+Lua試してみたいなーという要件もありましたし、
せっかくなのでこの機能をLuaスクリプトで書いてみることにしました。
nginxレシピ
opscodeのnginxクックブックにはluaをインストールするレシピもありました。
しかし、例のごとくそのままでは動かせなかったので
一部オーバーライドしたクックブックを書いてみました。
AWSの生AMIにこれをそのままプロビジョニングするとNginx+Luaが起動することを確認しています。
https://github.com/toritori0318/chef-nginx-lua-sample
直したところ
recipes/lua.rbにパッチを当てたのと、
recipes/source.rbにluaをインストールする処理を差し込んだくらいです。
ちなみにcjsonを入れているのは、今回json形式でレスポンスさせたかったからです。
Luaを動かすだけであればcjsonを入れる必要はありません。
サンプルアプリ仕様
サンプル実装
/etc/nginx/sites-available/lua_current_time
nginxのコンフィグです。
特に語るところはありません。
# Lua soライブラリのパス指定。今回はcjsonのため(ファイルパターンも指定が必要らしい) lua_package_cpath "/usr/local/lib/lua/5.1/?.so"; server { listen 80; access_log /var/log/nginx/access.log; location /current_time { # 外部Luaスクリプト読み込み content_by_lua_file /etc/nginx/lua/current_time.lua; } location / { default_type 'text/plain'; # コードもそのまま書ける content_by_lua "ngx.say('Hello,lua!')"; } }
/etc/nginx/lua/current_time.lua
パラメータを受け取ってゴニョゴニョしています。
特に語るところはありません。
local cjson = require "cjson" local ctime = "" local args = ngx.req.get_uri_args() if args.df == "epoch" then ctime = os.date("%s") else ctime = os.date("%Y-%m-%dT%H:%M:%S %z") end if args.rf == "json" then ngx.header.content_type = "application/json"; ngx.print(cjson.encode({current_time = ctime})) else ngx.header.content_type = "text/plain"; ngx.print(ctime) end
非常に簡単ですね。
ベンチマーク
abしてみました。
コマンドパラメータはこんな感じです。
ab -n 20000 -c 2 http://127.0.0.1/xxxx
/ (Hello Lua)
Server Software: nginx/1.4.3 Server Hostname: 127.0.0.1 Server Port: 80 Document Path: / Document Length: 11 bytes Concurrency Level: 2 Time taken for tests: 2.018 seconds Complete requests: 20000 Failed requests: 0 Write errors: 0 Total transferred: 3060000 bytes HTML transferred: 220000 bytes Requests per second: 9912.15 [#/sec] (mean) Time per request: 0.202 [ms] (mean) Time per request: 0.101 [ms] (mean, across all concurrent requests) Transfer rate: 1481.02 [Kbytes/sec] received
/current_time
Server Software: nginx/1.4.3 Server Hostname: 127.0.0.1 Server Port: 80 Document Path: /current_time Document Length: 25 bytes Concurrency Level: 2 Time taken for tests: 2.339 seconds Complete requests: 20000 Failed requests: 0 Write errors: 0 Total transferred: 3340000 bytes HTML transferred: 500000 bytes Requests per second: 8549.87 [#/sec] (mean) Time per request: 0.234 [ms] (mean) Time per request: 0.117 [ms] (mean, across all concurrent requests) Transfer rate: 1394.36 [Kbytes/sec] received
/static/index.html(静的ファイル配信。このファイルは手動で作りました)
Server Software: nginx/1.4.3 Server Hostname: 127.0.0.1 Server Port: 80 Document Path: /static/index.html Document Length: 6 bytes Concurrency Level: 2 Time taken for tests: 1.942 seconds Complete requests: 20000 Failed requests: 0 Write errors: 0 Total transferred: 4680000 bytes HTML transferred: 120000 bytes Requests per second: 10298.39 [#/sec] (mean) Time per request: 0.194 [ms] (mean) Time per request: 0.097 [ms] (mean, across all concurrent requests) Transfer rate: 2353.34 [Kbytes/sec] received
静的ファイル配信よりわずかに落ちますが十分早い。
Nginx+Lua、環境設定が若干面倒ですが、
上記クックブックを使うと一発で環境作れますし、
Luaスクリプトもお手軽に書けそうなので試してみてはいかがでしょうか〜
(゚Д゚)オLua!オLua!
*1:※追記 openrestyを使うと楽できるようです! http://openresty.org/
chefでattributeファイルを上書きしたい時
attributeファイルのオーバーライド
公式レシピを使う場合に、attributesファイルの一部のパラメータだけ更新したい時があると思います。
jsonでいちいち指定しても良いんですが、共通で設定したいパラメータは
site-cookbooks以下にattributesファイルで書いておきたいこともあります。
その場合、今までは馬鹿正直にオリジナルのレシピを丸々コピペして一部だけ更新する、
といったように使っていたんですが*1
include_attribute使えば簡単に書けるのでは?と思った。
nginxの場合
いままではベタ書きしてたのを…
site-cookbooks/nginx/attributes/default.rb
# オリジナルのattributes/default.rbをコピペ default['nginx']['version'] = '1.2.9' default['nginx']['package_name'] = 'nginx' default['nginx']['dir'] = '/etc/nginx' default['nginx']['script_dir'] = '/usr/sbin' default['nginx']['log_dir'] = '/var/log/nginx' default['nginx']['binary'] = '/usr/sbin/nginx' case node['platform_family'] when 'debian' default['nginx']['user'] = 'www-data' default['nginx']['init_style'] = 'runit' when 'rhel', 'fedora' default['nginx']['user'] = 'nginx' default['nginx']['init_style'] = 'init' default['nginx']['repo_source'] = 'epel' when 'gentoo' default['nginx']['user'] = 'nginx' default['nginx']['init_style'] = 'init' else default['nginx']['user'] = 'www-data' default['nginx']['init_style'] = 'init' end default['nginx']['upstart']['runlevels'] = '2345' default['nginx']['upstart']['respawn_limit'] = nil default['nginx']['upstart']['foreground'] = true default['nginx']['group'] = node['nginx']['user'] default['nginx']['pid'] = '/var/run/nginx.pid' default['nginx']['gzip'] = 'on' default['nginx']['gzip_http_version'] = '1.0' default['nginx']['gzip_comp_level'] = '2' default['nginx']['gzip_proxied'] = 'any' default['nginx']['gzip_vary'] = 'off' default['nginx']['gzip_buffers'] = nil default['nginx']['gzip_types'] = %w[ text/plain text/css application/x-javascript text/xml application/xml application/rss+xml application/atom+xml text/javascript application/javascript application/json text/mathml ] default['nginx']['gzip_min_length'] = 1_000 default['nginx']['gzip_disable'] = 'MSIE [1-6]\.' default['nginx']['keepalive'] = 'on' default['nginx']['keepalive_timeout'] = 65 default['nginx']['worker_processes'] = node['cpu'] && node['cpu']['total'] ? node['cpu']['total'] : 1 default['nginx']['worker_connections'] = 1_024 default['nginx']['worker_rlimit_nofile'] = nil default['nginx']['multi_accept'] = false default['nginx']['event'] = nil default['nginx']['server_tokens'] = nil default['nginx']['server_names_hash_bucket_size'] = 64 default['nginx']['sendfile'] = 'on' default['nginx']['access_log_options'] = nil default['nginx']['error_log_options'] = nil default['nginx']['disable_access_log'] = false default['nginx']['install_method'] = 'package' default['nginx']['default_site_enabled'] = true default['nginx']['types_hash_max_size'] = 2_048 default['nginx']['types_hash_bucket_size'] = 64 default['nginx']['proxy_read_timeout'] = nil default['nginx']['client_body_buffer_size'] = nil default['nginx']['client_max_body_size'] = nil # 一部オーバーライド default['nginx']['version'] = '1.4.3' default['nginx']['install_method'] = 'source'
こう直す。
別ファイルに書く(ファイル名はなんでもいいはず)。
site-cookbooks/nginx/attributes/default_ext.rb
include_attribute 'nginx::default' # customize default['nginx']['version'] = '1.4.3' default['nginx']['install_method'] = 'source'
さっき思いついたのでもしかしたら副作用があるかもしれないですが、
特に問題なければ今まで書いたレシピだいぶ綺麗になりそう。
*1:http://d.hatena.ne.jp/toritori0318/20130509/1368107821 これのopensshのattributeなんかそうですね