关于httpd <defunct>进程的简略理解

今天无意中查看到了一个apache+php的服务器上出现了很多httpd <defunct> 进程。

第一次见到这个名字的进程,于是查阅了相关资料。

记录一下我理解到的httpd <defunct>:

 

1、什么是httpd <defunct>

defunct进程实际上是‘zombies’进程(top里查看到标记为‘Z’的进程)。

当一个进程执行完毕、结束后,需要其父进程来读取自己的状态,才能完全结束,这期间,如果父进程一直没有来读取状态,那么这个执行完毕的进程会一直在进程表中占据一个条目,这个时候的进程就是 'defunct' 进程。

 

更多的内容介绍可以查看:http://en.wikipedia.org/wiki/Zombie_process

 

 

2、为什么会产生httpd <defunct>进程

 

    默认情况下,apache的设置是:一个工作进程执行完指定数目的请求后,主进程会结束掉这个工作进程。这样设计是为了不至于内存泄漏,从而导致失控。

    第一种情况:像前面所说的,apache的主进程会对“寿终正寝”的工作进程进行回收。然而当服务器负载(load)很高时,apache的主进程可能没有空闲的时间去执行这一步回收工作。从而导致这些没有回收的“寿终正寝”的工作进程以‘defunct’的姿态出现在top命令里。在这种情况下出现‘defunct’进程是不用太担心的,除非有超大量的‘defunct’进程。

 

    另一种可能的情况是:工作进程异常退出导致的,异常退出的原因可能有很多,比如web应用的代码里有bug,或者web应用的引擎有bug。这种情况,可以通过查看apache的error_log日志来查看,查找是否有严重的错误日志打印出来。

 

我碰到的情况都不是上面两种,所以我又查了更多的资料,比如这个:

 

