
スキーム
flaskを使用してテストアプリケーションを実行できる小さなクラウドのセットアップを見てみましょう。
このクラウドは、次の要素で構成されています。
- Dockerでのコカインランタイム実行アプリケーション。
- アプリケーションイメージを保存するためのDockerレジストリ 。
- 分散アプリケーションストレージとしてのElliptics 、およびクラウド構成。
- コカイン実行時集約ノード -クライアントコカインコードの単一のクラウドエントリポイント。
- アプリケーションにアクセスするための代替方法としてのHTTPフロントエンド 。
各段階で、段階の成功をテストするためにチェックを行います。

ご覧のとおり、 Dockerをサポートするには、少なくとも3.8のカーネルを備えた5台の仮想マシンが必要です。 必要なパッケージはリポジトリにあります 。
リポジトリを追加する方法
次の内容で/etc/apt/sources.list.d/reverbrain.listを作成します。
キーを引き上げます。
どのコカイン関連パッケージが利用可能か見てみましょう:
deb http://repo.reverbrain.com/precise/ current/amd64/ deb http://repo.reverbrain.com/precise/ current/all/
キーを引き上げます。
curl -O http://repo.reverbrain.com/REVERBRAIN.GPG sudo apt-key add REVERBRAIN.GPG
どのコカイン関連パッケージが利用可能か見てみましょう:
apt-get update apt-cache search cocaine
Ellipticsで5分
1台のマシンからEllipticsのインストールを展開して、クラスターの動作を実証する方法を簡単に説明する必要があります。 すぐに、これはこの楕円を戦闘用に展開するためのガイドとはみなされないことに注意してください。 Ellipticsの開発に携わっている人は、間違いなくこれについてあなたに話すでしょう。 情報はドキュメントにも記載されています 。
一対のコマンドでは、次のようになります。
sudo apt-get install elliptics=2.24.14.31 elliptics-client=2.24.14.31 mkdir /tmp/history/ && mkdir /tmp/root cp /usr/share/doc/elliptics/examples/ioserv.conf ./tst_ioserv.conf
さらにtst_ioserv.confで、文字通り3行を変更する必要があります。 だから:
group = 1 addr = localhost:1025:2-0 192.168.50.201:1025:2-1 // IP indexes_shard_count = 16
その後、実行します:
dnet_ioserv -c tst_ioserv.conf

cocaine-runtime + Dockerの構成
アプリケーションのコードを直接実行するマシンの構成でミニクラウドの実装を始めましょう。 インストールのコアは、確かにcocaine-runtimeです。 Dockerを使用するには、 Docker自体とcocaine-pluginもインストールする必要があります。目標はドッカーコンテナでアプリケーションを実行することですが、通常のプロセスとしてアプリケーションを起動することも明確にします。
コンテナ化は良好です。 アプリケーションの環境問題を解決します。
- 中毒は常に私たちと一緒です。
- 2つのアプリケーションの依存関係に競合はありません。
- 開発環境、テスト環境、製品環境での環境の不変性。
コンテナなしで起動することは、依存関係がない(たとえば、実行中のアプリケーション)場合や、コンテナを使用する技術的な能力がある場合(たとえば、カーネルが必要なバージョンよりも低く、更新できない場合)に適用可能で便利です。
リポジトリを接続した後、必要なパッケージをインストールします。
sudo apt-get install cocaine-runtime libcocaine-core2 libcocaine-plugin-docker2 libcocaine-plugin-elliptics=2.24.14.31 elliptics-client=2.24.14.31

