教你一招如何使用 php 父子进程坑人
现在项目中大多都会使用MQ(消息队列)用来解耦和提升服务稳定性,然后都会面临一个问题,就是消息积压,解决这个问题除了提升处理消息的速度以外,另外就是多开些消费者进程,并发的消费数据。
如果是其他语言可以多开些线程或协程消费数据,但是这些东西,在 php 里并没有很好地支持,所以大家多采用多进程的方式来增加消费者,然后这里又有了两种方式,父子多进程和普通多进程。
然后这里就有了一个有趣的坑人方法,小小一技就能把人坑的想打你,那就是使用父子进程。
这是 php 使用父子进程的一个伪代码
$pid = pcntl_fork(); //父进程和子进程都会执行下面代码 if ($pid == -1) { //错误处理:创建子进程失败时返回-1. die('could not fork'); } else if ($pid) { //父进程会得到子进程号,所以这里是父进程执行的逻辑 pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。 } else { //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。 }
那么怎么坑人呢?
坑人第一步,监听 signal
//使用ticks需要PHP 4.3.0以上版本 declare(ticks = 1); //信号处理函数 function sig_handler($signo) { switch ($signo) { case SIGTERM: // 我不想被 kill break; case SIGINT: // 我不想被 kill break; default: // 处理所有其他信号 } }
只需要监听两个,一个是监听的 ctrl+c 的 SIGINT ,另外一个是 kill 的默认 signal (不带任何参数就是使用的这个) SIGTERM,一般人都是用这里俩方法 kill 进程,只要监听这俩信号不让进程退出,然后其他人想要像重启进程产生的第一个想法就是 kill -9,kill -9 子进程不会被干掉,赞,这样就进了我们的套。
坑人第二步,修改子进程的名字,随便修改成一个相关不太相关的都行,但是不能和父进程有同样的关键词,自己能看懂就行,坑别人的同时也得给自己留条路不是,总之就是不要让别人使用 ps grep 的时候发现这是子进程,这是 php 设置进程名的一个函数
setproctitle("myscript");
如果 php version >= 5.5.0 可以用这个
cli_set_process_title("myscript")
假如使用这种方式在测试环境消费MQ数据,其他人在修了代码并重启进程,就会发现自己的数据总是莫名其妙的消失,而且还找不到是谁消费的,如果是kafka或者nsq之流还可以通过新增group或channel的方式继续开发,但是如果是 redis 的 list 做 MQ ,嘿嘿……
坑人的同时也得防止被坑不是,我们需要处理这种事情的时候,先找到主进程 pid ,然后使用这个命令
ps --ppid 父进程的pid
我懂得,你肯定想喷我,你这人这么怎么缺德,呵呵呵,我就是被人这么坑了一会,才这么印象深刻,难受。
更多架构、PHP、GO相关踩坑实践技巧请关注我的公众号:PHP架构师

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Golang面试题解析(五)
41.执行下面的代码发生什么? package main type Param map[string]interface{} type Show struct { *Param } func main() { s := new(Show) s.Param["RMB"] = 10000 } 考点:map初始化 map需要初始化后才能使用。 编译错误:invalid operation: s.Param["RMB"] (type *Param does not support indexing) 42.执行下面的代码发生什么? package main import "fmt" type student struct { Name string } func zhoujielun(v interface{}) { switch msg := v.(type) { case *student, student: msg.Name = "qq" fmt.Print(msg) } } 考点:类型转换 msg不属于student类型,所以没有Name字段。 改为: s := v.(student)...
- 下一篇
从0到1使用Kubernetes系列(二)——安装工具介绍
本文是Kubernetes系列的第二篇,将介绍使用Kubeadm+Ansible搭建Kubernetes集群所需要的工具及其作用。 主要内容包括: Kubeadm Kubeadm是什么 Kubeadm的目标 Kubeadm的子命令 Kubeadm的安装 CFSSL CFSSL的安装 Ansible Ansible是什么 Ansible的基本架构 Ansible功能特性 Ansible的安装 总结user-gold-cdn Kubeadm Kubeadm是什么 Kubeadm是一个提供Kubeadm init 和 Kubeadm join命令,用于创建Kubernetes集群的最佳实践“快速路径”工具。 Kubeadm可以在多种设备上运行,可以是Linux笔记本电脑,虚拟机,物理/云服务器或Raspberry Pi。这使得Kubeadm非常适合与不同种类的配置系统(例如Terraform,Ansible等)集成。 开发者可以在支持安装deb或rpm软件包的操作系统上非常轻松地安装Kubeadm。SIG集群生命周期SIG Cluster Lifecycle Kubeadm的SIG相关维护者...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- 2048小游戏-低调大师作品
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker安装Oracle12C,快速搭建Oracle学习环境