开发中遇到的gzuncompress,DomDocument等几个小问题以及一次Php上线碰到的502问题及php异常追踪
一、开发中遇到的gzuncompress,DomDocument等几个小问题记在此
1,昨天在命令行模式行运行一个很复杂的程序,一开始执行php,刚刚连接数据库,都没怎么查几条记录,(publish:October 27, 2017 -Friday) 就报错:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in..。
一开始看到这报错,还真是一头雾水,因为我这个程序正常运行出现内存溢出是完全可能的,因为会进行百万级的数据库查询,并且要生成几百M的数据文件出来,但目前我只是在调试程序,暂时还不应该出现这种报错啊。
然后再一看不对啊,报错提示允许内存128M,我这才申请多大点内存,怎么报错呢。使用php --ini 查看所使用的ini文件位置,才发现php才刚安装,php.ini文件都还没有,然后将此文件配置好,再次执行,果然正常。看来如果没有php.ini文件,php命令行下执行命令的默认内存申请限制是20480 bytes(即2M).
2、在使用gzuncompress时碰到报错。Warning: gzuncompress(): insufficient memory这也真是个诱惑的问题,php的压缩内容方法第二个参数是表示压缩等级,从0-9,0表示不压缩,9为最高压缩,而gzuncompress第二个参数也是个整数,一不小心就把这两个方法的第二个参数整到一起去了,以为是以哪个等级压缩,就要以哪个等级解压缩。
原来gzuncompress的第二个参数根本不是压缩等级,而是解压出来的字符串长度限制。
string gzcompress ( string $data [, int $level = -1 [, int $encoding = ZLIB_ENCODING_DEFLATE ]] )
string gzuncompress ( string $data [, int $length = 0 ] )
3、今天考虑将一个较大的数据存储至redis, 最后一算这些字符内容整个大小400多M,于是看了一下redis单个key的最大值限制,发现其要求在512M以下,A String value can be at max 512 Megabytes in length.虽然目前我的数据没有超过这个数,但是因为数据还会增长,后期超过的可能性很大,另外即便不会超过,也不能一直打着擦边球运行啊。于是考虑使用压缩。这也就是上面遇到gzuncompress问题的原因了。
php内容的压缩也考虑过其它的方法,比如之前一直用的msg_pack。但是这次使用msg_pack很意外,不知道为什么,压缩后的文件大小既然和压缩前一样,看了几遍代码觉得非常不可思议,但也没发出代码上的问题。我压缩的是个超长的XML内容,不知道是否与这有关。另外关于gzcompress的压缩率,我这压缩前的数据文件大小在480M,压缩后80来M。压缩率达到了6分之一。在我这个业务里完全满意这个效果。
4、处理xml的php类DomDocument在操作添加添加元素时,元素名称不能是以数字开头,比如:
$Xmlmake = new DomDocument('1.0', 'utf-8');
$sphinxXml = $Xmlmake->createElement('3g'); #此项会报错
另外xml元素创建节点值时,xml本身会对一些特殊字符作转义处理,比如<>符号,因为它会打乱xml的结构,所以如果你的值中有html元素,而又不想它转义,可以区分使用如下方法。
$text = $Xmlmake->createCDATASection($value); #如果值里面可能有特殊字符,使用createCDATASection,会自动将值处理成:<![CDATA[数据值]]>
$text = $Xmlmake->createTextNode($value);如果字段值都是一些明确没有特殊字符的值这样即可。
最后的前一篇文章里有提到类DomDocument在输出xml字符串时,默认是不带有缩进的,可以设置类的属性formatOutput为true.从而使生成的xml文件自动缩进。方便查阅。
二、一次上线碰到的502问题及php异常追踪
今天在上线时遇到了一些502报错,但并非大量,在上线后的几分钟里报了个几十条,程序中已经使用了register_shutdown_function方法捕获最终的异常并进行报错记录,但这次发生502时,PHP程序根本未记录任何错误。publish:December 26, 2017 -Tuesday 查看web里的nginx报错日志如下:
2017/12/26 17:03:00 [error] 11589#0: *202518654 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 192.168.168.164, server: 04007.cn, request: "GET /search/AF04A6B6C9B45D9624514 HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "fangha.com"
主要的报错日志:Connection reset by peer) while reading response header from upstream 表示php执行时间较长,并超出php-fpm.conf的request_terminate_timeout设置的秒数。但此处没有更详细的日志了。request_terminate_timeout用于设置当某个php脚本运行最长时间,若超出php-fpm进程管理器强行中止当前程序,并关闭fastcgi和nginx的网络连接,然后nginx中就会出现Connection reset by peer的错误了。
【建议】为了更详情地掌握nginx运行异常,建议在nginx的全局配置中将日志级别记入notice。这样可以记录nginx的详细异常信息。如下:
error_log logs/error.log notice;
查看PHP.ini中配置的php日志:error_log = /opt/data/logs/php/php_errors.log
[26-Dec-2017 19:30:29 PRC] PHP Warning: Invalid argument supplied for foreach() in /opt/fangha.com/revs/r20171226_1821/app/controller/aController.php on line 1428
发现一条warning日志,但从报错来看这条日志并非致命日志,可以忽略这条日志。
查看php-fpm的日志:; Default Value: log/php-fpm.log;error_log = log/php-fpm.log 发现在这次上线后出现一些php进程出现重启,看来正是php进行执行时间过长超时,导致php重启,进而最终体现在proxy上记录的502错误。但诡异的是WEB上并没有记录任何错误日志。
[26-Dec-2017 16:54:44] WARNING: [pool www] child 25560 exited with code 1 after 100614.838080 seconds from start [26-Dec-2017 16:54:44] NOTICE: [pool www] child 5894 started [26-Dec-2017 16:54:47] WARNING: [pool www] child 25603 exited with code 1 after 100618.063972 seconds from start [26-Dec-2017 16:54:47] NOTICE: [pool www] child 5895 started
此时感觉没法查了,能查的日志都查了,只知道这次上线的东西导致了部分请求过慢,但出异常的量却很少。所以:
【建议】开启fpm的slowlog,及时发现性能问题:
request_slowlog_timeout = 2s #执行时间超过2秒,则进行记录日志
slowlog = var/log/slow.log
request_terminate_timeout = 10s #执行时间不能超过这个值
幸运的是,上线出异常后,我一直tail -f 错误日志目录里的所有日志文件,期间发现一个日志文件一直在出现提示(被改变),即这个日志文件一直被其它的进程在修改,立即引起了我的注意,因为它很熟悉,我拿着这个文件名在程序里查找,发现我这次调用的日志生成方法是非追加写append,我便开始怀疑和此项有关。
因为我上线的时候有一个数据缓存文件是不存在的,上线之后才会陆续生成一个缓存文件,文件不存在并不会导致文件异常,但是文件不存在我会记录一个日志,此处不小心用了一个debug(需要覆盖写)的日志写入方法,我想应该是这里的问题导致很多php进程在等待写入最终造成一些php进程执行超时。万幸的是缓存文件很快生成,所以报的错很少,否则一定是一个恶性循环导致更大的问题。
除了查看日志外,linux也可以使用命令:strace -p 来追踪线程的执行过程,来排查php执行到了哪一步而出现了意外停止。如下为strace -p的执行日志:
[www@B4471 ~]$ ps -ef | grep php
root 10984 1 0 19:13 ? 00:00:00 php-fpm: master process (/opt/soft/php7/etc/php-fpm.conf)
www 10985 10984 0 19:13 ? 00:00:00 php-fpm: pool www
www 10986 10984 0 19:13 ? 00:00:00 php-fpm: pool www
[www@B4471 ~]$ strace -p 10985
......
access("/oasher.php", F_OK) = 0
access("/oprface.php", F_OK) = 0
poll([{fd=7, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
setsockopt(7, SOL_TCP, TCP_NODELAY, [1], 4) = 0
poll([{fd=7, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
sendto(7, "*2\r\n$3\r\nGET\r\n$25\r\npages_android_"..., 45, MSG_DONTWAIT, NULL, 0) = 45
poll([{fd=7, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
poll([{fd=7, events=POLLIN|POLLERR|POLLHUP}], 1, 5000000) = 1 ([{fd=7, revents=POLLIN}])
recvfrom(7, "$7408\r\n\235\207\242id\2411\246pageid\2411\245title\246\347\262"..., 8192, MSG_DONTWAIT, NULL, NULL) = 1448
poll([{fd=7, events=POLLIN|POLLERR|POLLHUP}], 1, 5000000) = 1 ([{fd=7, revents=POLLIN}])
recvfrom(7, "\203\255\241c\201\246\346\234\200\346\226\260\241u\201\246\350\257\204\345\210\206\241s\243pay\223\201\246\345"..., 8192, MSG_DONTWAIT, NULL, NULL) = 5969
write(4, "\1\6\0\1\37\370\0\0X-Powered-By: PHP/7.0.10"..., 8192) = 8192
chdir("/o821/www") = 0
times({tms_utime=16, tms_stime=3, tms_cutime=0, tms_cstime=0}) = 3013606966
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
fcntl(3, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}) = 0
write(4, "\1\6\0\1\24\10\0\0\\u6b27\\u7f8e\\u795e\\u5267"..., 5152) = 5152
shutdown(4, SHUT_WR) = 0
recvfrom(4, "\1\5\0\1\0\0\0\0", 8, 0, NULL, NULL) = 8
recvfrom(4, "", 8, 0, NULL, NULL) = 0
close(4) = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
accept(0,
相关文章:
开发中遇到的gzuncompress,DomDocument等几个小问题以及一次Php上线碰到的502问题及php异常追踪
一、开发中遇到的gzuncompress,DomDocument等几个小问题记在此 1,昨天在命令行模式行运行一个很复杂的程序,一开始执行php,刚刚连接数据库,都没怎么查几条记录,(publish:October 27, 2017 -Fridayÿ…...

【Material-UI】Button 组件中的基本按钮详解
文章目录 一、基本按钮变体1. 文本按钮(Text Button)2. 实心按钮(Contained Button)3. 轮廓按钮(Outlined Button) 二、应用场景与注意事项1. 使用场景2. 注意事项 三、总结 Material-UI 的 Button 组件是前…...

人工智能自动驾驶三维车道线检测—PersFormer模型代码详解
文章目录 1. 背景介绍2. 数据加载和预处理3. 模型结构4. Loss计算5. 总结和讨论 1. 背景介绍 梳理了PersFormer 3D Lane这篇论文对应的开源代码。 2. 数据加载和预处理 数据组织方式参考:自动驾驶三维车道线检测系列—OpenLane数据集介绍。 坐标系参考ÿ…...

LangChain +Streamlit+ Llama :将对话式人工智能引入您的本地设备成为可能(上篇)
🦜️ LangChain Streamlit🔥 Llama 🦙:将对话式人工智能引入您的本地设备🤯 将开源LLMs和LangChain集成以进行免费生成式问答(不需要API密钥) 在过去的几个月中,大型语言模型(LLMs)得…...

sql注入部分总结和复现
一个端口对应一个服务 联合查询注入 所有的程序中,单双引号必须成对出现 需要从这个引号里面逃出来 在后面查询内容 ?id1 要查库名,表名,列名。但是联合查询要知道有多少列,所以通过order by 去查询 order by # 通过二分法…...

开源企业级后台管理的快速启动引擎:Ballcat
Ballcat:快速搭建,高效管理,Ballcat让企业后台开发更简单。 - 精选真开源,释放新价值。 概览 Ballcat,一个专为企业级后台管理而设计的快速开发框架,以其高效的开发模式和全面的安全特性,为开发…...

FashionAI比赛-服饰属性标签识别比赛赛后总结(来自 Top14 Team)
关联比赛: FashionAI全球挑战赛—服饰属性标签识别 推荐大家看本篇博客之前,看一下数据集制作的方法,如何做一个实用的图像数据集 PS:我是参加完比赛之后才看的,看完之后,万马奔腾.....,因为发现比赛中还…...

C语言 | Leetcode C语言题解之第319题灯泡开关
题目: 题解: int bulbSwitch(int n) {return sqrt(n 0.5); }...

【第十届泰迪杯数据挖掘挑战赛A题害虫识别】-农田害虫检测识别-高精度完整更新
农田害虫检测识别项目-高精度完整版 一、说明: 该版本为基于泰迪杯完整害虫数据重新制作数据集、优化增强数据集、重新进行模型训练,达到高精度、高召回率的最优模型代码。包含论文、最优模型文件以及相关文件、原始数据集、训练数据集XML版、增强扩充…...

【Linux】—— Linux进程状态(R、S、D、T、Z、X)
🌏博客主页:PH_modest的博客主页 🚩当前专栏:Linux跬步积累 💌其他专栏: 🔴 每日一题 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮࿰…...
重生之我在NestJS中使用EventStream
有一个需求是需要长连接等待后台的返回,我们使用的EventStream,在NestJS中使用很简单,框架基本上已经封装好了 0. 如果没有创建项目的,可以先创建一个项目,创建项目的直接跳转到下一个步骤去 全局安装 nest: npm inst…...

自动化工具Selenium IDE基本使用——脚本录制
1 简介 Selenium相信大家都知道,在做自动化操作时,要使用浏览器驱动直接控制浏览器操作的时候,大多会结合Selenium框架使用。 但在对网页操作自动化的时候,实际上有一种更轻量的做法,那就是直接使用Selenium IDE&…...
【第十一天】进程调度算法,进程间通信方式,进程同步和互斥
进程调度算法有哪些 进程调度算法是操作系统中用来管理和调度进程(任务,作业)执行的方法。这些方法决定了在多任务环境下,如何为各个进程分配CPU时间,以实现公平性、高吞吐量、低延迟等目标。 先到先服务调度算法&am…...
Python的lambda函数
Python中的lambda函数是一种小型匿名函数,它允许你在需要函数对象的地方快速定义单行的小函数。lambda函数通常用于编写简洁的代码,尤其是当使用高阶函数(如map()、filter()、reduce()等)时。它们可以接收任何数量的参数ÿ…...
java9-泛型
1.泛型的简介 1.1 什么是泛型 泛型是一种特殊的数据类型。 它是Java 的一个高级特性。在 Mybatis、Hibernate 这种持久化框架,泛型更是无处不在。 在这之前,不管我们在定义成员变量时,还是方法的形参时,都要规定他们的具体类型…...

zotero安装与使用
文献管理工具) Zotero软件官网https://www.zotero.org/download,不修改安装位置,默认安装就行;安装完成官网直接邮箱注册一个账号,软件登陆账号:编辑-首选项-同步 修改论文保存位置,有从其它电脑拷贝过来的…...

Elasticsearch未授权访问漏洞
7.Elasticsearch未授权访问漏洞 Elasticsearch服务普遍存在一个未授权访问的问题,攻击者通常可以请求一个开放9200或9300的服务器进行恶意攻击。 步骤一:使用以下Fofa语法进行Elasticsearch产品搜索 "Elasticsearch" && port"9200" …...
【FPGA】module中CLOCK RESET iCall oDone的含义
一般的module并不只有iData和oData,还有其他的控制信号,如CLOCK RESET iCall oDone 基本的模式为 module cordicSinhCosh (input CLOCK,RESET,input iCall, output oDone,input [31:0]iData, output [31:0]oData, );reg [31:0] x;initial begin x = ...endreg signed [31:…...

OpenGL实现3D游戏编程【连载2】——了解并创建3D空间模型
1、本节实现的内容 上一节我们创建一个简单的窗口,本节我们需要了解一下细节内容,同时为了方便观看,我们需要显示一个世界坐标轴,建立一个直观的三维空间。 2、我们的眼睛设定(gluPerspective函数) 上一…...

Java-文件操作和IO
文件介绍 文件本身有多重含义,狭义的文件,特指硬盘上的文件(以及保存文件的目录),广义的文件:计算机上的很多硬件设备,软件资源,在操作系统中,都会被视为是"文件" 文件除了有数据内容之外,还有一部分信息,例如文件名,文件类型,文件大小,这些信息可以称作文件的元信…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...