Windows Server 2022 Datacenter
nginx 1.22
php ts 8.3
session用的是redis 5.0.14.1,
代码框架用的是thinkphp5.0
具体的现象是同一个会话请求时, 前面的请求处理会阻塞,下一个异步进来的请求,
不同会话之间不会相互阻塞
php API 测试的代码很简单
{
function test(){
echo "hello world";
}
function sleep1(){
//单存输出 <pre> 标签方便测试
pre();
//直接关闭session
session_write_close();
if (session_status() === PHP_SESSION_ACTIVE) {
echo_ln("session 开启了");
} else {
echo_ln("session 没启动");
}
// 在需要的地方检查session_write_close()是否被调用
if (session_status() === PHP_SESSION_ACTIVE && !headers_sent()) {
// 如果没有输出到浏览器并且Session处于活动状态,则调用session_write_close()
// session_write_close();
echo_ln("session 没关闭");
}
// echo_ln 单存的在 输出语句后面补上换行符
echo_ln( "strat:" . time() );
sleep(10);
echo_ln( "end:" . time() );
}
}
同一个浏览器开两个标签页,手动的,几乎同时刷新,会发现第二个被刷新的页面一定比前一个慢10秒才开始执行
已经配置过 php.ini , nginx.conf
nginx.conf
#user nobody;
worker_processes 8;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format detailed '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'upstream: $upstream_addr';
# access_log logs/access.log main;
access_log logs/access.log detailed;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
#为了让nginx在windows系统下支持高并发处理fastcgi
#手动添加多个监听ip
#加多少个监听ip就表示加多少监听进程协助处理请求
#直接加32个
upstream phpfastcgi_proxy{
#最少连接数负载均衡
least_conn;
server 127.0.0.1:9000;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
# server 127.0.0.1:9004;
# server 127.0.0.1:9005;
# server 127.0.0.1:9006;
# server 127.0.0.1:9007;
# server 127.0.0.1:9008;
# server 127.0.0.1:9009;
# server 127.0.0.1:9010;
# server 127.0.0.1:9011;
# server 127.0.0.1:9012;
# server 127.0.0.1:9013;
# server 127.0.0.1:9014;
# server 127.0.0.1:9015;
# server 127.0.0.1:9016;
# server 127.0.0.1:9017;
# server 127.0.0.1:9018;
# server 127.0.0.1:9019;
# server 127.0.0.1:9020;
# server 127.0.0.1:9021;
# server 127.0.0.1:9022;
# server 127.0.0.1:9023;
# server 127.0.0.1:9024;
# server 127.0.0.1:9025;
# server 127.0.0.1:9026;
# server 127.0.0.1:9027;
# server 127.0.0.1:9028;
# server 127.0.0.1:9029;
# server 127.0.0.1:9030;
# server 127.0.0.1:9031;
}
#开发
server {
listen 8000;
server_name location;
index index.php;
root D:\webapp\development\public;
location / {
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
}
location ~ .*\.php {
if (!-e $document_root$fastcgi_script_name) {
##此处直接返回404错误
##你也可以rewrite 到新地址去,然后break;
return 404;
}
#修改监听ip 为 phpfastcgi_proxy
fastcgi_pass phpfastcgi_proxy;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#charset koi8-r;
#access_log logs/host.access.log main;
# location / {
# root html;
# index index.html index.htm;
# }
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 8001;
server_name location;
index index.php;
root D:\webapp\development2\public;
location / {
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
}
location ~ .*\.php {
if (!-e $document_root$fastcgi_script_name) {
##此处直接返回404错误
##你也可以rewrite 到新地址去,然后break;
return 404;
}
fastcgi_pass phpfastcgi_proxy;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#charset koi8-r;
#access_log logs/host.access.log main;
# location / {
# root html;
# index index.html index.htm;
# }
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#生产
server {
listen 88;
server_name location;
index index.php;
root D:\webapp\production\public;
location / {
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
}
location ~ .*\.php {
if (!-e $document_root$fastcgi_script_name) {
##此处直接返回404错误
##你也可以rewrite 到新地址去,然后break;
return 404;
}
fastcgi_pass phpfastcgi_proxy;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#charset koi8-r;
#access_log logs/host.access.log main;
# location / {
# root html;
# index index.html index.htm;
# }
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
目前尚不知是php-cgi在windows系统下的根本性特性还是我配置哪里写错
有查到一个说法,windows下只有apache才能让php不阻塞执行,但是尚未验证,
请有经验的同行帮忙解答问题
结论如一楼评论,需要精确控制每次session变量的启动和关闭
然后我的php举例并不能模拟实际场景
一般情况下的阻塞场景,基本是请求数据库或其他应用程序,比较耗时
而 sleep函数 比较特殊,是真的直接阻塞整个进程或线程,原理不深究
php-fpm 同一会话session访问是串行的,上一个请求需要结束session后,下一个请求才能访问session。结局方案,需要的时候才用session_start()开启session,session不需要再使用了立刻执行session_write_close()关闭session
谢谢提供思路