美文网首页
crontab/daemon 相关的用户问题

crontab/daemon 相关的用户问题

作者: DeanWang | 来源:发表于2021-07-18 09:30 被阅读0次

    一个功能完善的web服务可能总是离不开定时任务和守护任务。
    前者经常用来完成一些定时触发的任务;例如跑数据
    后者则多用于进行一些需要一直执行的任务,例如做为MQ消息的消费者,需要一直监听消息

    在一般的Linux环境下,定时任务的执行可以直接配置crontab,而守护任务通常可以使用supervisor服务

    一般地这两个服务都会默认以root用户执行;而web服务则通常不会以root用户执行,例如nginx一般都会以低权限的www-data:www-data 用户执行

    而在代码层面,守护进程、定时任务和web服务通常会使用一套代码

    这就带来一个问题;高权限用户身份(例如root)执行的crontab/supervisor进程创建的文件属于root;这就会导致该文件无法被低权限用户身份(例如www-data)执行的web服务所读写;这就会带来线上的问题;

    一个典型的场景是,被守护进程、定时任务、web服务共用的日志组件代码在守护进程、定时任务中执行的时候创建的日志文件;无法被web服务读写。直接导致线上发生500(服务器内部错误)

    如何解决?

    一个方案是将定时任务、守护进程都改为低权限用户执行:
    例如crontab 使用 crontab -u www-data -e 就可以在用户www-data 权限下配置定时任务
    而supervisor的program段也可以指定user参数,来实现子进程以指定用户身份运行的目的,示例配置(注意礼貌 user 字段的配置):

    [program:abc]
    directory = /data/var/www/abc/
    command   = /usr/bin/php abc.php
    numprocs  = 1
    user = www-data
    autostart = true
    autorestart = true
    stdout_logfile = /var/log/stdout.log
    stderr_logfile = /var/log/stderr.log
    

    值得注意的是,如果supervisor的program是新增的user配置。需要在supervisorctl 中执行update命令;而不不仅仅是在supervisorctl下执行restart abc命令;单纯的restart并不会改变子进程的用户;
    这个可以通过supervisorctl下status查到子进程的pid,然后通过 ps aux 查看对应pid的用户证实,亲测必须update命令才能更新子进程的user身份

    该方案降低了定时任务和守护任务的用户身份,来达到不影响web服务的目的。同时带来的问题是,部分守护任务和定时任务依赖的服务,并不一定是能以www-data 身份执行的。同时对python等程序来说,更改身份也会带来环境的问题。所以该方案会带来较大的复杂性和不确定性

    还有一个方案是,在代码中对可能创建同时web服务可能write的文件(大部分文件权限对于其他用户都是可读的);直接进行chown操作;
    还是以日志文件示例,代码:

    private static function createLoggerByModule(string $module): ?Logger
    {
            $dir = ProjectConfig::logModuleDir($module);
            $filename = date('Y-m-d') . ".log";
            $logFile = $dir . '/' . $filename;
            if (!is_file($logFile)){
                $webUser = ProjectConfig::getInstance()->webUser();
                if (!empty($webUser)){
                    `touch $logFile`;
                    `chown $webUser $logFile`;
                }
            }
            ...
    }
    

    对于不存在的日志文件。直接先touch创建,然后执行chown,将文件的owner修改为web服务用户。

    该方案的好处在于对守护任务和定时任务无需改动,但是需要梳理代码中操作文件,尤其是写文件的地方;在这些地方在编码上注意文件所有者的设置(或者通过chmod修改文件的权限配置也可以,原理一样)

    相关文章

      网友评论

          本文标题:crontab/daemon 相关的用户问题

          本文链接:https://www.haomeiwen.com/subject/hvohyltx.html