centos7利用ngxtop监控nginx

在使用centos7的软件包管理程序yum安装python-pip的时候会报一下错误:

No package python-pip available.
Error: Nothing to do

说没有python-pip软件包可以安装。

这是因为像centos这类衍生出来的发行版,他们的源有时候内容更新的比较滞后,或者说有时候一些扩展的源根本就没有。

所以在使用yum来search python-pip的时候,会说没有找到该软件包。因此为了能够安装这些包,需要先安装扩展源EPEL。

EPEL(http://fedoraproject.org/wiki/EPEL) 是由 Fedora 社区打造,为 RHEL 及衍生发行版如 CentOS、Scientific Linux 等提供高质量软件包的项目。

首先安装epel扩展源:

sudo yum -y install epel-release

然后安装python-pip

安装pip

# sudo yum -y install python-pip

安装完之后别忘了清除一下cache

sudo yum clean all

安装好pip之后我们就可以安装ngxtop了

#sudo pip install ngxtop

安装成功,现在可操作ngxtop命令了,

#ngxtop

效果如下

#ngxtop

通常情况下我们的配置文件都在vhosts里面
# ngxtop -c /server/nginx/conf/vhosts/123.conf 

解决CentOS 7中php-fpm进程数过多导致服务器内存资源消耗较大的问题

前言:

最近服务器内存使用率一直居高不下,检查之后发现可能和php-fpm进程数过多有关。本文记录了我优化php-fpm配置文件的过程并补充了一些和php-fpm有关的知识。

什么是php-fpm:

php-fpm即FastCGI进程管理器,用于控制php的内存和进程等。

操作环境:

CentOS 7

问题检查:

首先查看php进程总数:
回显:
根据回显信息可知,查询时有20个php-fpm进程。
也可以通过下面的命令列出消耗内存最多的前50个进程:

解决过程:

下面我们通过修改配置文件来优化php-fpm,以达到降低内存使用率的目的。
我的php-fpm配置文件在 .../server/php/etc/ 目录下,进入该目录。
先备份一下原配置文件:
注:
使用vim打开配置文件后,按Esc键,之后输入”/”, 再输入“xxx”可以查找“xxx”这个字符串。
具体配置参数如下:
重启服务器:
重启后可以发现内存使用率相比于之前降低了。
注:
0. php-fpm.conf中参数作用的说明:
pm.max_children:静态方式下开启的php-fpm进程数量。
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式下的最小php-fpm进程数。
pm.max_spare_servers:动态方式下的最大php-fpm进程数量。
1. 进行上述设置时,我将php-fpm的执行方式设置成了动态:
2. php-fpm有两种执行方式:
一种是Static静态,另一种是Dynamic动态。如果设置成静态,那么只有 pm.max_children 这个参数起作用。如果设置成动态则有 pm.start_servers 、 pm.min_spare_servers 和 pm.max_spare_servers 这三个参数起作用。设置成动态后,当php-fpm启动时会按照 pm.start_servers 的参数设置启动相应个数的进程,之后php-fpm的进程数量将维持在 pm.min_spare_servers 和 pm.max_spare_servers 指定的个数之间。
3. 如何选择使用php-fpm的静态还是动态执行方式:
动态php-fpm执行方式允许php-fpm释放多余进程,从而节约内存资源。
静态php-fpm执行方式不允许php-fpm释放多于进程,避免了频繁开启或停止php-fpm进程,从而降低了服务器在某些情况下的响应时间。
本文转自网络:http://zhaokaifeng.com/?p=653

实时查看php-fpm的状态

location ~ ^/status$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
}

然后在php-fpm.conf里面打开选项
pm.status_path = /status
这样的话通过http://域名/status就可以看到当前的php情况,以前之知道可以配置location来看nginx的状态,没想到还可以看php-fpm的状态,,真的是学习了,,看到的状态如下:
pool: www php运行的组
process manager: dynamic php-fpm运行的方式
start time: 04/Jun/2012:16:05:32 +0800 开始时间
start since: 5932
accepted conn: 65678 接受链接
listen queue: 0 监听队列
max listen queue: 1 最大监听队列
listen queue len: 128 监听队列len
idle processes: 82 空闲进程
active processes: 4 活动进程
total processes: 86 总进程
max active processes: 25 最大活动进程
max children reached: 0 最大的子进程达到
实时的查看php-fpm的状态,进而优化php-fpm

