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

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

ただいまの
回答率

90.51%

  • PHP

    20382questions

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

  • JavaScript

    16461questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    6720questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • Apache

    1823questions

    Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

  • Ajax

    1091questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Ajaxによるロングポーリング中のリクエストの直列化について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 218

meamea

score 7

 状態

JS+PHPでリアルタイムのチャットをロングポーリングで実装しています。
JS側でリクエストを投げ、PHP側で1秒間隔でチェックを行い、タイムアウトを考慮して20秒程度で一旦返す形で実装しております。
サーバにajaxでリクエストを投げてからサーバ側で処理している時に、ページ遷移(更新)を行うと
前述のリクエストが返ってくるまでページ読み込みがされない状態となり、最大20秒前後待つ形になってしまいました。

 相談内容

次項の環境は変えずに、同一セッションからの複数リクエストが直列化されない様にすることは可能でしょうか。
ex)Apacheの設定変更や、jsでの設定項目など
難しい場合、素直にjs側でPromiseなりsetIntervalなどでポーリング処理を行いたいと思います。

 環境

Apache2.4
PHP5.6
MySQL5.6
全て1台にまとまっております。

 簡易ソース及び実行結果

for(var i=0;i<5;i++){
    (function(i){
        console.log("sent");
        $.ajax({
            url:url,
            type:"POST"
        }).done(function (response) {
            console.log("ok");
        });
    })();
}
function xxxx(){
    for($i=0;$i<20;$i++){
        //更新チェック処理及び離脱処理
        sleep(1);
    }
    echo (json_encode($result));
    exit();
}
(リクエストを投げる時はほぼ同時)
sent
sent
sent
sent
sent
(20秒間隔で結果が返ってくる)
ok
ok
ok
ok
ok

 試したこと

xhr.abort()でのリクエストキャンセル要求
→サーバ側の処理まで中断されないため、ロングポーリングが動ききってからページリロードなどのリクエストが処理されました。

 試してみたいが試せてないこと

HTTP/2でのリクエストの場合どうなるのか?
APIサーバを独立させ冗長化した後にリクエストを分けた場合には解決するのか?
nginxなどのApache以外のWebサーバを選択した場合には解決するのか?

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

次項の環境は変えずに、同一セッションからの複数リクエストが直列化されない様にすることは可能でしょうか。

むしろ、普通に組めばApache+PHPの処理は並列にさばけますし、PHP(フレームワークなども含む)で並列リクエストをロックしているような状況でなければ、1回に1つしかリクエストを処理できないのは設定ミスに近いと考えます(実運用には、到底耐えられないことでしょう)。

実際の詳細な設定は、ApacheでどのMPMを選んでいるか、そしてPHPをどう動かしているかによります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/30 13:49

    ご回答ありがとうございます。
    引き続き調査したところ、別ブラウザでの読み込みまでは止まっていないため、
    並列化自体はできていました。
    MPMはpreforkを使用しており、チューニングまではされていませんが
    それぞれ実行されているpidを出力したところ、それぞれ別のプロセス動作していました。

    > PHP(フレームワークなども含む)で並列リクエストをロックしているような状況
    ご指摘の状況を微塵も思いつかなかったので記述していませんが、
    ZendFramework2を使用しております。
    ZF2を使用せずに素のPHPで実行したところ、しっかり並列化しましたので、
    フレームワーク上の問題と判明しました。

    ありがとうございました。

    キャンセル

  • 2018/05/30 19:18

    解決しているようですが横から少し補足します。

    提示されている現象の原因としてよく「セッションファイルのロック」が挙げられます。

    php の素のセッション機構(ローカルファイル)は開始時にロックを取得するため、リクエスト中は次のリクエストがブロックされます。
    よくある対策としては下記があります。

    ### session_write_close を使う

    これを呼ぶとセッションが書き込まれ、ファイルロックが開放されるので、結果としてブロックも解除されます。
    ただし、これは実質的に「セッションの終了」を意味する関数なので、再度セッションを使いたいときは `session_start` する必要があります。

    参考: http://php.net/manual/ja/function.session-write-close.php

    ### session_start に read_and_close を渡す

    php7 以降であれば read_and_close を渡すことで読み込みが完了したらクローズするようにできます。
    私は使ったことがないので詳細な挙動はわかりませんが、おそらく読み取り専用となり、以後セッションを書き込んでも反映されなくなるような気がします。

    参考: http://php.net/manual/ja/function.session-start.php

    -----

    仮にセッションファイルロックが原因だとしても、どちらも php のネイティブな処理なので ZF2 が対応していなければ対処は難しいかもしれません。
    (特に後者。前者はまだ呼べば動きそうだが、後者は ZF で直に session_start を呼ぶのは狂気の沙汰だと思う)。

    キャンセル

  • 2018/05/31 09:31

    >> ArimaRyunosuke様
    補足ありがとうございます。
    こちらでも問題点を判明後引き続き調査したところ、おっしゃる通りセッションファイルのロックが原因でした。

    ZF2.4.xを使用しており、該当処理の前に認証を行っており、認証状態の保持にセッションを使用し、ロックがかかっている状態でした。
    しかし、Zend/Authentication/Storageでのセッションのため、
    Zend/Session/StorageにはあるisLocked()やunlock()等のセッション制御系が対応されていないため、
    一旦今回は保留としました。

    今回についてはポーリングに切り替えることで対処したいと考えております。
    ご両者共、大変勉強になりました。
    誠にありがとうございました。

    キャンセル

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

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

関連した質問

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

  • PHP

    20382questions

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

  • JavaScript

    16461questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    6720questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • Apache

    1823questions

    Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

  • Ajax

    1091questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。