新規プロトコルプラグイン

新規プロトコルプラグインは Traffic Server を任意のプロトコルのウェブプロキシーに拡張することを可能にします。この章では新規プロトコル API と新規プロトコルをサポートするプラグインについて説明します。また非常にシンプルな模造の HTTP ライクなプロトコルをサポートするサンプルプロトコルプラグインのコードの詳細なレビューも示します。

サンプルプロトコルについて

サンプルプロトコルはクライアントがサーバーにファイルを問い合わせることを可能にします。クライアントは特定の Traffic Server ポート( plugin.config で指定される)にリクエストを送信します。各リクエストは下記の構造を持ちます。

server_name file_name

Using the Protocol plugin, Traffic Server can accept these requests, parse them, and act as a proxy cache (i.e., request the file from the origin server on the client's behalf and store copies of response messages in cache). The Protocol plugin is a state machine that flows through the states illustrated in the Sample Protocol State Diagram. This figure illustrates the steps that Traffic Server and the Protocol plugin go through in order to support the sample protocol.

より具体的には、 Traffic Server とプロトコルプラグインは下記の処理をする必要があります。:

  • クライアントコネクションの listen と accept を行う。(サーバーポートは plugin.config で指定される)

  • やってきたクライアントリクエストを読込む

  • リクエストされたコンテンツを、 Traffic Server キャッシュ内でルックアップする

  • リクエストがキャッシュヒットした場合、キャッシュからコンテンツを配信する。(このシンプルな例では新鮮さのチェックを行わない)

  • リクエストがキャッシュミスした場合、オリジンサーバーとのコネクションを開く。(サーバーポートは plugin.config で指定される)

  • オリジンサーバーへリクエストを転送する。

  • オリジンサーバーのレスポンスを受け取る。

  • レスポンスをキャッシュし、クライアントに送信する。

Sample Protocol State Diagram

サンプルプロトコルの状態遷移図

サンプルプロトコルの状態遷移図

プロトコルプラグインの構造

To see how the Protocol plugin works, you need to understand some broader concepts. This section assumes you're familiar with the concepts of continuation, Traffic Server's asynchronous event model, and basic Traffic Server plugin structure. If you are not familiar with these concepts, then you may want to begin with the はじめに section.

プロトコルプラグインにおける継続

The Protocol plugin creates a static continuation that is an "accept" state machine - that is, a state machine whose job is to accept client connections on the appropriate port. When Traffic Server accepts a net connection from a client on that port, the accept state machine is activated. It then creates a new continuation: a transaction state machine. The accept state machine creates one transaction state machine for each transaction (where a transaction consists of a client request and Traffic Server's response). Each transaction state machine lives until the transaction completes; then it is destroyed. If the client's request for content is a cache miss, then a transaction state machine might need to open a connection to the origin server. This is illustrated in the Protocol Plugin Overview diagram below.

プロトコルプラグイン概要

プロトコルプラグイン概要

プロトコルプラグイン概要

プロトコルプラグインの記述の最初のステップは明確です。 TSPluginInit で、 plugin.config で指定されたクライアントポートでネットコネクションを listen する継続を生成しなければなりません。(この継続は accept ステートマシンです)

下記はプロトコルプラグインの為に実装される継続の概要です:

  • クライアントコネクションを listen し、 Traffic Server が新しいクライアントコネクションを accept する度にトランザクションステートマシンを生成する accept ステートマシン 。 accept ステートマシンは Traffic Server が動作している限り残ります。

  • クライアントリクエストを読込み、処理し、トランザクションが終了した際に破棄される トランザクションステートマシン

イベントフロー

プロトコルプラグインの残りの実装には、トランザクションの過程の中のイベントのフローの理解が求められます。 HTTP トランザクションプラグインとは異なり、このプラグインはネットワークコネクションからデータを読込み、 Traffic Server キャッシュへデータを読込み/書込みしなければなりません。これは、その継続は HTTP ステートマシンのイベントを受け取らず、 Traffic Server のプロセッサーサブシステムからイベントを受け取ることを意味します。例えば accept ステートマシンは、Traffic Server のネットプロセッサーからのイベント TS_EVENT_NET_ACCEPT によって始動します。 accept ステートマシンのハンドラー関数はそのため、このイベントを処理できなければなりません。

トランザクションステートマシンはクライアントコネクションがやって来たリクエストデータを受信した際に始動します。 ネットプロセッサー はやって来たデータのトランザクションステートマシンに通知します。トランザクションステートマシンはそのデータを読込み、それが終了した際にリクエストされたファイルのキャッシュルックアップを開始します。キャッシュルックアップが完了した際、トランザクションステートマシンは Traffic Server の キャッシュプロセッサー によって始動します。

トランザクションステートマシンがコンテンツを取得するためオリジンサーバーへのコネクションを開く必要がある場合(キャッシュミスした場合)、トランザクションステートマシンはサーバー名の DNS ルックアップを開始します。トランザクションステートマシンは Traffic Server の ホストデータベースプロセッサー からの DNS ルックアップイベントによって始動します。トランザクションがオリジンサーバーへ接続しなければならない場合、トランザクションステートマシンはネットコネクションを開始し、ネットプロセッサーからのイベントを待ちます。

プロトコルプラグインのイベントのフロー

プロトコルプラグインのイベントのフロー

プロトコルプラグインのイベントのフロー

The flow of events is illustrated in the Protocol Plugin Flow of Events diagram above. The thin straight lines show Net Processor event flow, the thin dashed lines represent Host Database event flow, and the thick dashed lines show Cache event flow.

Notice that this flow of events is independent of the Protocol plugin's design (i.e., whether you build accept or transaction state machines). Any plugin that supports network connections uses the net vconnection interfaces (TSNetAccept(), TSNetConnect()) and thus receives events from the Net Processor. Any plugin that performs cache lookups or cache writes uses TSCacheRead(), TSCacheWrite(), TSVConnRead(), and TSVConnWrite() and thus receives events from the Cache Processor and Traffic Server event system. Similarly, any plugin that does DNS lookups receives events from the Host Database Processor.

トランザクションステートマシンを実装する方法の一つ

プロトコルプラグインの トランザクションステートマシンTSM )は下記のようにする必要があります。

  • トランザクションの状態を追跡し続ける

  • (トランザクションの状態と受け取ったイベントに基づき)受け取ったイベントを処理する

  • 変更があったらトランザクションの状態を更新する

以下は TSM を実装できる方法の一つです。プロトコルプラグインがこれをどう行っているかの詳細は次の節で説明します。

  • 追跡し続ける必要のある全ての状態データを含む、トランザクションのデータ構造を作成する。サンプルのプロトコルプラグインにおいてこれは Txn_SM 構造体。

  • TSM の継続を作成する際、Txn_SM 型のデータを初期化する。データをトランザクションの初期状態に初期化する。(この場合、ネットコネクションはちょうど accept されている)このデータを TSContDataSet を使って TSM 継続に関連付ける。

  • 状態ごとに予想されるイベントを処理する、状態ハンドラー関数を記述する。

  • TSM のハンドラーを記述する。そのジョブはイベントを受け取る、現在の状態を検査する、そして適切な状態ハンドラー関数を実行する。プロトコルプラグインにおいて、そのハンドラーは main_handler である。 main_handler は各状態を処理するために状態ハンドラー関数を呼び出す。

The steps below describe the flow of execution illustrated in "How Transaction State Machines are Implemented in the Protocol Plugin".

  1. The handler for the TSM, (called main_handler in the Protocol plugin) receives events from the TSM.

  2. main_handler examines the state of the transaction-in particular, it examines the current handler.

  3. main_handler calls the current_handler (which is one of the state handler functions), and then passes the current event to current_handler. In the image below below, the current handler is called state2_handler.

  4. The current_handler handles the event and updates the data. In the image below below, the state is changed from state2 to state3 (and the current handler is changed from state2_handler to state3_handler). The next time main_handler receives an event, it will be processed by state3_handler.

  5. state2_handler arranges the next callback of the TSM. Typically, it gives Traffic Server additional work to do (such as writing a file to cache) so that it can progress to the next state. The TSM (main_handler) then waits for the next event to arrive from Traffic Server.

How Transaction State Machines are Implemented in the Protocol Plugin

プロトコルプラグインにおいてトランザクションステートマシンがどのように実装されるか

プロトコルプラグインにおいてトランザクションステートマシンがどのように実装されるか

典型的なトランザクションの処理

コードは下記のファイルに含まれます。:

  • Protocol.cc and Protocol.h

  • TxnSM.cc and TxnSM.h

下記は典型的なトランザクションを処理するコードの、段階的なウォークスルーです。

  1. The TSPluginInit() function is in the Protocol.cc file. It checks the validity of the plugin.config entries (there must be two: a client accept port and a server port) and runs an initialization routine, init.

  2. The init function (in Protocol.cc) creates the plugin's log file using TSTextLogObjectCreate().

  3. The init function creates the accept state machine using AcceptCreate. The code for AcceptCreate is in the Accept.cc file.

  4. The init function arranges the callback of the accept state machine when there is a network connection by using TSNetAccept().

  5. The handler for the accept state machine is accept_handler in the Protocol.cc file. When Traffic Server's Net Processor sends TS_EVENT_NET_ACCEPT to the accept state machine, accept_handler creates a transaction state machine (txn_sm) by calling TxnSMCreate. Notice that accept_event creates a mutex for the transaction state machine, since each transaction state machine has its own mutex.

  6. The TxnSMCreate function is in the TxnSM.cc file. The first thing it does is initialize the transaction's data, which is of type TxnSM (as defined in TxnSM.h). Notice that the current handler (q_current_handler) is set to state_start.

  7. TxnSMCreate then creates a transaction state machine using :c:func`TSContCreate`. The handler for the transaction state machine is main_handler, which is in the TxnSM.cc file.

  8. When accept_event receives TS_EVENT_NET_ACCEPT, it calls the transaction state machine ( TSContCall (txn_sm, 0, nullptr); ). The event passed to main_handler is 0 (TS_EVENT_NONE).

  9. The first thing main_handler does is examine the current txn_sm state by calling TSContDataGet(). The state is state_start.

  10. main_handler then invokes the handler for state_start by using the function pointer TxnSMHandler (as defined in TxnSM.h).

  11. The state_start handler function (in the TxnSM.cc file) is handed an event (at this stage, the event is TS_EVENT_NET_ACCEPT) and a client vconnection. state_start checks to see if this client vconnection is closed; if it is not, then state_start attempts to read data from the client vconnection into an TSIOBuffer (state_start is handling the event it receives).

  12. state_start changes the current handler to state_interface_with_client (that is, it updates the state of the transaction to the next state).

  13. state_start initiates a read of the client vconnection (arranges for Traffic Server to send TS_EVENT_VCONN_READ_READY events to the TSM) by calling TSVConnRead().

  14. state_interface_with_client is activated by the next event from Traffic Server. It checks for errors and examines the read VIO for the read operation initiated by TSVConnRead().

  15. If the read VIO is the client_read_VIO (which we are expecting at this stage in the transaction), then state_interface_with_client updates the state to state_read_request_from_client .

  16. state_read_request_from_client handles actual TS_EVENT_VCONN_READ_READY events and reads the client request.

  17. state_read_request_from_client parses the client request.

  18. state_read_request_from_client updates the current state to the next state, state_handle_cache_lookup .

  19. state_read_request_from_client arranges for Traffic Server to call back the TSM with the next set of events (initiating the cache lookup) by calling TSCacheRead().

  20. When the TSCacheRead() sends the TSM either TS_EVENT_CACHE_OPEN_READ (a cache hit) or TS_EVENT_CACHE_OPEN_READ_FAILED (a cache miss), main_handler calls state_handle_cache_lookup.