アプリケーションを管理するには、 cocaine-toolユーティリティが必要です。 それをインストールする最も簡単な方法は、標準のPythonパッケージリポジトリであるPyPIからです。
msgpackの Pythonにバインダーをインストールする必要があります。
sudo apt-get install msgpack-python
そして、 コカインツール 。
sudo pip install cocaine-tools
msgpack-pythonがPyPIからではないのはなぜですか?
Msgpack-pythonには2つの実装があります。 1つは純粋なPythonで、もう1つはCythonにあります。 PyPIからインストールする場合、バイナリバージョンのコンパイルが試行され、失敗した場合はクリーンな実装がインストールされます。 悪い点は、これらの実装が互いに互換性がないことです。 Cythonの標準バージョンを使用しました。 ほとんどの場合、必要な依存関係の一部が欠落しており、クリーンな実装がインストールされています。これは-バージョンによっては-理解できないエラーにつながります。 これは常に当てはまるわけではなく、おそらく状況は将来改善するでしょう。
公式ドキュメントの説明に従って、便利な方法で Dockerをインストールします。 次のパスが使用されます。
curl -s https://get.docker.io/ubuntu/ | sudo sh

パッケージが正常にインストールされると、 cocaine-runtimeはデフォルトの構成で開始されますが、これは変更する必要があります。
cocaine-runtimeを停止し、構成の変更に進みます。
sudo service cocaine-runtime stop
デフォルトの構成ファイルは/etc/cocaine/cocaine-default.confにあり、次のようになります。
{ "version": 2, "paths": { "plugins": "/usr/lib/cocaine", "runtime": "/var/run/cocaine" }, "services": { "logging": { "type": "logging" }, "storage": { "type": "storage", "args": { "backend": "core" } }, "node": { "type": "node", "args": { "runlist": "default" } } }, "storages": { "core": { "type": "files", "args": { "path": "/var/lib/cocaine" } }, "cache": { "type": "files", "args": { "path": "/var/cache/cocaine" } } }, "loggers": { "core": { "type": "syslog", "args": { "identity": "cocaine", "verbosity": "info" } } } }
クラウド構成を作成しましょう。 これを行うには、 2つのエンティティを構成する必要があります。
- 分散サービスでの作業を構成します(この例ではElliptics )。 問題は、 コカインランタイムが実行中のアプリケーション、アプリケーション起動プロファイル、アプリケーションマニフェストのリストをストレージから読み取ることです。 「そのまま」存在するファイルストレージを使用する場合、各ノードでこのデータの一貫性を維持する必要があり、これは非常に不便です。 分散保険の場合、この問題はそれ自体で解決されます。
- ランタイムに、クラウド自体の情報をクラウドの集約ノードに提供させます。
実験のために、提供されたデフォルト設定のコピー( /etc/cocaine/cocaine-cloud.confなど )を変更すると便利です。
servicesと同じネストレベルで構成にネットワークセクションを追加することで、 コカインランタイムに、 実行中のアプリケーションとサービスについて集約ノードに通知させることができます 。
"network" : { "group": "224.168.2.9" }, "services": { ... }
唯一のグループパラメータは、アラートが送信されるマルチキャストグループのアドレスを記述します。
ストレージは、 サービス/ストレージおよびストレージ/コアセクションを変更することで構成されます。
"storage": { "type": "elliptics" }, "storages" : { "core": { "type": "elliptics", "args": { "nodes" : { "192.168.50.201" : 1025 }, "io-thread-num" : 8, "wait-timeout" : 30, "check-timeout" : 60, "net-thread-num" : 8, "groups" : [1], "verbosity" : 2 } } }
Ellipticsストレージの実装は、対応するプラグインによって提供されます。 ちなみに、パッケージのすべてのプラグインは/ usr / lib / cocaineに配置されます。cocaine-runtimeはデフォルトでそれらを探します。
ここで、デフォルトでこの設定でコカインを強制的に開始します。 作成する
/etc/default/cocaine-runtime
:
CONFIG_PATH = "/etc/cocaine/cocaine-cloud.conf"
新しい設定でcocaine-runtimeを実行し、プロセスが機能していることを確認します。

