HTTPS コネクション時の libcurl による連続GET にて HTTPS への GET リクエストを行う際、curl ハンドラを初期化せずに利用した方が高速にダウンロードされると言う例題を記載しましたが、別のスレッドでタイミングがバラバラに GET したい場合、排他処理にて安全性を確保するための例題です。
libcurl 自体はスレッドセーフ化されているので、curl_easy_init にて毎回ハンドラを初期化し利用すれば何の問題もなく別のスレッドで GET リクエストを行えますが、同じハンドラを使いまわしたい場合には同じタイミングで同じハンドラが利用されないように排他処理を行っておく必要があります(今回のような特別な用途でないかぎりは全く必要のない例題です)。
pthread_mutex_lock にて排他処理を行っているので、GET リクエストが並列化されるわけではないので並列化による恩恵は受けれませんが、HTTPS への要求時における証明書の取得などの内部処理を毎回行わずに済むなどの恩恵が大きい場合に利用します(例題のweb.fc2.comはその恩恵が得られないサイトで、証明書が正しくない場合に起こるようです、別のサーバーにてお試しください)。
実行結果
2017年9月2日土曜日
2017年8月11日金曜日
HTTPS コネクション時の libcurl による連続GETリクエストの高速化の検討
HTTPS コネクション時の libcurl による連続GETリクエストを高速化するための検証用の例題です。
libcurl による GET 取得時の高速化手段として以下のサイトでまとめられています。
https://moz.com/devblog/high-performance-libcurl-tips
(c-ares/PowerDNS 等により DNSのリスポンスを良くするとか libcurl-multi による並列処理化等、上記サイトには書かれていませんが TCP FAST OPEN に対応しているサーバーであれば libcurl からオプションを指定して利用できます)
一方、HTTPS でのリクエストでは証明書の検証等で、単純なデータやり取り以外の部分で内部的に処理が食われてしまうことがあります。
下記の例題では HTTPS にてデータ取得を行うサイトが信頼のあるサイトであることを前提とし、証明書の検証を行っていません。
例題では以下の3つの手法にてサイトからのデータ取得をループし、取得時間を計測しています。
TCP FAST OPEN(CURLOPT_TCP_FASTOPEN)の影響があるかどうかどうかを見てみましたが、特に影響はありませんでした。
HTTPS 接続が正常に機能しているサイトではほぼ 3 の設定で高速化される印象ですが、ブラウザ接続した際に「信頼できる運営者情報はありません」等のアラートが出るサイトでは全く変化はありませんでした(証明書の検証を行っていないにも関わらず)。
新しいサーバーでテストする際等には証明書を正しく入れてもらうようにお願いするしかない状況です(libcurl の設定では対処できない)。
今回テストしたのはサーバーからの応答を取得後に別の応答を取得する必要がある場合の処理です。
URLが異なる複数の結果を予め取得しておく場合には libcurl-multi や CURL ハンドラを複数準備して別スレッドで並行して結果を取得すれば容易に高速化することは可能かと思います(スレッドで用いる場合は CURLOPT_NOSIGNAL を指定)。 実行結果
libcurl による GET 取得時の高速化手段として以下のサイトでまとめられています。
https://moz.com/devblog/high-performance-libcurl-tips
(c-ares/PowerDNS 等により DNSのリスポンスを良くするとか libcurl-multi による並列処理化等、上記サイトには書かれていませんが TCP FAST OPEN に対応しているサーバーであれば libcurl からオプションを指定して利用できます)
一方、HTTPS でのリクエストでは証明書の検証等で、単純なデータやり取り以外の部分で内部的に処理が食われてしまうことがあります。
下記の例題では HTTPS にてデータ取得を行うサイトが信頼のあるサイトであることを前提とし、証明書の検証を行っていません。
例題では以下の3つの手法にてサイトからのデータ取得をループし、取得時間を計測しています。
CURL_RequestText1:毎回CURLハンドラを初期化し、データ取得を行う例結果では、1/2 はサイトにより多少の変化はあるもののあまり差はなく(2の方が若干早い印象)、3 は 1 の半分程度の時間でデータ取得が行われています(この例題では記載していませんが、POST 時の応答も高速化されていました)。
CURL_RequestText2:毎回CURLハンドラを初期化し、内部的に確保されているコネクションの再利用等は行わずデータ取得を行う例(CURLOPT_FORBID_REUSE/CURLOPT_FRESH_CONNECT)
CURL_RequestText3:CURLハンドラを予め準備しておき、繰り返し利用する間は再利用する例
TCP FAST OPEN(CURLOPT_TCP_FASTOPEN)の影響があるかどうかどうかを見てみましたが、特に影響はありませんでした。
HTTPS 接続が正常に機能しているサイトではほぼ 3 の設定で高速化される印象ですが、ブラウザ接続した際に「信頼できる運営者情報はありません」等のアラートが出るサイトでは全く変化はありませんでした(証明書の検証を行っていないにも関わらず)。
新しいサーバーでテストする際等には証明書を正しく入れてもらうようにお願いするしかない状況です(libcurl の設定では対処できない)。
今回テストしたのはサーバーからの応答を取得後に別の応答を取得する必要がある場合の処理です。
URLが異なる複数の結果を予め取得しておく場合には libcurl-multi や CURL ハンドラを複数準備して別スレッドで並行して結果を取得すれば容易に高速化することは可能かと思います(スレッドで用いる場合は CURLOPT_NOSIGNAL を指定)。 実行結果
2017年6月20日火曜日
CGI に対応した HTTP リクエストによるファイル保存
CGI に対応した HTTP リクエストによるファイル保存の例題です。
ソケット通信を用いて HTTP リクエストを行う場合、レスポンスヘッダに含まれる Content-Length が 0 となり正しく本文が取得できない場合があります(libcurl 等を用いるとその辺の処理は自動的に行ってくれます)。
Apache サーバーに index.html 等のファイルを直接要求した場合にはそのようなことはありませんが、リクエストしたページが CGI で構成されている場合にそういう状況が発生します。
CGI はファイルの読み出しやページの生成の都合に応じて、逐次転送を行いますので、Content-Length の代わりにこれから送信するバイト数を16進数字にて送信しその本文を送信した後、転送が終われば 0 の文字列を送信します。
CGIによるファイル送信の流れ
ソケット通信を用いて HTTP リクエストを行う場合、レスポンスヘッダに含まれる Content-Length が 0 となり正しく本文が取得できない場合があります(libcurl 等を用いるとその辺の処理は自動的に行ってくれます)。
Apache サーバーに index.html 等のファイルを直接要求した場合にはそのようなことはありませんが、リクエストしたページが CGI で構成されている場合にそういう状況が発生します。
CGI はファイルの読み出しやページの生成の都合に応じて、逐次転送を行いますので、Content-Length の代わりにこれから送信するバイト数を16進数字にて送信しその本文を送信した後、転送が終われば 0 の文字列を送信します。
CGIによるファイル送信の流れ
レスポンスヘッダ例題では、HTTP リクエストを送信後 Content-Length が含まれるかどうかで CGI かどうかを判定し、受信処理により取得された本文をファイルとして保存しています。 実行結果
9bd9
[9bd9バイト分のデータ]
e000
[e000バイト分のデータ]
0
登録:
投稿 (Atom)