本文来自网络:https://blog.csdn.net/qdujunjie/article/details/43446667

php-fpm参数调优

关于php-fpm.conf参数调优,只对重要的参数进程调优.其它可参数前辈的.

http://php.net/manual/zh/install.fpm.configuration.php (官方的)

http://www.cnblogs.com/argb/p/3604340.html

http://www.cnblogs.com/jonsea/p/5522018.html

https://www.zybuluo.com/phper/note/89081

http://blog.64mazi.com/299/(推荐阅读)

1
2
3
4
5
关于emergency_restart_threshold 和emergency_restart_interval 参数,设置多少合适
额定内存为4G,拿出一半内存做php使用,即2G,每个php-fpm进程30m(经验值)
则2g最多可以承受2048/30~=68即设置为
emergency_restart_threshold=60(60个进程数)
emergency_restart_interval=60s(60秒内出现60个进程则优雅的重进php-fpm服务)
pm表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)。在更老一些的版本中,dynamic被称作apache-like。这个要注意看配置文件的说明。

下面4个参数的意思分别为:

pm.max_children:静态方式下开启的php-fpm进程数量。
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式下的最小php-fpm进程数量。
pm.max_spare_servers:动态方式下的最大php-fpm进程数量。

如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。

如果dm设置为dynamic,那么pm.max_children参数失效,
后面3个参数生效。
系统会在php-fpm运行开始的时候启动pm.start_servers个php-fpm进程,
然后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数。

公式:

假定一个php-fpm进程为30m计算,若4g内存,拿出一半做的php-fpm使用即2g
mem=2048pm=dynamicpm.maxchildren=100(

mem/20)
pm.start_servers = 75 (mem/30)minspareservers+(maxspareserversminspareservers)/2pm.minspareservers=50(

mem/40)
pm.max_spare_servers = 50 ($mem/20)

pm.max_children = 50 是最大可创建的子进程的数量。必须设置。这里表示最多只能50个子进程。

pm.start_servers = 20 随着php-fpm一起启动时创建的子进程数目。默认值:min_spare_servers + (max_spare_servers – min_spare_servers) / 2。这里表示,一起启动会有20个子进程。

pm.min_spare_servers = 10
设置服务器空闲时最小php-fpm进程数量。必须设置。如果空闲的时候,会检查如果少于10个,就会启动几个来补上。

pm.max_spare_servers = 30
设置服务器空闲时最大php-fpm进程数量。必须设置。如果空闲时,会检查进程数,多于30个了,就会关闭几个,达到30个的状态。

实际上的内存消耗是max_children*max_requests*每个请求使用内存
其它php优化
尽量少安装PHP模块,最简单是最好(快)的
socket连接FastCGI,/dev/shm是内存文件系统,socket放在内存中肯定会快些
cat >> /etc/security/limits.conf <<EOF
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
EOF
增加 PHP-FPM 打开文件描述符的限制:
# vi $php_install_dir/etc/php-fpm.conf
rlimit_files = 51200

以下摘自(麻子来了)http://blog.64mazi.com/299/

一、常用参数解释:


1)pm = dynamic #对于专用服务器,pm可以设置为static。
#如何控制子进程,选项有static和dynamic。
如果选择static,则由pm.max_children指定固定的子进程数。
如果选择dynamic,则由pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers 参数决定.
2)pm.max_children

在同一时间最大的进程数

pm.max_children = 120

3)pm.start_servers

php-fpm启动时开启的等待请求到来的进程数,默认值为:min_spare_servers + (max_spare_servers - min_spare_servers) / 2

pm.start_servers = 80

4)pm.min_spare_servers
在空闲状态下,运行的最小进程数,如果小于此值,会创建新的进程
pm.min_spare_servers = 60

5)pm.max_spare_servers
在空闲状态下,运行的最大进程数,如果大于此值,会kill部分进程
pm.max_spare_servers = 120

6)pm.process_idle_timeout
空闲多少秒之后进程会被kill,默认为10s
pm.process_idle_timeout = 10s

