質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • PHP

    19219questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

自宅サーバーにて、PHPのfile_get_contents("http://google.com")メソッドの処理時間が長すぎる。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 296

 分からない事&解決したいこと

自宅サーバーのcentOS6.8 centOS6.9 のPHPのfile_get_contents()処理時間を速くしたいです。

 時間計測結果

下記の3つの環境にて、
file_get_conetens()の時間を計測したところ、自宅サーバーのcentOSが遅すぎるという結果が得られました。

場所 PHP Version 時間 備考
自宅サーバー centOS6.8 centOS6.9  PHP7.2.0   約10秒  遅すぎる。。
自宅メインPC Windows10  PHP7.2.0   約0.2秒 
さくらレンタルサーバー FreeBSD  PHP5.4.45   約0.14秒 

 自宅のネット環境

WAN
|
ルーター[192.168.0.1]
└centOS [192.168.0.10]
└windows10 [192.168.0.17]

 テストに使用したPHPソース

echo '=========処理開始===========<br>'.PHP_EOL;

//PHPのバージョン表示
echo sprintf('Current PHP version: %s<br>', phpversion()).PHP_EOL;

//遅いメソッド処理の時間を調べる
$start = microtime(true);
$content = file_get_contents("http://google.com");
$time = microtime(true) - $start;

//スクレイピング結果からタイトルを取得
preg_match("~<title>(.+)</title>~", $content, $matches);

//結果表示
echo sprintf('title: %s<br>', $matches[1]).PHP_EOL;
echo sprintf('file_get_contentsのtime: %s<br>', $time).PHP_EOL;
echo '=========処理終了===========<br>'.PHP_EOL;

 テスト結果

▼自宅サーバーのcentOS

[root@localhost ~]# php file_get_contents.php
=========処理開始===========<br>
Current PHP version: 7.2.0<br>
title: Google<br>
file_get_contentsのtime: 10.242396831512<br>       //10秒。遅すぎる。。。。
=========処理終了===========<br>
▼自宅メインPCのwindows10

# php file_get_contents.php
=========処理開始===========<br>
Current PHP version: 7.2.0<br>
title: Google<br>
file_get_contentsのtime: 0.19305801391602<br>      //速い。
=========処理終了===========<br>
▼さくらレンタルサーバー(プラン:スタンダード 月額515円)

% php file_get_contents.php
=========処理開始===========<br>
Current PHP version: 5.4.45<br>
title: Google<br>
file_get_contentsのtime: 0.13969922065735<br>     //速い。
=========処理終了===========<br>

 質問まとめ

file_get_contents()を早くするために、手始めに何から取り組めばよいでしょうか。
検索しても、「curl()を使うと早くなる」といった情報しか見つからず、
crul()を試したところ、ほとんど速くなりませんでした。

調べるための検索ワードなど、教えていただけると幸いです。
よろしくお願い致します。

 追加で行った検証結果

追記(2018/01/04 22:37)

結果概要:
頂いた回答を元に、プロバイダのDNSからパブリックDNSに変更したところ、
物凄く処理時間のかかっていたPHP関数(file_get_contetns(),curl())が、
劇的に早くなりました。

変更前の処理時間:約5~10秒
変更後の処理時間:約0.3秒

 作業内容:検証用コマンドの実施(ネットワーク設定変更前)

▼検証前に現在の設定確認

[root@localhost ~]# cat /etc/resolv.conf
# Generated by NetworkManager
domain tojox1.kt.home.ne.jp
search tojox1.kt.home.ne.jp
nameserver 220.152.38.233
nameserver 220.152.38.201

[root@localhost ~]# ls -l /etc/sysconfig/network-scripts/ | grep eth
-rwxr-xr-x. 1 root root  5891  1月 18 21:10 2017 ifdown-eth
-rwxr-xr-x. 1 root root 12084  1月 18 21:10 2017 ifup-eth

→"ifcfg-eth0"ファイルが存在しませんでした。
→恐らくサーバー構築時に、私が作っていません。今回の回答内容を元に調べている際にこのファイルも必要ということを学びました。(構築当時、ネットワークが繋がっているようだったため、「ネットワーク設定はきっとOKだ!」と思っていました。)

[root@localhost ~]# cat /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=localhost.localdomain
GATEWAY=192.168.0.1

▼検証用コマンドの結果

