大家好,我是许久未曾露面的老李。
今天这篇是一个应后台留言所准备的「回答」合集片儿,里边有众多老哥参演。
第一位演员:图灵
是的,他的昵称真的就叫图灵,一开始我以为是图灵出版社的人...他是《PHP网络编程》的阅读者,由于比较读的比较认真仔细,所以他问了一些问题,你们感受一下。
图灵问:关于信号阻塞实现reload功能,如何保证「完成当前进程内任务后再退出」
老李答:在看这个解答前,先看下第二个问题,然后再回来。这个非常简单,就是说reload只是参数,TA背后应该是收到这个参数后向某个进程发送某个信号比如SIGUSR1。进程提前设置了SIGUSR1的mask,所以进程会首先「兜住」SIGUSR1信号暂时不理会SIGUSR1(注意不是一直不理会),一旦进程中UNBLOCK了这个信号,进程立马会相应这个信号,你让进程相应该信号时候退出进程即可。顺序上就是先设置屏蔽SIGUSR1信号,进程开始处理常规业务流程,处理完毕后解除屏蔽SIGUSR1信号。有一定应用场景限制,适合进程中是一次性的任务。
图灵问:关于pcntl_sigwaitinfo()函数,关键代码如下:
<?php
pcntl_sigprocmask( SIG_BLOCK, array( SIGTERM ) );
sleep( 1 );
pcntl_sigprocmask( SIG_UNBLOCK, array( SIGTERM ) );
pcntl_sigwaitinfo( array( SIGTERM ), $info );
一秒钟后向该进程发送SIGTERM信号,为什么$info变量依然表示该进程阻塞SIGTERM信号?
老李答:首先是与sleep毫无关系,就是说sleep在这段代码里没有任何意义。其次是没有阻塞SIGTERM信号。原因在于pcntl_sigwaitinfo()函数,你把上述代码里的前三行全部去掉,运行一下试试。pcntl_sigwaitinfo()函数本身就是阻塞的,TA阻塞等待任何信号,如果这个信号在TA的第一个参数里,TA就会反馈在$info里;如果这个信号没有在第一个参数里,按照信号默认动作走。
图灵问:关于阻塞的一些疑问,问题太长了,我直接截图了:
老李答:这么说吧,我们说阻塞你可以理解为两种情况,一种是我们阻塞在某个系统调用上,另一种是阻塞IO。首先说默认情况下,socket IO都是阻塞IO,当accept系统调用试图从阻塞的listen-socket上获取信息时,如果没有新的链接,发起accept系统调用所在进程会进入CPU睡眠(这里有个CPU时间片的概念);如果说listen-socket是非阻塞的,那么尽量不使发起accept系统调用的进程进入睡眠而是返回EWOULDBLOCK(在PHP里可能是被抽象为false了)。而select系统调用本身就可以实现阻塞,TA是无视IO是否阻塞或非阻塞的,即便没有调用任何阻塞IO,使用select系统调用的目的就是「使得当前进程阻塞在select上而不是IO上」。
图灵问:能否列举一段「异步阻塞」的代码。
老李答:首先我们对齐一下概念这个问题里的「异步」是说IO复用而不是AIO们。然后这个问题很简单,《PHP网络编程》里select系统调用的代码,你把listen-socket设置为阻塞即可。但是这么做很愚蠢,因为会有这样一个问题,就是路人甲刚连接到服务器socket上,服务器此时尚未执行到accept,然后路人甲此时强行单方面断开了连接,对应问题里如果说这个IO是个阻塞的,那么此时就会出现比较尴尬的现象了。这种场景我没有实现过,时间点可能不好卡,总之大概是这么个道理。这里需要涉及到TCP/IP基础知识。
第二位演员:路人甲
其实也不算是个问题,是老李觉得有必要提一下这个玩意。这个玩意叫做DH,TA出现的意义是什么呢?这个说来话长,大家可以参考一下老李很久之前写的一篇文章:
这里有个问题就是首先单纯DH是无法杜绝中间人攻击的,但是TA可以提高门槛和成本,最起码使得那些上来就用青花瓷扒掉你们裤衩的人抓瞎,这已经可以过滤掉一大波儿人了。如果需要杜绝中间人攻击,需要的DH算法上包裹一层RSA数字签名。
老李之前和永强、阿尼特、东北大嫖客写过一个跨语言的DH库,大概涵盖了PHP、Java、Swift、Golang集中主流语言的,有需要的可以拿走。
https://github.com/ti-dh
如果大家对DH有兴趣可以投票下,我可以简单写下文章普及一下。
第三位演员:腰不好
其实我忘了具体是谁了,应该就是腰不好,至于他腰为什么不好,我也不知道。TA问的问题好像是:如何防止数据库自增id对外暴露而被坏蛋们遍历获取数据。举个例子比如你的用户uid用的是MySQL的自增id,然后你有个api可能是user/getinfo?uid=1这样的,此时对方就可以通过遍历uid来批量获取用户信息,其次是对外暴露了用户的真实注册量,解决方案有好几个,我说下你们参考一下:
综合考虑的话,我推荐第二种方案,发号器太麻烦了而且一旦服务器时钟回拨极有可能导致重复id出现。
最后一群群演
最后一个环节了,老李之前曾经让大家后台留言给点儿建议,这些建议我都收集上来了,你们感受下。
实际上老李不是特别擅长这些。不过这个建议我觉得代表了一批人,可以考虑。
我记得张国荣英文名是叫Leslie?不管了,附近的人系列我需要想想这么进行下去,毕竟还没写完。
大佬有点儿狠!这家伙全是硬核需求啊。记下了。
... ... 不知道评论啥
这个我完全听不懂他在说什么。
不行,没接触过大数据,整不了。我最擅长用phpMyAdmin直接导出sql文件...
我记得明朝万历年间有一位兵部尚书叫做石星,你们可以搜下。建议很硬核,和上面的狮子王提的主题都很不错,我收纳了。
最后如果大家觉得有用的话,劳烦点个在看,thx。