7)pm.max_requests
每个进程处理多少个请求之后自动终止,可以有效防止内存溢出,如果为0则不会自动终止,默认为0#设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 
如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.
pm.max_requests = 500 

8)pm.status_path
注册的URI,以展示php-fpm状态的统计信息
     pm.status_path = /status
     其中统计页面信息有:
     pool 进程池名称
     process manager 进程管理器名称(static, dynamic or ondemand)
     start time php-fpm启动时间
     start since php-fpm启动的总秒数
     accepted conn 当前进程池接收的请求数
     listen queue 等待队列的请求数
     max listen queue 自启动以来等待队列中最大的请求数
     listen queue len 等待连接socket队列大小
     idle processes 当前空闲的进程数
     active processes 活动的进程数
     total processes 总共的进程数(idle+active)
     max active processes 自启动以来活动的进程数最大值
     max children reached 达到最大进程数的次数

9)ping.path
ping url,可以用来测试php-fpm是否存活并可以响应
ping.path = /ping

10)ping.response
ping url的响应正文返回为 HTTP 200 的 text/plain 格式文本. 默认值: pong.
ping.response = pong


11)pid = run/php-fpm.pid
#pid设置,默认在安装目录中的var/run/php-fpm.pid,建议开启
 
12)error_log = log/php-fpm.log
#错误日志,默认在安装目录中的var/log/php-fpm.log
 
13)log_level = notice
#错误级别. 可用级别为: alert(必须立即处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice.
 
14)emergency_restart_threshold = 60
emergency_restart_interval = 60s
#表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启。这两个选项一般保持默认值。
 
15)process_control_timeout = 0
#设置子进程接受主进程复用信号的超时时间. 可用单位: s(秒), m(分), h(小时), 或者 d(天) 默认单位: s(秒). 默认值: 0.
 
16)daemonize = yes
#后台执行fpm,默认值为yes,如果为了调试可以改为no。在FPM中,可以使用不同的设置来运行多个进程池。 这些设置可以针对每个进程池单独设置。
 
17)listen = 127.0.0.1:9000
#fpm监听端口,即nginx中php处理的地址,一般默认值即可。可用格式为: 'ip:port', 'port', '/path/to/unix/socket'. 每个进程池都需要设置.
 
18)listen.backlog = -1
#backlog数,-1表示无限制,由操作系统决定,此行注释掉就行。 19)listen.allowed_clients = 127.0.0.1
#允许访问FastCGI进程的IP,设置any为不限制IP,如果要设置其他主机的nginx也能访问这台FPM进程,listen处要设置成本地可被访问的IP。
默认值是any。每个地址是用逗号分隔. 如果没有设置或者为空,则允许任何服务器请求连接


20)#unix socket设置选项,如果使用tcp方式访问,这里注释即可。
listen.owner = www
listen.group = www
listen.mode = 0666
#启动进程的帐户和组
user = www
group = www
21)request_terminate_timeout = 0 #设置单个请求的超时中止时间. 
该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用. 设置为 '0' 表示 'Off'.当经常出现502错误时可以尝试更改此选项。 

22)request_slowlog_timeout = 10s #当一个请求该设置的超时时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中. 设置为 '0' 表示 'Off' 

23)slowlog = log/$pool.log.slow #慢请求的记录日志,配合request_slowlog_timeout使用 

24)rlimit_files = 1024 #设置文件打开描述符的rlimit限制. 默认值: 系统定义值默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。 

25)rlimit_core = 0 #设置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整数. 默认值: 系统定义值. 

26)chroot = #启动时的Chroot目录. 所定义的目录需要是绝对路径. 如果没有设置, 则chroot不被使用. 

27)chdir = #设置启动目录,启动时会自动Chdir到该目录. 所定义的目录需要是绝对路径. 默认值: 当前目录,或者/目录(chroot时) 

28)catch_workers_output = yes #重定向运行过程中的stdout和stderr到主要的错误日志文件中. 
如果没有设置, stdout 和 stderr 将会根据FastCGI的规则被重定向到 /dev/null . 
默认值: 空. 

