记录一次解决PHP返回数据被nginx截断的问题
2017-08-01 02:05
531 查看
前言
今日,发生了一件懵逼的事情,通过内部接口获取数据的时候,概率性出现返回的数据被截断的问题。内部接口好好的为何突然出现问题了?此文将记录这次本应该很快解决却没有很快解决的过程。正文
背景
内部接口分为5+3=8台机器,为什么这么说呢,5台是一直有的,而3台是刚新增的,问题就出在了这三台,由于负载均衡策略所以出现在前文说到的概率性出现返回的数据被截断的问题。一般开发是没有机器权限的,在不申请临时机器权限的情况下。解决速度完全取决于运维,无果。
发现过程
1.先是四处埋点记日志,确认原因是日志被截断了。2.由于无线上机器权限所以只好通过跳板机到拟真环境进行
curl -H 'Host:internal.xxx.com' '192.168.xx.xx/data/get_list.json?xxx=xxx'
操作来定位哪台机器出问题了。
是的,8台机器都试过去发现,真的是新增的3台有问题。
3.进一步确认机器上nginx的error日志报错了一堆:
2016/06/07 00:41:28 [crit] 32763#0: *5439 open() "/usr/local/nginx/fastcgi_temp/5/02/0000000025" failed (13: Permission denied) while reading upstream, client: 203.171.237.2, server: internal.xxx.com, request: "GET /xxx/xxx.json HTTP/1.0", upstream: "f astcgi://127.0.0.1:9000",...
好了,到现在基本可以得出结论是nginx导致的。
分析截断产生原因
看报错显示是fastcgi_temp的写入没权限?有点懵逼,这个和fastcgi_temp什么关系?
经过查资料得到:
原来nginx存在一个buffer的机制,数据过大超出缓冲区的最大容量,会将数据写入临时文件时(fastcgi_temp目录下),而此时又没有权限,所以再返回时,超出缓冲区的数据将丢失,就出现了截断。
解决办法
先是查询nginx的配置user www //此处的意思是nginx 使用root 的权限,解决问题1 head{ fastcgi_buffers 4 64k;//此处值代表nginx 设置 4个 32k 的块进行缓存,总共大小为4*64k fastcgi_buffer_size 64k;//磁珠值代表每块大小 }
给fastcgi_temp 目录赋读写权限
sudo chown -R www:root fastcgi_temp chmod -R 764 /usr/local/nginx/fastcgi_temp/
nginx的buffer机制
对于来自 FastCGI Server 的 Response,Nginx 将其缓冲到内存中,然后依次发送到客户端浏览器。缓冲区的大小由 fastcgi_buffers 和 fastcgi_buffer_size 两个值控制。比如如下配置:
fastcgi_buffers 4 64k; fastcgi_buffer_size 64K;
fastcgi_buffer_size : 用于指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers选项指定的缓冲区大小。
fastcgi_buffers : 指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求。如果一个PHP脚本所产生的页面大小为256KB,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于硬盘。一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“16 16k”、“4 64k”等。
所以总计能创建的最大内存缓冲区大小是 4*64K+64K = 320k。而这些缓冲区是根据实际的 Response 大小动态生成的,并不是一次性创建的。比如一个 128K 的页面,Nginx 会创建 2*64K 共 2 个 buffers。
当 Response 小于等于 320k 时,所有数据当然全部在内存中处理。如果 Response 大于 320k 呢?fastcgi_temp 的作用就在于此。多出来的数据会被临时写入到文件中,放在这个目录下面。
内存中缓冲了 320K,剩下的会写入的文件中。而实际的情况是,运行 Nginx Process 的用户并没有 fastcgi_temp 目录的写权限,于是剩下的数据就丢失掉了。
相关文章推荐
- PHP返回数据被nginx截断问题的解决方法
- nginx +phpfastcgi 环境下 导出excel文件,超时,数据被截断问题,解决
- nginx下运行php的程序时返回200访问却是空白页问题的解决方法
- 解决nginx在记录post数据时 中文字符转成16进制的问题【转载】
- 记录一次java ssm框架下数据回滚问题以及解决方法
- ubuntu nginx php mysql 网站架设过程中遇到问题的解决记录
- 解决一次由于SSL证书到期导致的网站不能访问的问题(Nginx,php,Apache)
- PHP返回内容过长时被nginx截断的解决办法
- nginx下运行php的程序时返回200访问却是空白页问题的解决方法
- 记录一次powercenter数据抽取问题解决
- SQLSERVER 占了500多M内存,原来的程序无法一次查询出50多W数据了,记录下这个问题的解决过程。
- nginx下运行php的程序时返回200访问却是空白页问题的解决方法
- Mybatis 查询int类型数据,返回记录条数为0时报错问题解决
- 关于CListCtrl控件更新Item的闪烁问题和一次插入大容量数据的显示问题解决办法
- 如何解决ACCESS中SELECT TOP语句竟然返回多条记录的问题?
- MSSQL 将截断字符串或二进制数据问题的解决方法
- linq to sql统一更新方法,直接返回更新的对象(解决更新后再刷新数据错误显示问题)
- Nginx下alias支持PHP的问题解决
- 解决服务器返回JSON数据中文乱码问题
- php 调用webservice ,返回数据 中文乱码问题