PHP内からあのサービスに接続したいけど、その前に正常に動いているか確認したいってときに、ソケット通信で相手先のサービスの稼動状況を確認できたりします。
PHPでソケット通信してサービスの稼動状況をチェックするサンプル
PHPでソケット通信するためには、ソケット関数
やfsockopen関数
を利用します。
<?php $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if (@socket_connect($socket, "192.168.0.100", 80)) { echo "接続できました"; } else { echo socket_strerror(socket_last_error()); }
<?php $socket = @fsockopen("192.168.0.100", 23, $errno, $errstr, 10); if ($socket === FALSE) { echo $errno . $errstr; } else { echo "接続できました"; }
これはサーバーや特定のポート(例えばHTTPとか)が応答するかどうかのチェックなので、厳密なその上で利用したいサービスやAPI等が正常に応答するかというチェックではありません。
例えば、最初のHTTPのサービスが動いているかどうかは、ポートからの応答があるというのはわかりますが、実際にリクエストを投げてみればHTTPステータスコード500(Internal Server Error)が返ってくる場合もあり、厳密なチェックではありません。
ただ、PINGを飛ばして応答を見るといった簡易的な死活チェックには使えます。
実際に応答が無かった場合などは、
111Connection refused 113No route to host
のような、エラーコードとメッセージを受け取ることもできます。
socket_connect()のタイムアウトの問題
socket_connect() を使った場合で、例えば指定したIPのサーバーがダウンしていたり経路が存在しなかった場合に、激しくタイムアウトまで待たされるという現象が出たりします。
どうもsocket_connect()にはコネクション確立時のタイムアウトが設定できないっぽいです。
socket_set_option() やstream_set_timeout() など設定できそうな関数があるんですが、コネクション時のタイムアウトは設定できないっぽい。(そもそもstream_set_timeout()はストリームに対する操作のため、socket_connect()のリソースには適用できない)
PEARのNet_Socketを使っても同様の問題(内部的にはsocket_connect()を使っているので当たり前ですが)が出ますし、オプションも見当たらないのでfsockopen()を使った方が無難なのかな、と思ったりします。
$socket = @fsockopen("192.168.0.100", 23, $errno, $errstr, 10);
のように、第5引数でコネクション時のタイムアウト(上記の場合は10秒)を設定できますし。
[PR]
[PR]
関連記事
PHPのcURL関数を使ってHTTPSでアクセスすると環境変数が読込まれる
Apache Tikaを使ってドキュメントの中身を取り出すPHPプログラム
不要なApacheやPHPの拡張モジュールを削除するとどれくらい効果があるか調べてみる
NFSマウントした領域内でPHPのsession_startを実行すると異様に重い件
PHPのプログラムをデーモンとして動かしてくれるPEAR::System_Daemon
[PHP] inotify関数を使ってログを監視するスクリプトを作ろう
[24時間365日] サーバ/インフラを支える技術