BiGWill 写道(链接: 点击这里
Thanks all for your help....
I finally nailed it down to the access_log which was 2GB big, which is the limit of the file system!

Guess i should implement some logrotation :D

Thanks everyone for their suggestions/help!

regards,

 

他说的是日志文件达到2G的上限,导致出现httpd <defunct> 进程,我这里使用的是cronolog来按天切割日志,每个日志文件才几十M,所以这个也不是想要的。

 

再比如这个:

 

gulaizi 写道(链接在这里: 点击跳转
问题的原因不会apache的问题,而是php版本的兼容性问题。
介于这个问题,我开始察看PHP问题,终于发现是php我安装了mmcahe,而且mmcache已经很久之前就停止开发了,对linux x86-64有兼容性问题。去掉mmcache,问题解决。

 

还有这个同学的描述:点击这里

 

都不符合我机器上的环境,所以我索性重启了一下apache,然后问题就解决了,很匪夷所思。原因依然待查……

 

最后,贴一段对系统管理员有用的,对“defunct”进程本质的解释:

 

来源: Yahoo Answers
The below explains what <defunct> means. If you aren't a Unix system administrator, this may not be of interest to you.

Normally, when a process exits (normally or abnormally), it enters a state known as “zombie” (which in top appears as Z). Its process ID stays in the process table until its parent waits on (or “reaps”) it. Under normal circumstances, when the parent process fully expects its child processes to exit, it sets up a signal handler for SIGCHLD so that, when the signal is sent (upon a child process's exit), the parent process then reaps it at its convenience.

If the parent process has hung for some reason, such as if it's suspended, or is too busy, or is deadlocked, then child processes that exit will not be reaped (until the parent process resumes again). This can cause serious problems if there are many child processes, occupying slots in the process table that will not be freed.

In that case, one solution (if the parent process is unrecoverable, say), is to kill the parent process. Then, the child processes will be reparented to the init process (process ID 1), which will reap them. (If the init process is stalled, then you have much, much bigger problems than child processes not being reaped. In fact, a crashed init process will usually cause a kernel panic.)

 

-----EOF------

&lt;think>好的,用户现在遇到了Nginx 1.20.1的403 Forbidden错误,并且特别提到了SELinux相关的配置问题。我需要结合之前的引用和之前的回答来提供解决方案。首先,用户之前的回答中已经提到了SELinux的目录位置、配置文件检查以及权限设置,现在需要更具体地针对403错误和SELinux进行调整。 首先,回顾用户提供的引用内容:引用[1]提到检查Nginx配置文件中的root指令和权限限制;引用[2]讨论了访问/root目录下的文件导致403的问题,建议移动文件或调整权限;引用[3]指出文件权限不足,需要chmod修改。但用户现在的问题更侧重于SELinux的配置,这可能涉及到文件上下文标签或端口策略。 接下来,用户之前的问题是关于SELinux目录和Nginx启动失败的解决方案,其中提到了修复文件上下文、生成自定义策略模块等方法。现在需要将这些方法应用到403错误中,特别是当SELinux阻止Nginx访问特定文件或目录时。 可能的步骤包括: 1. 检查SELinux状态,确认是否处于Enforcing模式。 2. 查看审计日志,找到被拒绝的操作,使用audit2allow生成策略。 3. 调整文件或目录的SELinux上下文,例如使用semanage和restorecon。 4. 检查Nginx配置中的root目录是否正确,确保文件权限足够。 5. 考虑SELinux布尔值设置,如允许HTTP服务访问网络或文件。 需要注意用户可能已经检查过文件权限,但问题依然存在,所以重点应放在SELinux策略上。同时,用户提到的是403错误,这可能与读取权限或执行权限有关,而不仅仅是文件存在与否。需要确保Nginx进程有权限访问指定路径,并且SELinux没有阻止该访问。 最后,要提供具体的命令和步骤,确保用户能逐步操作,同时强调安全性,避免过度放宽权限。例如,推荐移动文件到标准目录而不是修改/root权限,或者生成自定义策略而非完全禁用SELinux。&lt;/think>### Nginx 1.20.1 403 Forbidden错误与SELinux配置综合解决方案 --- #### 一、核心排查逻辑(SELinux优先) 403 Forbidden错误本质是**访问权限被拒绝**,但需区分: 1. **常规权限问题**:文件所有权、权限位(如`chmod`/`chown`) 2. **SELinux限制**:上下文标签、布尔值策略、端口绑定策略 --- #### 二、SELinux专项排查步骤 ##### 1. 验证SELinux是否触发拦截 ```bash # 查看实时拦截日志(过滤nginx相关拒绝记录) grep "avc:.*nginx" /var/log/audit/audit.log ``` 若输出类似以下内容,则确认是SELinux策略拦截: ```log avc: denied { read } for pid=1234 comm="nginx" name="index.html" dev="sda1" ino=56789 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file ``` ##### 2. 修复文件/目录上下文标签(关键步骤) 当Nginx访问非标准路径(如`/root/`)时,需修正SELinux上下文: ```bash # 示例:若资源存放在/root/web_content/目录下 # 添加文件上下文规则(httpd_sys_content_t为Web内容标准标签) semanage fcontext -a -t httpd_sys_content_t "/root/web_content(/.*)?" # 强制刷新上下文 restorecon -R -v /root/web_content # 验证标签(应显示httpd_sys_content_t) ls -lZ /root/web_content/index.html ``` ##### 3. 调整SELinux布尔值 ```bash # 查看与HTTP服务相关的布尔值 getsebool -a | grep httpd # 允许Nginx访问用户家目录(慎用!仅限测试环境) setsebool -P httpd_enable_homedirs 1 # 允许Nginx建立网络连接(常见于代理场景) setsebool -P httpd_can_network_connect 1 ``` --- #### 三、Nginx基础权限修复(与SELinux协同) ##### 1. 文件系统权限配置 ```bash # 确保Nginx用户(通常为nginx或www-data)有访问权限 chown -R nginx:nginx /root/web_content # 不推荐长期使用/root目录,建议迁移到/var/www chmod 755 /root/web_content find /root/web_content -type f -exec chmod 644 {} \; ``` ##### 2. 配置文件验证 在`nginx.conf`或站点配置中检查: ```nginx server { listen 80; server_name example.com; root /root/web_content; # 高风险路径!建议改为/var/www/html # 必须关闭目录列表(autoindex off为默认值) location / { index index.html; autoindex off; # 若开启可能导致403[^1] } } ``` 使用命令验证语法: ```bash nginx -t ``` --- #### 四、高阶场景:自定义SELinux策略 当标准修复不适用时,可生成针对性策略模块: ```bash # 从审计日志生成策略(需安装policycoreutils-python-utils) grep "avc:.*nginx" /var/log/audit/audit.log | audit2allow -M nginx_custom # 编译并加载模块 semodule -i nginx_custom.pp # 验证模块加载 semodule -l | grep nginx_custom ``` --- #### 五、安全建议 1. **路径规范**:避免使用`/root`作为Web根目录,优先使用`/var/www`(SELinux默认已配置安全上下文)[^2] 2. **最小权限原则**: - 仅开放必要端口:`semanage port -l | grep http` - 仅启用必要布尔值:`setsebool -P httpd_graceful_shutdown 1` 3. **日志监控**:定期检查`/var/log/nginx/error.log`和`/var/log/audit/audit.log` --- ### 引用说明 - 配置文件语法验证方法参考引用[1]。 - 文件路径安全性建议参考引用[2]。 - SELinux策略自定义流程见原始回答中的引用[4]。 --- ### 相关问题 1. 如何让SELinux允许Nginx访问外部存储设备(如挂载的硬盘)? 2. 在Kubernetes中部署Nginx时如何同步处理SELinux策略? 3. 如何通过audit2why工具解读SELinux拒绝日志?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值