一介闲人
一介闲人
先描述下事故发生,刚开始访问网页出现访问卡顿,访问速度慢,接口还会出现返回502现象,初步排查,以为是并发过高触发了限流机制。 过一段时间,负载均衡提示某台服务器的https转发异常,检查Apache服务,服务正常且没有假死线程。本地访问网站正常,重启Apache服务后,负载均衡转发正常。 再过一段时间,前端反馈网站页面访问提示NGINX错误,该错误是负载均衡没找到可转发服务直接报错,但是负载均衡心跳检查提示服务正常。 此时陷入了困境 服务器本地访问127.0.0.1 也开始大部分出现访问异常,偶尔能访问。 现象总结:网站开始出现卡顿,负载均衡部分转发异常,页面偶尔可以访问,但大部分无法访问。查看Apache的error.log日志,提示很多[warn] (OS 64)指定的网络名不再可用。 : winnt_accept: Asynchronous AcceptEx failed.
经查询,是PHP的session缓存文件过多,导致缓存文件写入失败,正常情况,缓存文件都有过期机制,会自动删除。但是由于并发增高,Apache性能到达瓶颈,Apache频繁重启,导致删除缓存文件失败,缓存文件达到60万后开始出现卡顿,达到100万后开始出现访问失败,达到120万将拒绝所有访问。
针对以上原因可以尝试使用一下方法解决: 1、找到Apache中配置的PHP安装目录(如果知道PHP的安装目录,这步可以跳过) 进去Apache的安装目录,进入conf文件夹,打开httpd.conf配置文件,搜索“PHPIniDir”,找到PHP的安装目录。 2、找到PHP的缓存文件目录 进入PHP安装目录,打开php.ini文件,搜索“session.save_path”,没有注释的配置参数的目录就是缓存文件存放目录,把这个目标更换到其他空文件夹下,保存即可。观察新的缓存文件夹,如果长时间没有缓存文件写入,重启Apache服务。 如果在php.ini中的session.save_path都在注释里面,即没有配置这个参数,则默认在C盘》window文件夹》Temp文件夹下。在php.ini中加上 session.save_path=“你的缓存文件存放目录”即可。 php.ini中注释是在注释行开头加 英文分号(; ) 3、删除原有的已经阻塞的文件夹
该方法可能导致session过期后无法自动删除 修改php.ini中的session.save_path = "2;/tmp/session",其中2表示2层级离散,以 [ sess_00a13rniiiidq4o7kig6fe0b06 ] 这个缓存文件为例,其存储路径为/temp/session/0/0; 由于PHP不会自动创建散列目录,所以需要提前手动创建,创建维度为0~9,a~z。
该方法对window系统不友善。 在cron定时任务中添加 [ find /tmp/session -amin +180 -exec rm -rf {} ; ]这个任务; 任务说明:1小时清理1次,清理3小时以前的缓存文件。 注:该方法不能完全解决问题,若session缓存文件过快,还是有可能导致同样的问题。 window系统下,写bat执行删除任务,或者写程序进行定时删除,由于文件比较多,一次性加载到内存再删除比较耗性能,所以建议采用逐文件删除,虽然速度稍慢。
Path pa = Paths.get( path ); // path是缓存文件目录
try {
DirectoryStream stream = Files.newDirectoryStream( pa );
Iterator<Path> pathIterator = stream.iterator();
while (pathIterator.hasNext()) {
Path curPath = pathIterator.next();
File curFile = curPath.toFile();
String fileName = curFile.getName(); //文件名称,日志使用
long time = curFile.lastModified(); //(毫秒)
if( time < delTime ){ // delTime = 当前时间(毫秒) - 缓存文件想要保留的毫秒数
logger.info( path + "\\" + fileName);
curFile.delete();
}
}
} catch (IOException e) {
e.printStackTrace();
}
评论