二、php对子进程的三种管理方式
static:
表示在php-fpm运行时直接fork出 pm.max_chindren个子进程
dynamic:
表示,运行时fork出pm.start_servers个进程,随着负载的情况,动态的调整,最多不超过pm.max_children个进程。同时,保证闲置进程数不少于pm.min_spare_servers数量,否则新的进程会被创建,当然也不是无限制的创建,最多闲置进程不超过pm.max_spare_servers数量,超过则一些闲置进程被清理。
ondemand: 
当有请求时,创建进程,启动不创建,最多不超过pm.max_chindren进程数,当进程闲置会在pm.process_idle_timeout秒后被及时释放。


三、重要参数的理解与设置

 

【重要一】
request_terminate_timeout = 120
#表示等待120秒后,结束那些没有自动结束的php脚本,以释放占用的资源。
当PHP运行在php-fpm模式下,php.ini配置的max_execute_time是无效的,
需要在php-fpm.conf中配置另外一个配置项:request_terminate_timeout;以下是官方文档的说明:


set_time_limit()和max_execution_time只影响脚本本身执行的时间。
(这两个参数在php.ini中)任何发生在诸如使用system()的系统调用,流操作,数据库操作等的脚本执行的最大时间不包括其中.
还可以是以下情况:
参考:http://zyan.cc/tags/request_terminate_timeout/1/
  1. $ctx = stream_context_create(array(  
  2.    ‘http’ => array(  
  3.        ‘timeout’ => 1 //设置一个超时时间,单位为秒  
  4.        )
  5.    )
  6. );
  7. file_get_contents(“http://example.com/”, 0, $ctx);  //设置超时时间


下面4个参数的意思分别为:
pm.max_children:静态方式下开启的php-fpm进程数量。
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式下的最小php-fpm进程数量。
pm.max_spare_servers:动态方式下的最大php-fpm进程数量。

如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。
如果dm设置为 dynamic,那么pm.max_children参数失效,后面3个参数生效。 
系统会在php-fpm运行开始 的时候启动pm.start_servers个php-fpm进程,
然后根据系统的需求动态在pm.min_spare_servers和 pm.max_spare_servers之间调整php-fpm进程数。

比如说512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服 
务器的负载情况来设置,比较合适的值在5~10之间。


pm = dynamic模式非常灵活,也通常是默认的选项。
但是,dynamic模式为了最大化地优化服务器响应,会造成更多内存使用,因为这种模式只会杀掉超出最大闲置进程数(pm.max_spare_servers)的闲置进程,
比如最大闲置进程数是30,然后网站经历了一次访问高峰,高峰期时共动态开启了50个进程全部忙碌,0个闲置进程数,
接着过了高峰期,可能没有一个请求,于是会有50个闲置进程,但是此时php-fpm只会杀掉20个子进程,
始终剩下30个进程继续作为闲置进程来等待请求,这可能就是为什么过了高峰期后即便请求数大量减少服务器内存使用却也没有大量减少,
也可能是为什么有些时候重启下服务器情况就会好很多,因为重启后,php-fpm

本文来自网络:http://www.cnblogs.com/300js/p/5920124.html

避免PHP-FPM内存泄漏导致内存耗尽

对于PHP-FPM多进程的模式,想要避免内存泄漏问题很简单,就是要让PHP-CGI在处理一定数量进程后退出即可。
否则PHP程序或第三方模块(如Imagemagick扩展)导致的内存泄漏问题会导致内存耗尽或不足。
php-fpm.conf中有相关配置:
#请自行按需求配置

pm.max_requests = 1024

实际上还有另一个跟它有关联的值max_children,这个是每次php-fpm会建立多少个进程,这样实际上的内存消耗是max_children*max_requests*每个请求使用内存。

另外一些粗暴的方法包括建立cron kill掉占用内存过多的php-cgi,

1.检查php进程的内存占用,杀掉内存使用超额的进程

一般情况下,如果php-cgi进程占用超过1%的内存,就得考虑一下是否要杀掉它了。因为普通情况下,php-cgi进程一般占用0.2%或以下。

这里提供一个脚本供各位使用,就是放在cron任务里,每分钟执行一次。

使用crontab -e 命令,然后添加如下调度任务

* * * * * /bin/bash /usr/local/script/kill_php_cgi.sh

kill_php_cgi.sh脚本如下

#!/bin/sh
#如果是要杀掉php-fpm的进程,下面的语句中php-cgi请改成php-fpm
pids=`ps -ef|grep php-cgi|grep -v “grep”|grep -v “$0″| awk ‘{print $2}’`
if [ “$pids” != “” ];then
for  pid  in   $pids;
do
kill -9 $pid
done

fi

2.增加内存,将PHP_FCGI_MAX_REQUESTS的值设置成跟你内存总存储量相对应的值

3.优化程序,降低处理每次请求占用的内存大小

如果PHP-FPM能够提供配置子进程内存超过指定大小就被kill,那就省事多了

以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索内存 , 程序 , 进程 , 内存泄漏 , 配置 php-fpm php fpm内存泄漏、如何避免内存泄漏、c 避免内存泄漏、避免内存泄漏、信息泄漏可导致,以便于您获取更多的相关知识。

本文转自网络  https://yq.aliyun.com/ziliao/9107

CentOS7 linux下yum安装redis以及使用

 一、安装redis

1、下载fedora的epel仓库

1
yum install epel-release

2、安装redis数据库

1
yum install redis

3、安装完毕后,使用下面的命令启动redis服务

1
2
3
4
5
6
7
8
# 启动redis
service redis start
# 停止redis
service redis stop
# 查看redis运行状态
service redis status
# 查看redis进程
ps -ef | grep redis

5、设置redis为开机自动启动

1
chkconfig redis on  或 systemctl enable redis.service

6、进入redis服务

1
2
3
4
# 进入本机redis
redis-cli
# 列出所有key
keys *

7、防火墙开放相应端口

1
2
3
4
5
6
7
8
# 开启6379
/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT
# 开启6380
/sbin/iptables -I INPUT -p tcp --dport 6380 -j ACCEPT
# 保存
/etc/rc.d/init.d/iptables save
# centos 7下执行
service iptables save

二、修改redis默认端口和密码

1、打开配置文件

1
vi /etc/redis.conf

2、修改默认端口,查找 port 6379 修改为相应端口即可

3、修改默认密码,查找 requirepass foobared 将 foobared 修改为你的密码

4、使用配置文件启动 redis

1
redis-server /etc/redis.conf &

5、使用端口登录

1
redis-cli -h 127.0.0.1 -p 6179

6、此时再输入命令则会报错

7、输入刚才输入的密码

1
auth 111

8、停止redis

命令方式关闭redis

1
2
redis-cli -h 127.0.0.1 -p 6179
shutdown

进程号杀掉redis

1
2
ps -ef | grep redis
kill -9 XXX

三、使用redis desktop manager远程连接redis

1、访问如下网址下载redis desktop manager

1
2
<a href="https://redisdesktop.com/download" target="_blank">https://redisdesktop.com/download
</a>

2、安装后启动,新建一个连接

3、填写如下信息后点击“Test Connection”测试是否连接成功

4、如果长时间连接不上,可能有两种可能性

a)bind了127.0.01:只允许在本机连接redis