ポート10053で開始した後、このノードのサービスロケーターは、アプリケーションの可用性の要求を待ちます。 これは、クラウドアプリケーションおよびサービス用の一種のDNSです。つまり、サービスまたはアプリケーションの名前によって、要求を処理するために要求を送信する場所がわかります。
cocaine-tool info
コマンドを使用して、このノード上のアプリケーションに関する情報を要求できます。 このコマンドの出力はまだ驚くべきものではありませんが、覚えておいてください-すぐに変更されます。
コカインランタイムとプラグインに加えて、 Dockerをインストールしたことを思い出してください。 また、正常に開始されたことを確認します。

同様のアクションが2番目のマシンで実行されると想定しています。 合計で、共有ストレージを調べるコカインランタイムを実行する2台の車があります-それは素晴らしいことです!
この時点で、アプリケーションを実行することはすでに可能です。 もちろん、これはまったくクラウドではありませんが、それでもです。 袖をまくりましょう、始めましょう。
まず、アプリケーションコードをコカインストレージに配信する必要があります。 このタスクは、 cocaine-toolを使用して簡単に解決できます 。
サンプルを使用してリポジトリのクローンを作成し、ディレクトリに移動します。
git clone git@github.com:cocaine/cocaine-framework-python.git -b v0.11 cd cocaine-framework-python/examples/flask/

アプリケーションコードに加えて、 manifest.jsonが次の場所にあることがわかります。
{ "slave": "main.py" }
このファイルの主なタスクは、実行するものをプラットフォームに伝えることです。 環境を渡すこともできます 。
プロセスとして実行するアプリケーションのコードをクラウドにダウンロードするには、次のコマンドを実行する必要があります。
cocaine-tool app upload --name example
cocaine-toolは 、アプリケーションをアーカイブにパックし、クラウドにアップロードします。 次に、ダウンロードしたアプリケーションのリストを確認します。

これがアプリケーションです! 主なものは、アプリケーションのインストールに必要なflaskのインストールを忘れないことです。 コンテナなしで実行することの欠点は次のとおりです。
sudo apt-get install python-flask
次に、アプリケーションに割り当てられるリソース、分離のタイプ、ワーカー数の管理などを構成する必要があります。 プロファイルはこの目的に役立ちます。 プロファイルは、複数のアプリケーションに関連付けることができます。
最も単純なプロファイルは空のJSON
{}
です。 この場合、デフォルト設定が使用されます。
利用可能なすべてのオプションの説明は、 説明にあります。 後でコンテナ内でアプリケーションを起動するときに、より興味深い例を検討します。
デフォルトのプロファイルに名前を付けて、クラウドストレージにアップロードします。 正しく起動したことを確認してください。

最後に、スイッチを引いてアプリケーションが起動するときが来ました:
cocaine-tool app start --name example --profile default

これで、
cocaine-tool info
コマンドの出力が変更されました。 このノードで実行されているアプリケーションとアプリケーションに関する統計が表示されます。
アプリケーションにメッセージを送信してみましょう。 このためには、このような小さなpythonスクリプトで十分です。
#!/usr/bin/env python from cocaine.services import Service app = Service("example") print(app.enqueue("write", "DATA").get()) print(app.enqueue("read", "DATA").get())
アプリケーションはまだ1つのノードでのみ実行されていますが、2番目のノードに移動して実行することもできます。 これで、 Dockerでアプリケーションのインフラストラクチャを構築し続けることができます。
Dockerレジストリ
Docker-registryは、アプリケーションイメージ(コンテナ)のプライベートリポジトリです。 詳細については、公式のdockerのドキュメントを参照してください 。
Docker-registryは、画像を保存するための多くのバックエンドをサポートしています。 品揃えは、ローカルファイルシステムに画像を記録することから始まり、 Ellipticsに画像を保存するまで拡張されます。
Docker-registryを実行する最も簡単な方法は、Dockerを使用することです。 これを行うには、 Docker (上記を参照)をインストールし、コマンドに目的のイメージを実行させる必要があります。
sudo docker run -p 5000:5000 registry
レジストリイメージは最初にリポジトリからロードされてキャッシュされ、次回はすぐに起動します。

