前情提要请看:宝塔面板的0点CPU高占用bug解疑(一),以下内容来源于hostloc的flyqie,原帖地址为:https://hostloc.com/thread-1030797-1-1.html

本人测试环境: Bt-Panel 7.7.0, Debian10 amd64
经查看本地/www/server/panel目录下的面板代码以及与老哥交流(原帖子回复), 确认原帖老哥拿到的代码并非宝塔目前主版本代码(可能是开发版)。[注:此处“老哥”为本人,原帖在hostloc中发帖并交流]

分析

宝塔目前主版本代码会执行/www/server/panel/BT-Task作为BT-Task service。在/www/server/panel/BT-Task引入了 /www/server/panel/task.py并执行其中的main函数。在task.py中,main函数中会开启多个线程去调用其他任务, 最后主进程交由startTask函数进行处理。startTask是个死循环函数, 它会先执行从面板数据库中拿取的任务, 之后调用siteEdate函数进行网站到期处理。siteEdate 函数正常来说应该在一天内只执行一次/www/server/panel/script/site_task.py,但是很不幸宝塔程序员逻辑写错了:

def siteEdate():
    global oldEdate
    try:
        # 程序拿到的永远是启动时候/www/server/panel/data/edate.pl的值, 第二次执行时候虽然oldEdate不为空, 但是/www/server/panel/data/edate.pl已经发生变化了, 没有去更新
        # 两种解决方法, 删掉oldEdate判断或者在函数结束后将oldEdate手动置空
        if not oldEdate:
            oldEdate = ReadFile('/www/server/panel/data/edate.pl')
        if not oldEdate:
            oldEdate = '0000-00-00'
        mEdate = time.strftime('%Y-%m-%d', time.localtime())
        if oldEdate == mEdate:
            return False
        os.system(get_python_bin() +
                  " /www/server/panel/script/site_task.py > /dev/null")
    except Exception as ex:
        logging.info(ex)
        pass

这将会导致在第一次执行后, 每次调用siteEdate函数时都会继续执行/www/server/panel/script/site_task.py。更糟糕的是,/www/server/panel/script/site_task.py中似乎也没有对此做处理(判断时间), 也就是说site_task.py会不断执行一系列没有必要的检测。

修复

建议官方尽快解决, 目前可用临时修复补丁进行修复,但不保证完全可靠(补丁基于7.7.0并且未经过长期及生产环境测试), 建议谨慎使用。

diff -uN old/task.py new/task.py
--- old/task.py    2022-06-10 13:13:00.107691400 +0800
+++ new/task.py    2022-06-10 13:17:52.807987000 +0800
@@ -158,8 +158,7 @@
 def siteEdate():
     global oldEdate
     try:
-        if not oldEdate:
-            oldEdate = ReadFile('/www/server/panel/data/edate.pl')
+        oldEdate = ReadFile('/www/server/panel/data/edate.pl')
         if not oldEdate:
             oldEdate = '0000-00-00'
         mEdate = time.strftime('%Y-%m-%d', time.localtime())

标签: 宝塔面板, panel, aapanel

添加新评论