herokuでredisとtornadoを使ってみる

tornado redis を連携したアプリを heroku で動かしてみた。

前提
以下はすんでいるものとする。

  • heroku アカウントは作成済み
  • SSH の鍵は登録済み
  • クレジットカード情報は登録済み
  • virtual env はインストール済み
  • redis はデフォルトポート(6379)で起動済み

ローカル開発環境に heroku toolbelt をインストール


heroku にデプロイするときなどに利用するツール群、heroku toolbelt をインストール
オフィシャルのドキュメントに従い、インストール

$ wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh
This script requires superuser access to install apt packages.
You will be prompted for your password by sudo.
...

tornado をデプロイ
続いて、tornado を利用したアプリを heroku にデプロイする。
今回は Tornado-Heroku-Quickstart という heroku のラッパーを利用して、tornado のボイラープレートの作成と heroku へのデプロイまでを一気に済ませてしまう。

https://github.com/mikedory/Tornado-Heroku-Quickstart

$ curl -L 'https://github.com/mikedory/Tornado-Heroku-Quickstart/tarball/master' | tar zx && cd mikedory-Tornado-Heroku-Quickstart-*
 % Total % Received % Xferd Average Speed Time Time Time Current
 Dload Upload Total Spent Left Speed
100 149 100 149 0 0 114 0 0:00:01 0:00:01 --:--:-- 136
100 3710 100 3710 0 0 1353 0 0:00:02 0:00:02 --:--:-- 5269
$ ./init.sh

************************************
Creating directories and fetching dependancies
 % Total % Received % Xferd Average Speed Time Time Time Current
 Dload Upload Total Spent Left Speed
100 93637 0 93637 0 0 121k 0 --:--:-- --:--:-- --:--:-- 171k
 % Total % Received % Xferd Average Speed Time Time Time Current
 Dload Upload Total Spent Left Speed
100 6875 100 6875 0 0 8715 0 --:--:-- --:--:-- --:--:-- 16447
Initialized empty Git repository in /home/jsmith/mikedory-Tornado-Heroku-Quickstart-4030895/.git/
Do you want to start a Heroku app as well?
1) Yes
2) No
#? 1
Committing to Git

... snip ...

-----> Discovering process types
 Procfile declares types -> web
-----> Compiled slug size: 23.0MB
-----> Launching... done, v4
 http://stormy-castle-2941.herokuapp.com deployed to Heroku

To git@heroku.com:stormy-castle-2941.git
 * [new branch] master -> master
New project created! Taking you there now.
Opening stormy-castle-2941.. xprop: unable to open display ''
Failure in opening http://stormy-castle-2941.herokuapp.com/ with options {}: Unable to find a browser command. If this is unexpected, Please rerun with environment variable LAUNCHY_DEBUG=true or the '-d' commandline option and file a bug at https://github.com/copiousfreetime/launchy/issues/new
done
Cleaning up...
Done!
Cleaning up...
Done!
************************************

しばらくすると

  • Tornado のミニマルなボイラープレートが jquery normalize.css と一緒にローカルに構築
  • pip と requirements.txt を利用して heroku 環境へデプロイ
  • ローカルのブラウザでデプロイしたアプリを表示

が行われる。
成功の場合、ブラウザが開き、「hi」の画面が表示される

heroku 上の Python を起動して、tornado がインストールされていることを確認する。

$ heroku run python
Running `python` attached to terminal... up, run.2919
Python 2.7.3 (default, Oct 1 2012, 19:43:58)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tornado
>>>

ローカル環境で tornado を起動
heroku 環境ではなく、ローカル環境でもアプリの動作を確認してみる。
tornado がインストールされていない場合は、pip でインストールする。

$ pip install -r requirements.txt

heroku toolbelt に含まれる foreman というプログラムがプロセス管理を行う。
設定は Procfile で行う。

$ cat Procfile
web: python main.py
$ foreman start
22:47:53 web.1 | started with pid 15544

http://localhost:5000/ にアクセスするとトップ画面が表示される。

tornado と Redis を連携する
オンメモリー KVS の Redis と連携してみる。
ページを表示すると、インクリメントする簡単なカウンターを Redis で実装する。

herokuの設定

heroku redis アドオンを追加する。
今回は、ミニマムプランでは料金のかからない Redis To Go を利用。

