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

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

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

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

PHP

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

Q&A

解決済

2回答

3041閲覧

NginxでPHPを動かした際、一つのブラウザから同時に送られたリクエストを、並列で処理することができません

kb2

総合スコア8

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

PHP

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

0グッド

1クリップ

投稿2017/08/17 06:59

###前提・実現したいこと
NginxでPHPを、PHP-FPMにて動かしています。そのPHPにて、同じブラウザからほぼ同時に送られた複数のリクエストを、並列で処理しようとしています。
最終的に行いたいのは、一つのブラウザから送信された複数のAjax通信を、PHPを使い並列で同時に処理していくことですが、その前段階で躓いています。

###発生している問題
同じブラウザからの複数のリクエストを受けつけ、並列で処理しようとしていますが、なぜかうまく並列で処理してくれません。

curlで複数のリクエストを送ると並列で処理してくれますが、Chromeなどで複数のタブを開き、ほぼ同時にリクエストを送ると、並列で処理されず、リクエストが送られた順に、一つずつ処理が行われてしまいます。

###確認した方法など
Nginxから最初に読み込まれる、index.php の記載は

php

1<?php 2error_log('index.php start' . "\n", 3, '/xxx/log.txt'); 3sleep(5); 4error_log('index.php end' . "\n", 3, '/xxx/log.txt');

という、log.txt にログを吐き出すだけの非常にシンプルなものです。

同一ブラウザから3つのリクエストをほぼ同時に送信した場合は、log.txtへの出力は下記のようになり、各リクエストが順番に処理されてしまっているのがわかりました。

index.php start index.php end index.php start index.php end index.php start index.php end

curlから3つのリクエストをほぼ同時に送信した場合は、log.txtへの出力は下記のようになり、各リクエストが並列で処理できていることがわかりました。

index.php start index.php start index.php start index.php end index.php end index.php end

同じChromeでも、シークレットモードからと通常のモードからほぼ同時にリクエストを送ると、その2つのリクエストは並列で処理してくれています。

並列で処理できる場合があるので、Nginxのworker数やコネクション数などは問題ないと思うのですが、同一ブラウザから送られた場合に、並列で処理できないのは何が問題なのでしょうか。
もし分かる方がいましたら、是非ご教授いただければ幸いです。

###補足情報(言語/FW/ツール等のバージョンなど)
nginx 1.9.9
PHP 5.6.30 (fpm-fcgi)

nginxの設定ファイルの一部

user nginx; worker_processes auto; worker_rlimit_nofile 10240; events { worker_connections 4096; use epoll; multi_accept on; }
location / { try_files $uri /index.php$is_args$args; } location ~ \.php$ { fastcgi_buffer_size 64K; fastcgi_buffers 16 64K; fastcgi_busy_buffers_size 256K; fastcgi_temp_file_write_size 256k; try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }

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

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

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

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

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

guest

回答2

0

自己解決

原因は結局不明でしたが、一応なんとかなりました。

URLに異なるクエリパラメータを付与することによって、同一ブラウザからのアクセスでも、並列で処理してくれることがわかりました。

リクエストそれぞれに、ランダムな値などをクエリパラメータに付与することで、対処をしたいと思います。

見ていただいた方、どうもありがとうございました。

投稿2017/08/17 09:32

kb2

総合スコア8

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

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

0

Nginxの詳しい挙動はわかりませんが、PHPの動きとして試したところ、同一ブラウザでは複数タブ間でPHPのセッション情報が共有され、シークレットモードではセッション情報が引き継がれずに新しい環境になるので、その辺りでブラウザとWebサーバの接続が一つの直列にまとめられている等があるかもしれません。
ひとまず並列に処理したい場合はBeanstalkdやAmazon SQS等のキューシステムを利用して非同期で処理するとやりたいことが解決できるかもしれません。
PHPのWebフレームワークのLaravelの例では以下のような機能があり、他のフレームワークや単体ライブラリでも可能かと思います。
Laravel 5.4 キュー

※詳細に接続状況を検証する場合は、Nginxの監視ツールや通信内容を確認するツールなどもあるので検証すると良いかと思います。

投稿2017/08/17 08:23

編集2017/08/17 08:30
aro10

総合スコア4106

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

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

kb2

2017/08/17 08:34

ご回答ありがとうございます。 セッション情報が共有される、ということに関係はありそうな気はしますね。 サーバー設定などでどうしようもなければ、非同期処理などのやりかたも検討してみようかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問