起動すると、 Docker-registryはポート5000でリッスンします。 私たちは彼にpingを送ります
curl "http://192.168.50.4:5000/_ping"
これでセットアップは完了です。
コンテナでアプリケーションをビルドおよびデプロイします
コンテナの場合のアプリケーションの展開は、「非コンテナ」と大差ありません。 最も重要な違いは、イメージをビルドするにはDockerfileが必要なことです。 実際には、イメージの内部状態を形成するために実行する必要があるシェルコマンドのセットで構成されています。 その後、イメージがDocker-registryに注がれます。
さらに、コンテナを実行するDockerは、レジストリからイメージをロードできます。 Dockerfileの構文、使用可能なコマンドはこちらにあります。 Dockerfileの代わりに、アセンブリ中にコンテナ内で実行されるChefレシピまたはPuppetマニフェストを提供できます。
このアプリケーションのプロファイルでは、絶縁Dockerのタイプを指定する必要があります。 これを行うには、新しいプロファイルを作成します。
{ "queue-limit": 1000, "pool-limit": 10, "isolate": { "type": "docker", "args": { "memory_limit": 1000000000, "endpoint": "unix:///var/run/docker.sock", "registry": "registry.cloud.net:5000", "cpu_shares": 0 } }, "concurrency": 200 }
docker-profile.jsonという名前でファイルにプロファイルを配置し、docker-profileという名前でアップロードします
cocaine-tool profile upload --name docker-profile --profile=docker-profile.json
この例では、既製のDockerfileがあり、クラウドへのアプリケーションのダウンロードは次のとおりです。
sudo cocaine-tool app upload --docker=unix:///var/run/docker.sock --registry=registry.cloud.net:5000 --manifest manifest-docker.json --name example-docker --timeout 20000
これはインスタントプロセスではなく、すべて画像とネットワークのサイズに依存します。 しかし、その結果、同様の碑文が表示されるはずです。 次に、アプリケーションが起動します。

1つのポイントが見落とされています-どのアプリケーションが起動時にコカインランタイムを開始し、それをどのように見つけるかについて。 これにはランリストがあります。 本質的に、この連想配列のアプリケーションとそのプロファイルは、起動時にcocane-runtimeが読み取ります。 プロファイルのように、 ストレージに配置されます 。 クラウドの異なるノードで実行中のアプリケーションのセットは異なる場合があるため、それらの実行リストは異なる場合があります。 ランリストの名前は、ノードサービスのrunlistパラメーターのcocaine-runtime configで指定されます。
集約ノードの構成
本質的に、構成のこの部分は、「コカインランタイムの構成」項目に非常に似ています。 コカインランタイムは集約ノードとして機能するため、これは自然なことです。 その中のすべてのバランシング作業は、 ゲートウェイプラグインによって実行されます 。
このプラグインには2つの実装があります。 最初はアドホックと呼ばれます。 「すぐに使用可能」であり、追加のパッケージをインストールする必要はありません。 戦闘で使用する2番目の実装はipvsと呼ばれます。 名前が示すように、同じ名前のテクノロジーを使用します。 アドホックは、 ipvsを使用できない場合に使用するのが賢明です。 そしてもちろん、このプラグインの独自の実装を記述して、好みのテクノロジーを使用してバランスを取ることができます。
言葉から行為へ。 パッケージをインストールします。
sudo apt-get install cocaine-runtime libcocaine-core2 libcocaine-plugin-ipvs2 libcocaine-plugin-elliptics=2.24.14.31 elliptics-client=2.24.14.31