$ heroku addons --app stormy-castle-2941
stormy-castle-2941 has no add-ons.
$ heroku addons:add redistogo:nano
Adding redistogo:nano on stormy-castle-2941... done, v6 (free)
Your Redis is in your preferred cloud (aws/us-east-1).
Use `heroku addons:docs redistogo:nano` to view documentation.
$ heroku addons --app stormy-castle-2941
=== stormy-castle-2941 Configured Add-ons
redistogo:nano

設定した redis のインターネット接続用 URL を確認

$ heroku config
=== stormy-castle-2941 Config Vars
REDISTOGO_URL: redis://redistogo:dummy@dory.redistogo.com:9419/

プログラムからは、環境変数 “REDISTOGO_URL” に設定された URL を利用して Redis にアクセスする。

ローカル環境の設定
pip でインストールし、requirements.txt ファイルを更新する。

$ pip install redis
$ pip freeze
redis==2.7.2
tornado==2.4
$ pip freeze > requirements.txt

次に、tornado のアプリにコードを書き足す。

まずはルーティングを追加

@@ -19,9 +19,11 @@
 define("port", default=5000, help="run on the given port", type=int)

# application settings and handle mapping info
+import redis
 class Application(tornado.web.Application):
 def __init__(self):
 handlers = [
+ (r"/counter", CounterHandler),
 (r"/([^/]+)?", MainHandler)
 ]
 settings = dict(

次に、db コネクションを用意。
Redis には環境変数 REDISTOGO_URL で設定された URL でアクセスする。ローカル環境向けの URL も用意しておく。

@@ -30,7 +32,7 @@
 debug=True,
 )
 tornado.web.Application.__init__(self, handlers, **settings)
-
+ self.db = redis.from_url(os.environ.get('REDISTOGO_URL', 'redis://localhost:6379'))

# the main page
 class MainHandler(tornado.web.RequestHandler):

最後にインクリメント処理を追加。

@@ -47,6 +49,12 @@
 google_analytics_id=google_analytics_id,
 )

+# counter page
+class CounterHandler(tornado.web.RequestHandler):
+ def get(self):
+ result = self.application.db.incr('counter')
+ self.write('counter is %d' % result)
+ self.flush()

# RAMMING SPEEEEEEED!
 def main():

foreman を使ってローカル起動
※ローカルでは redis を起動しておくこと

$ foreman start
23:00:06 web.1 | started with pid 16092
23:00:29 web.1 | [I 130130 23:00:29 web:1462] 200 GET /counter (127.0.0.1) 0.49ms

curl でカウンターページにアクセス。

$ curl http://localhost:5000/counter
counter is 1
$ curl http://localhost:5000/counter
counter is 2

無事成功。

プログラムの反映

ローカル環境で動作を確認したので、heroku にデプロイする。
修正したプログラムをコミットして、heroku に push するだけ。
requirements.txt が更新されていれば、デプロイ時に pip でモジュールも更新される。

$ git status .
# On branch master
# Changes not staged for commit:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: heroku.sh
# deleted: init.sh
# modified: main.py
# modified: requirements.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

$ git commit -m 'redis support' main.py requirements.txt
[master bcf75de] redis support
 2 files changed, 13 insertions(+), 3 deletions(-)
$ git push heroku master
Counting objects: 7, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 595 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
-----> Deleting 0 files matching .slugignore patterns.
-----> Python app detected
-----> No runtime.txt provided; assuming python-2.7.3.
-----> Using Python runtime (python-2.7.3)
-----> Installing dependencies using Pip (1.2.1)
 Downloading/unpacking redis==2.7.2 (from -r requirements.txt (line 1))
 Running setup.py egg_info for package redis

Installing collected packages: redis
 Running setup.py install for redis

Successfully installed redis
 Cleaning up...

-----> Discovering process types
 Procfile declares types -> web
-----> Compiled slug size: 23.2MB
-----> Launching... done, v5
 http://stormy-castle-2941.herokuapp.com deployed to Heroku

To git@heroku.com:stormy-castle-2941.git
 8910bd7..bcf75de master -> master

本番環境での動作を確認

$ curl http://stormy-castle-2941.herokuapp.com/counter
counter is 1
$ curl http://stormy-castle-2941.herokuapp.com/counter
counter is 2

無事成功。

あとは、ローカルで開発し、heroku push&deploy するサイクルを繰り返せば良いだけ。

Advertisements
Tagged with:
Posted in middleware

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 6 months ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 6 months ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 6 months ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 1 year ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 1 year ago
%d bloggers like this: