nginxソース分析のupstream設計
6406 ワード
nginxの神秘的な武器江湖については、そのレンダリングを止めたことがありません.間違いなくupstreamです.nginxには、高性能、高同時性、強い安定性など、多くの切り札があります.しかしupstreamがなければかなり色が落ちます.upstreamはnginxをエージェントサーバにし、fastcgiプロトコルのphpに接続することができ、memcached、redis、mongodb、mysql handlersocket、uwsgiプロトコルのサーバ、さらにはすべてのサーバに接続することができます.本文は一歩一歩その神秘的な色彩を明らかにする.
今、あなたの直感には、upstreamはnginxの神秘的なメカニズムであり、nginxがバックエンドのサーバに接続できるようにしています.バックエンドに何台のサーバがあるかにかかわらず、指定したポリシーに基づいて1台を選択し、接続し、要求データを送信し、バックエンドサーバの応答を得て、最後にクライアントに応答します.もしこの説明がupstreamがnginxのために何をしたかを明らかにすれば、私たちはその実現を深く探求します.想像以上に簡単になる心配はありません.
nginxでupstreamをどのように使用するかは、upstream backend{server backend 1.example.com weight=5;server backend 2.example.com:8080;server unix:/tmp/backend 3;server backup 1.example.com:8080 backup;server backup 2.example.com:8080 backup;server { location/{ proxy_pass http://backend; } }
nginxのライフサイクルには、解析構成、起動プロセス、処理要求の3つの重要なプロセスがあります.この3段階をめぐってupstreamがどのように実現されるかを分析する.
1、解析構成:
nginxには複数のupstreamがあり、各upstreamには上のupstreamのような独自の名前があります.各upstreamは、指定した複数のサーバ情報に対応します.サーバはドメイン名、ip、unixであってもよい.最終的にはsocket操作可能なip:portとして解析されるので、ドメイン名であればgetservernameでより多くのサーバ情報に変換されます.そしてproxy_passは、nginxがリクエストを処理するときにusptream内のサーバを見つけるために、特定のupstreamにバインドされます.ここにはproxy_passの値はupstream nameではありません.upstreamの値を作成し、バインドします.これはfastcgi,memcachedなどupstreamを使用する他のモジュールにも適用されます.
構造体は次のとおりです.
upstreams = {}; server_infos = []; upstreams[upstream_name] = server_infos; server_infos = [server1, server2, ...];
umcf->upstreams = [ngx_http_upstream_srv_conf_t*, ngx_http_upstream_srv_conf_t*, ...];
plcf->upstream = ngx_http_upstream_conf_t;
plcf->upstream.upstream = ngx_http_upstream_srv_conf_t*;
plcf->upstream.upstream.servers = [ngx_http_upstream_server_t*, ngx_http_upstream_server_t*, ...];
plcf->upstream.upstream.servers[i].addrs = [ngx_addr_t*, ngx_addr_t*, ...];
init_main発生後:
plcf->upstream.upstream.peer.init = ngx_http_upstream_init_round_robin_peer;
plcf->upstream.upstream.peer.data = [ngx_http_upstream_rr_peer_t*, ngx_http_upstream_rr_peer_t*, ...];
賢いあなたは、nginxが要求を処理するときに、どのように具体的なサーバーを見つけるかがpeerのinitとdataに基づいて計算されることを予見することができます.
2、プロセスの開始
ほっとして、upstreamはnginxの起動プロセスの段階で、何も起こらなかった.
3、処理要求
要求を処理するには、あるサーバを見つけて、指定したプロトコルに基づいて要求を送信し、応答を受信して解析し、最後にクライアントに応答します.
upstreamはどのようにして指定されたサーバーを見つけたのですか?
nginxには構造体ngx_がありますhttp_request_t:対応するのはリクエストです
解析構成段階の最後にnginxはpeerのinitとdataの処理に基づいて計算される.requestにupstream、upstreamにpeer、peerのsocketaddr、socketlenに値があるようにして、nginxは具体的なサーバーに接続できるようにしましょう.
もともとこれに対して大きな幅を書きたいと思っていましたが、ソースコードを読む楽しみは細部を体得することで、書くのはずっと流れを整理するだけで、これらの構造体を除いて、他はすべてこの考え方に基づいて書いて、間違いを避けられないかもしれません.
3、upstreamには何がありますか.
upstreamはhttpの半分を占めていると言えます.タイマ、タイムアウト処理、リクエスト処理、リクエストの構築方法、レスポンスの解析方法、長接続、ポリシーなど.どの小さなテーマがもっと深く知りたいのか、読書量を見てから深く考えてみましょう.
nginxはhttpサーバだけでなくmailエージェントサーバ、streamエージェントサーバでもあります.はい、1.9バージョンのnginxはstream(tcp)をサポートし始めました.しかしhttpとstreamはupstreamをサポートしていますが、mailはサポートしていません.
nginxはwebsocketサーバ,rtmpサーバにも処理できる.upstreamの機能がhttp、streamから独立すれば、非常に優れた再構築になります.
4、私が書きたいことは興味があるかもしれません.
nginxのsubrequestは非常に不思議なメカニズムで、私が書いたnginxダイナミックエージェントなど、クールなことをすることができます.これはあなたの興味を引き起こすのではないでしょうか.モジュール、ソースコード、nginxのメッセージなど、興味のあることを教えてください.nginxはjavascritをサポートし、Igor Sysoev大神は自分の軽量級js仮想マシンを実現します.luaのソースコードがどのように実現するかに興味があれば、これを書いてみてください.^-^
本文は終わります!原文を読む:http://nglua.com/reads/5.html
今、あなたの直感には、upstreamはnginxの神秘的なメカニズムであり、nginxがバックエンドのサーバに接続できるようにしています.バックエンドに何台のサーバがあるかにかかわらず、指定したポリシーに基づいて1台を選択し、接続し、要求データを送信し、バックエンドサーバの応答を得て、最後にクライアントに応答します.もしこの説明がupstreamがnginxのために何をしたかを明らかにすれば、私たちはその実現を深く探求します.想像以上に簡単になる心配はありません.
nginxでupstreamをどのように使用するかは、upstream backend{server backend 1.example.com weight=5;server backend 2.example.com:8080;server unix:/tmp/backend 3;server backup 1.example.com:8080 backup;server backup 2.example.com:8080 backup;server { location/{ proxy_pass http://backend; } }
nginxのライフサイクルには、解析構成、起動プロセス、処理要求の3つの重要なプロセスがあります.この3段階をめぐってupstreamがどのように実現されるかを分析する.
1、解析構成:
nginxには複数のupstreamがあり、各upstreamには上のupstreamのような独自の名前があります.各upstreamは、指定した複数のサーバ情報に対応します.サーバはドメイン名、ip、unixであってもよい.最終的にはsocket操作可能なip:portとして解析されるので、ドメイン名であればgetservernameでより多くのサーバ情報に変換されます.そしてproxy_passは、nginxがリクエストを処理するときにusptream内のサーバを見つけるために、特定のupstreamにバインドされます.ここにはproxy_passの値はupstream nameではありません.upstreamの値を作成し、バインドします.これはfastcgi,memcachedなどupstreamを使用する他のモジュールにも適用されます.
構造体は次のとおりです.
typedef struct {
ngx_http_upstream_conf_t upstream;
...
} ngx_http_proxy_loc_conf_t;
typedef struct {
ngx_http_upstream_srv_conf_t *upstream;
ngx_msec_t connect_timeout;
ngx_msec_t send_timeout;
ngx_msec_t read_timeout;
ngx_msec_t timeout;
ngx_msec_t next_upstream_timeout;
size_t send_lowat;
...
} ngx_http_upstream_conf_t;
struct ngx_http_upstream_srv_conf_s {
ngx_http_upstream_peer_t peer;
void **srv_conf;
ngx_array_t *servers; /* ngx_http_upstream_server_t */
ngx_uint_t flags;
ngx_str_t host;
u_char *file_name;
ngx_uint_t line;
in_port_t port;
in_port_t default_port;
ngx_uint_t no_port; /* unsigned no_port:1 */
};
typedef struct {
ngx_str_t name;
ngx_addr_t *addrs;
ngx_uint_t naddrs;
ngx_uint_t weight;
ngx_uint_t max_fails;
time_t fail_timeout;
unsigned down:1;
unsigned backup:1;
} ngx_http_upstream_server_t;
typedef struct {
ngx_http_upstream_init_pt init_upstream;
ngx_http_upstream_init_peer_pt init;
void *data;
} ngx_http_upstream_peer_t;
struct ngx_http_upstream_rr_peer_s {
struct sockaddr *sockaddr;
socklen_t socklen;
ngx_str_t name;
ngx_str_t server;
ngx_int_t current_weight;
ngx_int_t effective_weight;
ngx_int_t weight;
ngx_uint_t conns;
};
upstreams = {}; server_infos = []; upstreams[upstream_name] = server_infos; server_infos = [server1, server2, ...];
umcf->upstreams = [ngx_http_upstream_srv_conf_t*, ngx_http_upstream_srv_conf_t*, ...];
plcf->upstream = ngx_http_upstream_conf_t;
plcf->upstream.upstream = ngx_http_upstream_srv_conf_t*;
plcf->upstream.upstream.servers = [ngx_http_upstream_server_t*, ngx_http_upstream_server_t*, ...];
plcf->upstream.upstream.servers[i].addrs = [ngx_addr_t*, ngx_addr_t*, ...];
init_main発生後:
plcf->upstream.upstream.peer.init = ngx_http_upstream_init_round_robin_peer;
plcf->upstream.upstream.peer.data = [ngx_http_upstream_rr_peer_t*, ngx_http_upstream_rr_peer_t*, ...];
賢いあなたは、nginxが要求を処理するときに、どのように具体的なサーバーを見つけるかがpeerのinitとdataに基づいて計算されることを予見することができます.
2、プロセスの開始
ほっとして、upstreamはnginxの起動プロセスの段階で、何も起こらなかった.
3、処理要求
要求を処理するには、あるサーバを見つけて、指定したプロトコルに基づいて要求を送信し、応答を受信して解析し、最後にクライアントに応答します.
upstreamはどのようにして指定されたサーバーを見つけたのですか?
nginxには構造体ngx_がありますhttp_request_t:対応するのはリクエストです
struct ngx_http_request_s {
uint32_t signature; /* "HTTP" */
ngx_connection_t *connection;
...
ngx_http_upstream_t *upstream;
ngx_array_t *upstream_states;
/* of ngx_http_upstream_state_t */
...
};
struct ngx_http_upstream_s {
...
ngx_peer_connection_t peer;
...
};
struct ngx_peer_connection_s {
ngx_connection_t *connection;
struct sockaddr *sockaddr;
socklen_t socklen;
ngx_str_t *name;
ngx_uint_t tries;
ngx_msec_t start_time;
ngx_event_get_peer_pt get;
ngx_event_free_peer_pt free;
void *data;
};
解析構成段階の最後にnginxはpeerのinitとdataの処理に基づいて計算される.requestにupstream、upstreamにpeer、peerのsocketaddr、socketlenに値があるようにして、nginxは具体的なサーバーに接続できるようにしましょう.
もともとこれに対して大きな幅を書きたいと思っていましたが、ソースコードを読む楽しみは細部を体得することで、書くのはずっと流れを整理するだけで、これらの構造体を除いて、他はすべてこの考え方に基づいて書いて、間違いを避けられないかもしれません.
3、upstreamには何がありますか.
upstreamはhttpの半分を占めていると言えます.タイマ、タイムアウト処理、リクエスト処理、リクエストの構築方法、レスポンスの解析方法、長接続、ポリシーなど.どの小さなテーマがもっと深く知りたいのか、読書量を見てから深く考えてみましょう.
nginxはhttpサーバだけでなくmailエージェントサーバ、streamエージェントサーバでもあります.はい、1.9バージョンのnginxはstream(tcp)をサポートし始めました.しかしhttpとstreamはupstreamをサポートしていますが、mailはサポートしていません.
nginxはwebsocketサーバ,rtmpサーバにも処理できる.upstreamの機能がhttp、streamから独立すれば、非常に優れた再構築になります.
4、私が書きたいことは興味があるかもしれません.
nginxのsubrequestは非常に不思議なメカニズムで、私が書いたnginxダイナミックエージェントなど、クールなことをすることができます.これはあなたの興味を引き起こすのではないでしょうか.モジュール、ソースコード、nginxのメッセージなど、興味のあることを教えてください.nginxはjavascritをサポートし、Igor Sysoev大神は自分の軽量級js仮想マシンを実現します.luaのソースコードがどのように実現するかに興味があれば、これを書いてみてください.^-^
本文は終わります!原文を読む:http://nglua.com/reads/5.html