如果php有个功能需要耗时很久,做完之后才能进行下一步,如何让客户安心等待?

阿采 发布于 2015/11/16 10:46
阅读 1K+
收藏 0
PHP

php网站,有个调用shell脚本创建文件的任务,要耗时大概1分钟,做完之后还有一些数据库操作以及其他文件操作,我现在做了一个进度条,当用户提交新建之后会显示进度条,但是shell命令的执行时间无法预计,所以进度条是写死的20%的时候开始调用shell,然后就卡在20%,等shell执行好就刷的到了100%。

有两个问题,

1. 有没有办法可以让这个新建的过程更友善一点,不要给用户一种很突兀的卡半天突然好了的错误?

2. 有没有办法获取到shell执行失败的结果?因为一旦shell执行失败,任务调就卡在了20%,而且在shell之前php做的一个创建文件夹和另一个文件的操作就无法回退,因为拿不到shell执行失败的这个信息


以下是问题补充:

@阿采:shell应该是肯定能执行成功的,除非出现服务器之间网络异常或者服务器本身系统或硬件异常。了解了一下php的超时机制,现在卡死的问题应该是shell执行时间超过了30s。在php中增加了ini_set('max_execution_time', 120);将shell执行的时间放宽到2分钟,再没有出现卡死的现象,虽然很慢最后都执行成功了。 进度条的实时刷新还没有解决方案。目前进度条和shell执行是在同一个php文件中,即使是假定shell脚本每次执行都是1分钟,有没有好的办法可以让它在shell执行过程中实时刷新? (2015/11/16 15:09)
加载中
0
lonyis
lonyis
用消息队列。另外尽量少用php shell单线程坑很多
0
xper
xper

根据之前自己的经验给你提几个建议,按需采用:

1,任务先在数据库中保存,你应该采用内存保存(进度,状态,更新时间),完成就保存在数据中,标志完成。内存写入时记上有效期,超过就请求不到需要去数据库查状态。

2,实时请求的时候,判断进度,和时间超时1分钟,提示:任务可能需要好久请多等待,假如内存无数据,数据库查询也是没有完成就意味着是失败了就直接通知任务失败。

3,这个shell工作的内容是不是差不多一样?就可以在生成时就在固定位置写入内存状态,同时检测是否出错,出错就返回任务失败。

4,按照正常的功能需求来说,任务是不允许失败的,如果失败就改自己查找问题,及时解决。

5,这个shell执行的时候应该提示客户休息一下,等会来某个地址就能查看文件了。

6,假如生成的文件需要下载就检测文件是不是存在,数据库状态是不是完成,当前用户是不是有权限下载。


提供几种进度控制理念(个人看法):

1,文件下载进度(知道文件大小了,判断网速,得知时间)

2.1,任务执行进度:粗略(知道流程,在流程中加入状态,通过获取状态来大概知道进度)

2.2,任务执行进度:精细一点(知道流程,等分过程,百分比实时记录)(知道流程,过程中有其他表现形式,例如文件的解压,个数分进度,大小分进度,个数加大小分进度)

3,文件生成进度(知道生成大小,且是分批次写入,检测大小和总大小计算进度)(知道生成流程,等分流程控制,反馈信息进度)(知道文件生成数量,按数量计算,等分进度)

4,通用进度(知道流程,尽量等分进度【细分单个流程】)

xper
xper
回复 @阿采 : 整体没问题,具体在遇到其他实际问题再问吧
阿采
阿采
谢谢这么用心的回答。 你的意思是不是在启动shell这个命令前插入数据库任务启动的flag,flag在内存里也有,完成时候在数据库更新成已完成的flag。另外起一个计数器,隔一段时间就去check内存里的flag是不是已完成,如果不是,判断时间是不是超过了我们计划让用户等待的最长时间,如果超过了就中断shell,提示用户操作失败,进行前期活动的回退?
0
阿采
阿采
最后发现没有办法提前获取shell执行的总体时间,所以换了一个思路,将进度条换成了不确定性进度条,就是类似安卓系统里那种一直转圈,看不出进度的那种,解决了问题。
0
a
amhoho
我专门的写了个解决方案的文章,去看看:http://segmentfault.com/a/1190000004235213
阿采
阿采
打不开
返回顶部
顶部