wpf999 发表于 2017-3-26 22:15:34

终极检测方案:应对FAHClient程序僵死

问题现象
由于网络的问题,FAHClient程序在下载或上传任务包时,可能出现程序僵死的现象。 出现这种情况后,通过FAH控制面板退出程序实际上是不生效的。在windows下必须通过windows任务管理器直接结束FAHClient.exe进程,在Linux下则通过kill -9 FAHClient-PID 结束进程。

后果
FAHClient程序僵死的直接后果是停止了folding@home计算,造成PPD下滑。 这就需要用户时常关注fah的运行状态,总有不便。

原因分析
这实际上是FAHClient程序的一个重大bug,在网络发生异常状态时,程序不能识别并处理这个异常,进而进入某种死锁状态。

已有的解决努力
这为应对这个bug,队友提出了各种解决方案。 以Lynt朋友的方法最为出色。Lynt在过去开发了基于Autoit脚本的卡包检测与处理程序——FAH_Daemon (http://www.equn.com/forum/thread-40464-1-1.html),支持windows和Linux。该程序在3213团队中发挥了显著的作用,为不少网络不稳定的队友解决了问题。 最近Lynt兄弟又写了一个ubuntu专用的守护脚本(http://www.equn.com/forum/forum. ... id=42978&pid=572649), 当发生卡包时,重启fah系统服务。该守护程序判断FAHClient某个SLOT超过这个阀值时间没有运算,将认定此SLOT发生卡包,继而运行重启FAHClient等动作。


新的检测办法
根据我的观察,FAHClient进程在运行时会侦听 36330 TCP端口和7396 TCP端口,其中36330端口还以telnet的方式提供交互式查询与控制命令。 所以登录进入看看:# telnet 127.0.0.1 36330
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Welcome to the Folding@home Client command server.
>
可以发现,FAHClient程序会打出“Welcome to the Folding@home Client command server.”的欢迎词。 根据Linux命令行的一般规则,让我们尝试输入help,看看有什么结果:
可以发现,这里提供了不少查询与控制命令。


于是,我就立即产生了个思路: 当FAHCient僵死时,telnet端口还有响应吗?如果没有响应,那么这不正好是一个我们寻求已久的FAHCient僵死的最佳判据吗!   
多年来的直观感觉告诉我,FAHCient僵死时还响应telnet交互命令的可能性很小。 然后,开始等待FAHClient出现僵死。。。
先测试了FAHClient正常状态下,36330 telnet端口都有响应。 恰好今晚就遇到一台fah主机出现僵死,立即开始验证:# curl -m 5telnet://172.16.16.11:36330
curl: (7) Failed connect to 172.16.16.11:36330; 拒绝连接
#
果然,FAHClient程序不理我们了。

而正常的FAHClient,则是这样:#echo -e "info\nquit\n\n" | curl -m 5telnet://172.16.16.16:36330
Welcome to the Folding@home Client command server.
> PyON 1 info
[
[
    "Folding@home Client",
    ["Website", "http://folding.stanford.edu/"],
    ["Copyright", "(c) 2009-2014 Stanford University"],
    ["Author", "Joseph Coffland <joseph@cauldrondevelopment.com>"],
    ["Args", ""],
    ["Config", "/home/wpf/fahclient_7.4.4-64bit-release/config.xml"]
],
[
    "Build",
    ["Version", "7.4.4"],
    ["Date", "Mar4 2014"],
    ["Time", "12:01:17"],
    ["SVN Rev", "4130"],
    ["Branch", "fah/trunk/client"],
    ["Compiler", "GNU 4.1.2 20080704 (Red Hat 4.1.2-46)"],
    ["Options", "-std=gnu++98 -O3 -funroll-loops -mfpmath=sse -ffast-math -fno-unsafe-math-optimizations -msse2"],
    ["Platform", "linux2 2.6.18-164.11.1.el5"],
    ["Bits", "64"],
    ["Mode", "Release"]
],
[
    "System",
    ["CPU", "Genuine Intel(R) CPU @ 3.00GHz"],
    ["CPU ID", "GenuineIntel Family 6 Model 63 Stepping 1"],
    ["CPUs", "16"],
    ["Memory", "31.19GiB"],
    ["Free Memory", "30.54GiB"],
    ["Threads", "POSIX_THREADS"],
    ["OS Version", "3.10"],
    ["Has Battery", "false"],
    ["On Battery", "false"],
    ["UTC Offset", "8"],
    ["PID", "3329"],
    ["CWD", "/home/wpf/fahclient_7.4.4-64bit-release"],
    ["OS", "Linux 3.10.0-327.el7.x86_64 x86_64"],
    ["OS Arch", "AMD64"],
    ["GPUs", "4"],
    ["GPU 0", "NVIDIA:5 GP104 "],
    ["GPU 1", "UNSUPPORTED: NV3 "],
    ["GPU 2", "NVIDIA:5 GP104 "],
    ["GPU 3", "UNSUPPORTED: NV3 "],
    ["CUDA", "6.1"],
    ["CUDA Driver", "8000"]
]
]
---
> #
我们可以把输出加个重定向echo -e "info\nquit\n\n" | curl -m 5telnet://172.16.16.11:36330 > stdout.txt2> stderr.txt
若文件stdout.txt为空,则说明FAHClient程序发生了僵死, 在文件stderr.txt里还有curl执行出错的更多信息。

下一步的工作
至此,最为难搞的FAHClient僵死判据已经得到了较为圆满的解决。下一步就是集成一个完整的FAH守护脚本。基本流程伪代码如下:

while 1
sleep 10 mins
if 检测结果==僵死 then
   restart FAHClient
end if
end while

可以搞成定时任务,Linux下以crond方式实现,比如每10分钟执行一次。
每次先检测FAHClient程序是否发生了僵死,若僵死,则restart FAHClient,否则什么不干,退出。   Linux下FAH客户端分为service版本和免安装版, 对于service版本,直接调用service/ systemctl重启,对于 免安装版, 则建议适当包装,成为service形式,以便restart。Windows下定时任务和重启FAHCl也可通过一些相应的机制来完成,这里就不详说了。


(完)


由于近期工作任务繁忙,本人暂时就不去做实现了。对本文方案感兴趣的朋友,欢迎自行实现,推荐在校生练习一下。

horst1981 发表于 2017-3-27 01:03:23

坐等大能出招。

dutian_007 发表于 2017-3-27 08:30:05

大神呀,我是看不懂,简单来讲就是找到了假死时电脑的异常,并提出了假死的解决办法——守护程序加入新指令。版主啊,送佛送到西吧,直接搞定算了。

金鹏 发表于 2017-3-27 10:20:16

难得一见的技术宅文
做等高手继续实践

Lynt 发表于 2017-3-27 15:43:20

W版的思路很新颖也很直接,FAHClient不响应了,肯定是卡死了,但是我认为还需要多做一些验证工作,因为目前除了下载WU卡包外,还有下载运算内核卡死,上传卡包等问题,另外多SLOT中某一个SLOT卡包是否会导致 FAHClient不响应 telnet请求等问题需要验证(即验证是否所有/绝大多数不运算的情况是否都可以通过telnet是否响应来判断),如果绝大多数情况都可以用 telnet响应与否作为判断就可以采用此方法,这样会极大简化FAH卡包判断(目前从LOG内容判断较为复杂,但是几乎所有状况都能抓出来),减少卡包判断占用系统资源,并且有可能实现Windows/Linux整合的卡包处理脚本。

Lynt 发表于 2017-3-28 23:01:18

本帖最后由 Lynt 于 2017-3-30 16:04 编辑

为验证telnet响应判断FAHClient卡死的准确性,已在Linux卡包处理脚本中增加telnet无响应检测代码(目前仅将telnet无响应记录到log文件中,不作重启动作),与FAH LOG内容判断卡包作比对。因本人网络状况较佳,极少出现卡包现象,希望有运行Linux计算(最好是双卡或以上平台)并且常卡包的算友协助验证。另外telnet无响应代码做了些改动,不用CURL指令(CURL要另外安装,本人的Ubuntu 14.10及16.10安装时都有依赖问题,并且无法自动安装依赖包,需要手动安装指定依赖包),仅判断telnet localhost 36330是否成功,可能并不完善,也需要验证。

脚本说明如下:

1. 先确定运行机器的FAH SLOT,必要时修改脚本14行,将需要守护的SLOT加入列表;

2. 为脚本增加运行权限:sudo chmod +x fah_daemon_telnet.sh3. 运行方式: Daemon_Full_Path/fah_daemon.sh "Full_Path_to_Log_File" "Minutes" , 例如:./fah_daemon.sh /var/lib/fahclient/log.txt 15其中“Minutes”指定卡包时间阀值,即守护程序判断FAHClient某个SLOT超过这个阀值时间没有运算,将认定此SLOT发生卡包,继而运行重启FAHClient等动作;
4. 设置cron自动运行:
因为权限问题,必须以root权限运行脚本,因此执行sudo crontab -e增加一行(其中*/5 * * * *表示每5分钟运行一次):*/5 * * * * /home/lynt/fah_daemon_telnet.sh /var/lib/fahclient/log.txt 15 > /dev/null 2>&1已知问题:
1. 因为是以root身份运行,产生的临时文件及 fah_daemon.log日志文件都将保存在 /root 目录下,察看较麻烦,需要sudo(已更新脚本,将日志文件保存到/var/log/fah_daemon.log,方便查看):
2. 脚本会为每个SLOT产生一个临时文件,形如:temp_FSxx_log.txt,其中 FSxx为SLOT名称,如FS00、FS01等(已更新脚本,将临时文件保存到/var/log路径下,方便查看);

3. 绿色版FAHClient需要修改脚本中杀FAHClient进程及重启FAHClient的指令,分别为pgrep -u fahclient | xargs kill -9 > /dev/null 2>&1    #杀进程,安装版只需找出fahclient用户的进程全部杀掉,比较简单/etc/init.d/FAHClient start > /dev/null 2>&1    #启动FAHClient以下是守护脚本,期待高人改进:

wpf999 发表于 2017-3-29 08:53:54

读取tcp port 36330的方法很多,curl只是其中一种。 C可以调用socket读取, python不但能用socket,还支持直接读取telnet的机制( import telnetlib )

wpf999 发表于 2017-3-29 09:03:14

Lynt 发表于 2017-3-28 23:01
为验证telnet响应判断FAHClient卡死的准确性,已在Linux卡包处理脚本中增加telnet无响应检测代码(目前仅将 ...

log文件建议保存到/var/log/ 下,以便于普通用户查看。

Lynt 发表于 2017-3-29 09:17:12

wpf999 发表于 2017-3-29 09:03
log文件建议保存到/var/log/ 下,以便于普通用户查看。

谢谢W版的建议,我晚一点改一下log输出路径,至于telnet验证方法,目前仅作简单验证,先直接shell调用系统telnet指令,以后确定要用此方法再改成其他更好的方式

wpf999 发表于 2017-3-29 23:53:24

Lynt 发表于 2017-3-28 23:01
为验证telnet响应判断FAHClient卡死的准确性,已在Linux卡包处理脚本中增加telnet无响应检测代码(目前仅将 ...
关于ubuntu的curl, 我虚拟机里有个ubuntu 16-10 server版, 打开看了看,自带curl 。      curl是一个很给力的网络工具,如果预编译包安装不成功,也可以下载source code编译安装,过程也很简单。这里写了个步骤http://www.equn.com/forum/thread-42267-1-1.html,以备查阅。在centos 6下的curl比较旧,我也是从source code编译的。

quamtum 发表于 2017-3-30 07:52:39

就我個人經驗是有遇到gui無反應但是可以telnet進去暫停
不過在這情況fah是會繼續跑不會中斷
最讓我困擾的還是卡在一半log檔不更新,最後100%也不上傳的卡法
此時只要按任意鍵就會上傳繼續跑,可是就有一段時間是沒分數...

wpf999 发表于 2017-3-30 11:14:15

quamtum 发表于 2017-3-30 07:52
就我個人經驗是有遇到gui無反應但是可以telnet進去暫停
不過在這情況fah是會繼續跑不會中斷
最讓我困擾的還 ...

欢迎交流,提供更多测试case

Lynt 发表于 2017-3-30 16:07:49

已更新6楼脚本,将日志文件fah_daemon.log及临时文件temp_FSxx_log.txt等存放到 /var/log路径下,方便查看,另更新脚本增加对SLOT手动暂停的判断

玩家共和国 发表于 2017-3-30 21:00:38

一直对FAH编程团队没有好感。求我们帮助运算,程序还不弄的傻瓜点,明知有bug这么久不解决。

ONLY 发表于 2017-3-31 20:27:23

本帖最后由 ONLY 于 2017-3-31 20:31 编辑

等了几天,终于有个GPU客户端卡死,试验了下,telnet如常,有正常反应,此路不通~

页: [1] 2 3
查看完整版本: 终极检测方案:应对FAHClient程序僵死

论坛官方淘宝店开业啦~