ipvsを使用できない場合は、指定されたパッケージの最後をインストールする必要はありません。 基本構成の違いはわずかであり、個別に示されます。
ネットワークセクションにゲートウェイサブセクションを追加すると、 ランタイムを集約ノードにすることができます 。 以前のように、デフォルトで設定のコピーを修正すると仮定します。 前の段落と同様にストレージサービスを構成します。すぐに必要になります。
"network": { "group": "224.168.2.9", "gateway": { "type": "ipvs" // adhoc } }, "services"...
sudo service cocane-runtime restart
と、プロセスが開始するはずです。
cocaine /usr/bin/cocaine-runtime --daemonize --configuration /etc/cocaine/cocaine-gateway.conf --pidfile /var/run/cocaine/runtime.pid
実際、 ゲートウェイは多数のパラメーターを受け入れます(これらのパラメーターについては資料で確認できます)。
ログを開きましょう(デフォルトではsyslogに書き込まれます)。 2つのノードの接続が登録され、そのうちの1つがオフになったことがわかります。 バックエンドでも同じことができ、 検出が機能することを確認できます。

コカインネイティブプロキシ
Cocaine-native-proxyを使用すると、HTTP経由でクラウドアプリケーションにアクセスできます。 インストールと設定は非常に簡単です。
apt-get install cocaine-native-proxy
次に、 ロケーターセクションで集約ノードのリストを指定する必要があります。 この場合、そのようなノードは1つだけです。 厳密に言えば、集約モードで動作しないロケーターとノードのアドレスを指定できます。 これは、そのようなノードが他のノード上のサービスやアプリケーションについて何も知らないという理由で悪いことです。つまり、それらにアクセスすることはできません。 パラメーターの詳細な説明は、 github.com / cocaine / cocaine-native-proxy / blob / master / README.mdにあります。
{ "endpoints": [ "0.0.0.0:8080" ], "backlog": 2048, "threads": 2, "application": { "locators": ["192.168.50.103:10053"], "service_pool": 5, "reconnect_timeout": 180, "request_timeout": 5 } }
インストールのクラウドエントリポイントは、集約ノードを持つマシンです。 HTTPインターフェースはcocaine-native-proxyを介して公開されているという事実にもかかわらず、実際には、このプロキシーは集約ノードも使用します。 ロケーターセクションの構成で指定しました。 2つの方法でアプリケーションを呼び出してみましょう。 HTTPクライアントはhttpイベントハンドラーを使用し、Pythonのクライアントコードから書き込みイベントと読み取りイベントを処理します。
クライアントコードは、クラウドエントリポイントのアドレスを示します。 私の場合-192.168.50.103。
#!/usr/bin/env python from cocaine.services import Service app = Service("example", host="192.168.50.103") print(app.enqueue("write", "DATA").get()) print(app.enqueue("read", "DATA").get())
フラスコアプリケーションは、httpイベントハンドラーとして呼び出されます。 現在、HTTPプロキシは、イベントを送信するアプリケーションを決定する2つの方法をサポートしています。 最初の方法は、渡されたURLがパターンに従って構築されていることを前提としています:
///tail?arg=1&args=2. URL . /tail?arg=1&args=2 . .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'

exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .

curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'

exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .

curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .
///tail?arg=1&args=2. URL . /tail?arg=1&args=2
. .
X-Cocaine-Service, X-Cocaine-Event . nginx .
, :
curl "http://localhost:8080/read" -H "X-Cocaine-Service: example" -H "X-Cocaine-Event: http" curl "http://localhost:8080/example/http/read"
. , . , . . . , , (, 5%). . . , , .
. example , exampleGroup . example 1000 . .
service/locator: adding group 'exampleGroup'
exampleGroup . , , app.py hello:
@app.route('/') def hello(name=None): return "HELLO! I'm version #2"
, example2 .
curl "http://localhost:8080/exampleGroup/http/"
, . example2 0 , HTTP-proxy . , HTTP-proxy . , .
, , . , Cocaine , c, . .