b)protected-mode设置了yes(使用redis desktop manager工具需要配置,其余不用)

解决办法:

1
2
3
4
5
# 打开redis配置文件
vi /etc/redis.conf
# 找到 bind 127.0.0.1 将其注释
# 找到 protected-mode yes 将其改为
protected-mode no

5、重启redis

1
2
service redis stop
service redis start

6、再次连接即可

 

参考:

https://www.cnblogs.com/wiseroll/p/7061673.html

http://blog.csdn.net/gebitan505/article/details/54602662

http://blog.csdn.net/lh2420124680/article/details/75426144

 

本文转发自:https://www.cnblogs.com/rslai/p/8249812.html

session的垃圾回收机制

session.gc_maxlifetime

session.gc_probability

session.gc_divisor

session.gc_divisor 与 session.gc_probability 合起来定义了在每个会话初始化时启动 gc(garbage collection 垃圾回收)进程的概率。此概率用 gc_probability/gc_divisor 计算得来。例如 1/100 意味着在每个请求中有 1% 的概率启动 gc 进程。session.gc_divisor 默认为 100。

比如:session.gc_maxlifetime=30,session.gc_divisor=1000,session.gc_probability=1,就表示每一千个用户调用session_start()的时候,就百分百的会执行一次垃圾回收机制,将磁盘上没用的session文件删除。