実行環境 実行したコマンド 早さ(体感) 備考
自宅サーバー centOS6.8 centOS6.9 dig example.com @8.8.8.8 0.1秒以下
自宅サーバー centOS6.8 centOS6.9 ping -c 1 93.184.216.34 約0.1秒
自宅サーバー centOS6.8 centOS6.9 dig example.com 0.1秒以下 意外と早かったです
自宅サーバー centOS6.8 centOS6.9 ping -c 1 example.com 約0.1秒 意外と早かったです
 作業内容:検証用コマンドの実施(ネットワーク設定含む)

ネットワーク設定変更作業:

▼ifcfg-eth0を作成

[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
#memo: このファイルは20180114に自分で新規作成した(このファイルが存在しなかった為))
#参考: http://www.obenri.com/_minset_cent6/netconfig_cent6.html
DEVICE=eth0
NM_CONTROLLED=yes
ONBOOT=yes
TYPE=Ethernet
BOOTPROTO=none
IPADDR=192.168.0.10
HWaddr=00:1F:29:4C:86:61
DNS1=8.8.8.8         //パブリックDNSを指定
DNS2=8.8.4.4         //パブリックDNSを指定
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="System eth0"

▼ネットワーク再起動

[root@localhost ~]# service network restart
インターフェース eth0 を終了中:  デバイスの状態: 3 (切断済み)
                                                           [  OK  ]
ループバックインターフェースを終了中                       [  OK  ]
ループバックインターフェイスを呼び込み中                   [  OK  ]
インターフェース eth0 を活性化中:  アクティブ接続の状態: アクティベート済み
アクティブ接続のパス: /org/freedesktop/NetworkManager/ActiveConnection/3
                                                           [  OK  ]

▼resolv.confが自動で更新された事を確認しました

[root@localhost ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 8.8.8.8
nameserver 8.8.4.4

//備考: centos6ではifcfg-eth0を作ると自動でresolv.confが設定されるという記事を読み、実際に更新されることを確認しました。

▼(こちらは変更していないので、)変更が無い事を確認

[root@localhost ~]# cat /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=localhost.localdomain
GATEWAY=192.168.0.1

▼検証用コマンドの結果

実行環境 実行したコマンド 早さ(体感) 備考
自宅サーバー centOS6.8 centOS6.9 dig example.com @8.8.8.8 0.1秒以下 変化無し
自宅サーバー centOS6.8 centOS6.9 ping -c 1 93.184.216.34 約0.1秒 変化無し
自宅サーバー centOS6.8 centOS6.9 dig example.com 0.1秒以下 変化無し
自宅サーバー centOS6.8 centOS6.9 ping -c 1 example.com 約0.1秒 変化無し

▼PHP関数の計測結果

実行環境 関数名 ※ネットワーク設定変更前の早さ ネットワーク設定変更後の早さ 備考
自宅サーバー centOS6.8 centOS6.9 curl() 約5秒 約0.2秒 早くなりました!!
自宅サーバー centOS6.8 centOS6.9 file_get_contents() 約10秒 約0.3秒 早くなりました!!

検証以上

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+5

Googleページのスクレイピングはポリシー違反なのでやめましょう(←とりあえず残しておきます)

コメントによるとやはりネットワーク設定に問題があると思いますので回答を書き換えました。まずは、DNS設定に問題があるのか、その他ネットワーク設定に問題があるのか確認してみるとよいです。

たぶん名前解決に時間がかかっていると思われるので、下記コマンドで確認してみてください。下記どれでも遅い場合はその他ネットワーク設定に問題があるはずです。

 DNS確認

  1. GoogleなどのパブリックDNSをIP直指定で名前解決をしてみます(名前解決がないので早いはず)
  2. example.com に直接IP直指定でPINGをうってみます(名前解決がないので早いはず)
  3. 現在のDNS設定で名前解決してみます(名前解決があるので遅いはず)
  4. 現在のDNS設定でPINGをうってみます(名前解決があるので遅いはず)
#(↓早いはず)google-public-dns-a.google.com:8.8.8.8
dig example.com @8.8.8.8

#(↓早いはず)example.com:93.184.216.34
ping -c 1 93.184.216.34

#(↓遅いはず)プロバイダのDNSを使って名前解決する
dig example.com

#(↓遅いはず)プロバイダのDNSを使ってPING
ping -c 1 example.com

 resolv.conf

上記から、DNS設定に問題がある場合は、直接外部プロバイダのDNSを指定するのではなく、ルーターから名前解決できるようにしてください。CentOSにプライベートIPを振っているようなので、多分 192.168.0.1, 192.168.1.1 のようなプライベートIPアドレスです。ネットワーク設定に問題のないWindowsなどで確認してみてください。

そして、たぶん必要ないと思われるのでdomain, searchはコメントアウトしてください。これらはざっくりいうとドメインの補完機能です。

例えば、現在の設定でいうとhttp://something.tojox1.kt.home.ne.jphttp://somethingだけでアクセスできるようにする機能です。この機能が必須でdomainもsearchも同じなら、domain だけ残すようにします。複数ドメインが必要な場合は search のみにします。

/etc/resolv.conf

#domain tojox1.kt.home.ne.jp
#search tojox1.kt.home.ne.jp tojox2.kt.home.ne.jp    #←複数ドメインの場合
nameserver ルーターのIPアドレス

そして下記コマンドでネットワークを再起動してからDNSのレスポンスを確認してみます。

sudo service network restart
#OR
#sudo /etc/init.d/network restart

#名前解決の応答を確認
dig www.google.co.jp
curl -L https://www.google.co.jp

 パブリックDNS

たまにプロバイダのDNS応答速度が非常に不安定な場合があります。その場合はパブリックDNSに変更してみます。

 ネットワーク設定

ネットワークアダプタやルーターに問題がある場合は下記を参考にしてみてください。基本的にネットワークアダプタに問題がある場合はルーターや同じネットワーク上のWindowsマシンからのレスポンスも遅いはずです。

  • CentOSで使ってないネットワークアダプタを無効にする
  • CentOSのネットワークアダプタを固定IPに変更する(DHCPの場合)
  • CentOSやルーターのプライベートネットワーク向けのIPv6サポートを無効にしてみる
  • CentOSでSELinuxやiptablesが有効になっている場合はOFFにしてみる
  • ルーターの設定を確認してみる(ルーティング設定やパケットフィルタなど)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/14 13:06

    Tomakさん、回答頂きありがとうございます。

    頂いた情報を元にテストを行った結果を報告させて頂きます。

    //下記コマンドの実行結果
    [Bash]
    curl -L https://www.google.co.jp

    ▼自宅サーバーcentOS
    約5秒 //他のサーバーに比べると、かなり時間がかかっています。
    ▼自宅メインPC windows10
    約0.2秒
    ▼さくらレンタルサーバー
    約0.2秒

    //DNS設定の確認
    [root@localhost ~]# cat /etc/resolv.conf
    # Generated by NetworkManager
    domain tojox1.kt.home.ne.jp
    search tojox1.kt.home.ne.jp
    nameserver 220.152.38.233
    nameserver 220.152.38.201

    //googleのスクレイピングについて
    承知いたしました。
    公開APIを叩く以外に使用しないよう気を付けます。ご注意いただきありがとうございます。

    //頂いたサンプルコードによるfile_get_contetns()処理
    ▼自宅サーバーcentOS
    [root@localhost ~]# php file_get_contents.php
    file_get_contentsのtime: 5.2409801483154<br>

    ▼自宅メインPC windows10
    C:\> php file_get_contents.php
    file_get_contentsのtime: 0.3338029384613<br>

    ▼さくらレンタルサーバー
    % php file_get_contents.php
    file_get_contentsのtime: 0.26770210266113<br>


    参考サイトの掲載など丁寧に回答頂きありがとうございます。
    DNS設定のコメントアウトを試しながら時間を測定してみます。

    取り急ぎ、お礼申し上げます。

    キャンセル

  • 2018/01/14 23:39 編集

    Tomakさん、回答頂きありがとうございます。
    頂いた回答を元に、ネットワーク設定を変更したところ、
    本質問が解決いたしました。本当に助かりました!
    ありがとうございます。
    (作業した内容を追記致しました)

    作業概要:
    頂いた回答を元に
    DNSをパブリックDNSに変更したところ、目的の処理(file_get_contents())が速くなりました。

    追記:
    [直接外部プロバイダのDNSを指定せず、ルーターから名前解決できるようにする]設定につきましては、
    今回は検証しておりません。(ちょっと調べてみましたが、ルータの設定方法を含めネットワークの仕組みについて私がもっと理解する必要だと思い、今は一旦後回しにする事にしました。)

    お礼:
    解決策を頂いた事以外に、変更を実施する具体的な意味や問題の切り分け方などを丁寧に教えていただき、物凄く勉強になりました。本当にありがとうございました。

    キャンセル

  • 2018/01/14 23:45

    追記2:
    file_get_contents()にて公開APIを叩いたところ、同様に処理が早くなる事を確認しました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    19219questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • トップ
  • PHPに関する質問
  • 自宅サーバーにて、PHPのfile_get_contents("http://google.com")メソッドの処理時間が長すぎる。