HostedRedmine.com has moved to the Planio platform. All logins and passwords remained the same. All users will be able to login and use Redmine just as before. *Read more...*
A little more about Router V2¶
Routerとの違いを記述。
Routerの位置付け¶
変更なし。
- 実際の構成
参考: Cloud Foundry Open Tour - London
Routerの仕事¶
(変更なし)
- urlへのアクセスをアプリケーション・インスタンス(ホスト:ポート)に振り分ける
- アプリケーション・インスタンスからのレスポンスをクライアントに返す
URLへのアクセスをアプリケーション・インスタンス(droplet)に振り分ける¶
- 上の図を少し詳細化
- ◎基本的な仕組み (大幅に変更)
- RouterULSServer1が起動される
- クライアントから接続があると, luaのスクリプトが実行される
参考: nginx はどのようにリクエストを処理するか , nginx連載5回目: nginxの設定、その3 - locationディレクティブ - インフラエンジニアway , Module ngx_http_core_module- RouterULSServerの'/'に対してsubrequestが発行される
- RouterULSServerがURL(とcookie)に対応するdropletのホストとポートを(含む情報を)返す
- 該dropletに対してsubrequestが発行される
- (該subrequestのresponseを処理して返す)
- RouterULSServerの'/'に対してsubrequestが発行される
- ◎そのためにしていること (ほとんど変更なし)
- URLとdropletsのmapの管理
RouterULSServerが起動される¶
- router/lib/router.rb#L119-122
Router.server = Thin::Server.new(inet, port, RouterULSServer, :signals => false) if inet && port Router.local_server = Thin::Server.new(fn, RouterULSServer, :signals => false) if fn Router.server.start if Router.server Router.local_server.start if Router.local_server
- 参考: 以前の版 (V1とする)
違いは,以下の2点Router.server = EM.start_server(inet, port, ClientConnection, false) if inet && port Router.local_server = EM.start_server(fn, nil, ClientConnection, true) if fn
- サーバーをEventMachineを利用して起動するのではなく,Thin::Serverを作って起動している点
- サーバー上で動作するクラス(モジュール)がClientConnectionからRouterULSServerに変更されている点
クライアントから接続があると, luaのスクリプトが実行される¶
- nginx.conf#L63-149 [2]
location / { .. access_by_lua ' ..
L63-149にはaccess_by_lua
が2か所あるが,ここで扱うのは後( L119-147 )の方
前( L80-98 )の方は,routerのstatus情報取得URLへのアクセスを扱うものなので,ここでは対象外とする- RouterULSServerの'/'に対してsubrequestが発行される
このsubrequestは,見かけ上'/vcapuls'に対して発行されているが,local res = ngx.location.capture( "/vcapuls", { body = req } )
↓
実際はinternalなlocationとして 以下の定義 がなされているため,unix socket で待ち受けているRouterULSServerの'/'へのアクセスとなる
[3]location = /vcapuls { internal; .. proxy_pass http://unix:/tmp/router.sock:/; }
- RouterULSServerがURL(とcookie)に対応するdropletのホストとポートを(含む情報を)返す
router/lib/router_uls_server.rb#L10-60:https://github.com/cloudfoundry/vcap/blob/a519ef2415a3f6acf899d6081635c7d3c8a0304e/router/lib/router/router_uls_server.rb#L10 で定義されている- まずrequestからURLとcookieを取りだす
router/lib/router_uls_server.rb#L16body = request.body.read
router/lib/router_uls_server.rb#L20-25uls_req = JSON.parse(body, :symbolize_keys => true) raise ParserError if uls_req.nil? || !uls_req.is_a?(Hash) stats, url = uls_req[ULS_STATS_UPDATE], uls_req[ULS_HOST_QUERY] sticky = uls_req[ULS_STICKY_SESSION]
- URLからdropletを選択する
router/lib/router/router_uls_server.rb#L30-41unless droplets = Router.lookup_droplet(url) Router.log.debug "No droplet registered for #{url}" raise Sinatra::NotFound end # Pick a droplet based on original backend addr or pick a droplet randomly if sticky _, host, port = Router.decrypt_session_cookie(sticky) droplet = check_original_droplet(droplets, host, port) end droplet ||= droplets[rand*droplets.size]
- responseにdropletのhost:portを入れて返す
uls_response = { ULS_STICKY_SESSION => new_sticky, ULS_BACKEND_ADDR => "#{droplet[:host]}:#{droplet[:port]}", ULS_REQUEST_TAGS => uls_req_tags, ULS_ROUTER_IP => Router.inet } end uls_response.to_json end
- まずrequestからURLとcookieを取りだす
- RouterULSServerがURL(とcookie)に対応するdropletのホストとポートを(含む情報を)返す
- 該dropletに対してsubrequestが発行される (ここはluaではなく,単にnginxの設定)
nginx.conf#L137proxy_pass http://$backend_addr;
- (該subrequestのresponseを処理して返す)
nginx.conf#L139-147# Handling response from backend servers header_filter_by_lua ' -- add package.path and package.cpath package.path = package.path..";<%= node[:lua][:module_path] %>/?.lua" package.cpath = package.cpath..";<%= node[:lua][:module_path] %>/?.so" local uls = require ("uls") uls.post_process_response(ngx) ';
- RouterULSServerの'/'に対してsubrequestが発行される
urlとdropletsのmapの管理¶
- データ構造: Router@droplets
⇔特に変更なし(参考: V1 ) - 登録: Router#register_droplet
⇔大きな変更なし(参考: V1 ) - 削除: Router#unregister_droplet
⇔変更なし(参考: V1 ) - (定期的な)チェック: Router#check_registered_ulrs
⇔変更なし(参考: V1 )
---- - NATS listener の登録: Router#setup_listeners
⇔変更なし(参考: V1 ) - 定期チェックの登録: Router#setup_sweeper 内
⇔大きな変更なし(参考: V1 )EM.add_periodic_timer(CHECK_SWEEPER) { check_registered_urls log_connection_stats }
EM.add_periodic_timer(CHECK_SWEEPER) { check_registered_urls }
1 ちなみに'ULS'は'Upstream Location Server'の略のようだが( 根拠 ),その場合'RouterULSServer'は'Server'がダブっていることになる。上記 Open Tour London での表記は'Upstream Locator Svc'と若干異なっている。
2 このファイルは, router/
の下ではなく,リポジトリーでは vcap/dev_setup/cookbooks/nginx/templates/default/
に置かれる。理由は理解できるが,探しにくかったのもまた事実。
3 ここで交換されるデータ構造については,router/ext/nginx/uls.lua#L37-72 のコメントに記述がある。