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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Apache

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

PHP

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

JavaScript

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

jQuery

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

Ajax

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

Q&A

解決済

1回答

1466閲覧

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

meamea

総合スコア15

Apache

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

PHP

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

JavaScript

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

jQuery

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

Ajax

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

0グッド

1クリップ

投稿2018/05/30 00:41

編集2018/05/30 00:48

状態

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

相談内容

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

環境

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

簡易ソース及び実行結果

js

1for(var i=0;i<5;i++){ 2 (function(i){ 3 console.log("sent"); 4 $.ajax({ 5 url:url, 6 type:"POST" 7 }).done(function (response) { 8 console.log("ok"); 9 }); 10 })(); 11}

php

1function xxxx(){ 2 for($i=0;$i<20;$i++){ 3 //更新チェック処理及び離脱処理 4 sleep(1); 5 } 6 echo (json_encode($result)); 7 exit(); 8}
(リクエストを投げる時はほぼ同時) sent sent sent sent sent (20秒間隔で結果が返ってくる) ok ok ok ok ok

試したこと

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

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

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

投稿2018/05/30 01:32

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meamea

2018/05/30 04:49

ご回答ありがとうございます。 引き続き調査したところ、別ブラウザでの読み込みまでは止まっていないため、 並列化自体はできていました。 MPMはpreforkを使用しており、チューニングまではされていませんが それぞれ実行されているpidを出力したところ、それぞれ別のプロセス動作していました。 > PHP(フレームワークなども含む)で並列リクエストをロックしているような状況 ご指摘の状況を微塵も思いつかなかったので記述していませんが、 ZendFramework2を使用しております。 ZF2を使用せずに素のPHPで実行したところ、しっかり並列化しましたので、 フレームワーク上の問題と判明しました。 ありがとうございました。
ArimaRyunosuke

2018/05/30 10: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 を呼ぶのは狂気の沙汰だと思う)。
meamea

2018/05/31 00:31

>> ArimaRyunosuke様 補足ありがとうございます。 こちらでも問題点を判明後引き続き調査したところ、おっしゃる通りセッションファイルのロックが原因でした。 ZF2.4.xを使用しており、該当処理の前に認証を行っており、認証状態の保持にセッションを使用し、ロックがかかっている状態でした。 しかし、Zend/Authentication/Storageでのセッションのため、 Zend/Session/StorageにはあるisLocked()やunlock()等のセッション制御系が対応されていないため、 一旦今回は保留としました。 今回についてはポーリングに切り替えることで対処したいと考えております。 ご両者共、大変勉強になりました。 誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問