注意:一般对于一些大型的门户网站,建议将session.gc_divisor调大一点,减少开销

接下来,我通过一个例子演示下,如何配置才能让调用gc(垃圾回收)进程呢!

通过配置php.ini文件,修改以下几个信息:

  1. session.gc_maxlifetime = 60//当session文件在60s后还没有被访问的话,则该session文件将会被视为“垃圾文件”,并且等待gc(垃圾回收)进程的调用的时候被清理掉
  2. session.gc_probability = 1000

因为gc进程被调用的概率是通过gc_probability/gc_divisor 计算得来的,这里我将session.gc_probability改成1000,而session.gc_divisor 默认情况下也是1000。则gc进程在每次执行session_start()函数的时候都会被调用到。

以下我通过截图简单的说明下:

我开启三个会话,则创建三个对应的session文件,当每个文件在30秒内都没被调用的话,就会被当成是“垃圾文件”,等到gc进程调用的时候,“垃圾文件”就会被unlink,因为之前我已经通过修改php.ini配置文件,将gc被调用的概率改成百分百,所以接下来,如果我重新使用任何一个浏览器刷新下页面的时候,三个session文件,应该只剩下一个了

本文转自网络 https://www.cnblogs.com/hongfei/archive/2012/06/17/2552434.html

Access-Control-Allow-Origin跨域访问

PHP 设置跨域访问:

header("Access-Control-Allow-Origin:http://api.maxianwei.cn");

允许api.maxianwei.cn访问 ,那么要允许所有域名访问呢:

header("Access-Control-Allow-Origin:*");

要设置多个域名呢? Access-Control-Allow-Origin 只能设置一个域名 用逗号或其他连接符合是不行的,其实只要判断请求来源域名是不是自己允许的,然后设置即可代码如下:

$orginAllows = ['http://api.maxianwei.cn','http://api2.maxianwei.cn'];
$referOrgin = $_SERVER['HTTP_REFERER'];
$pattern = '/(http[s]{0,1}:\/\/[^\/]*)\/.*/';
preg_match($pattern, $referOrgin, $match);
$refer = $match[1];
if(in_array($refer,$orginAllows)){
   header("Access-Control-Allow-Origin:{$refer}");
}

PHP 将大量数据导出到 Excel 的方法一

数据量很大时(5万条以上),用 PHPExcel 导出 xls 将十分缓慢且占用很大内存,最终造成运行超时或内存不足。

set_time_limit(0);
ini_set(“memory_limit”,”512M”);

可以通过设置 PHP 的运行时间和内存限制来阻止错误发生,但仍然不能确保导出完成。

<?php
// 不限制脚本执行时间以确保导出完成
set_time_limit(0);
// 输出Excel文件头,可把user.csv换成你要的文件名
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="amazon_product_quantity.csv"');
header('Cache-Control: max-age=0');
 
// 从数据库中获取数据,为了节省内存,不要把数据一次性读到内存,从句柄中一行一行读即可
$sql = 'select * from amazon_product_quantity';
$stmt = mysql_query($sql);
 
// 打开PHP文件句柄,php://output 表示直接输出到浏览器
$fp = fopen('php://output', 'a');
 
// 输出Excel列名信息
$head = array('code', 'sub_code', 'sp_code', 'quantity');
foreach ($head as $i => $v) {
 // CSV的Excel支持GBK编码,一定要转换,否则乱码
 $head[$i] = iconv('utf-8', 'gb2312', $v);
}
 
// 将数据通过fputcsv写到文件句柄
fputcsv($fp, $head);
 
// 计数器
$cnt = 0;
// 每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
$limit = 100000;
 
// 逐行取出数据,不浪费内存
while ($row = mysql_fetch_array($stmt,MYSQL_ASSOC)) {
 $cnt ++;
 if ($limit == $cnt) { //刷新一下输出buffer,防止由于数据过多造成问题
 ob_flush();
 flush();
 $cnt = 0;
 }
 
 foreach ($row as $i => $v) {
 $row[$i] = iconv('utf-8', 'gb2312', $v);
 }
 fputcsv($fp, $row); 
}
?>