PHP 代码更新的时候会不会中断用户正在进行的请求及响应

2019-09-19 17:59:22 +08:00
 awanganddong

php 模式是使用的 php-fpm 模式

比如用户正在请求响应,这时候我更新了代码。会不会对正在请求响应产生影响

问了我老大,他说不会。 让我了解 web 的工作原理

这里我就想问下,大家 这个没想明白

6494 次点击
所在节点    PHP
28 条回复
imdong
2019-09-19 18:05:18 +08:00
答:不会。

如果对工作原理懂了,都不会这么问了。

简单的说,用户 -> Nginx -> php-fpm ( read php file -> run code ) -> Nginx -> 用户

你更改 php 文件的时候,只要 fpm 执行中,就不会出现问题。

因为不是边执行边读取,而是读取以后再执行,读取文件是瞬时完成的,修改和读取不会同时(系统保证)
toyuanx
2019-09-19 18:13:21 +08:00
可以看下这篇文章: https://blog.csdn.net/IT_10/article/details/95387481

"可以看到一旦 kill 掉 worker 进程后,会重启一个新的 worker 进程。因此客户端请求肯定会得到响应处理。这进一步验证了的上面的结论,master 进程负责监听子进程的状态,子进程挂掉之后,会发信号给 master 进程,然后 master 进程重新启一个新的 worker 进程。"

正常来说上线的时候对用户是有有影响的,但是如果上线的时间够快,可能影响就比较少
lincanbin
2019-09-19 18:15:03 +08:00
你去 Google 搜一下,关键字:php-fpm 平滑重启
lp7631010
2019-09-19 18:17:40 +08:00
人家问的是更改 php 文件吧 跟 fpm 重启啥的有什么关系呢
awanganddong
2019-09-19 18:19:37 +08:00
@imdong 你说的最后一句,可以稍微解答我的困惑,但是就是太简略了。

@toyuanx nginx 的热加载和 php-fpm 的热加载 master-worker 这种模式我也知道。包括多进程间内存是隔离的。


但是隐约感觉没有一语中的。
awanganddong
2019-09-19 18:27:21 +08:00
https://t.ti-node.com/thread/6528965533792993280

这是一个大佬的笔记


apue 我需要连接下了
ben1024
2019-09-19 18:30:23 +08:00
每个进程在运行时已经把代码加载到对应的内存中,每个进程使用的内存是独立的,不会相互干扰
mcfog
2019-09-19 18:35:23 +08:00
是否有影响影响多少用户多少时间取决于你们的部署流程是否正确
能否观测、监控到这种影响取决于你们的基础设施是否完善

一个很基本简单的方法论:如果你要修复或者改进一个问题,就必须先确保你能够观测、重现或测量它,否则你做的一切改进都是没有意义的。在建立了观测手段以后,减少更新代码对用户的影响这种属于常规基础的问题,找一些实践跟着做就行,很容易降到 0 或者可以忽略的程度的。

基于你其实并没有说你们的情况,所以这里即使说了一些实践做法的人也都只是随意说一些常见的可以做的事情而已
CODEWEA
2019-09-19 19:13:00 +08:00
答案:会 和 不会取决你如何更新代码。
你如果是用 svn git 那种覆盖式的更新,大概率是会因为文件依赖而遇到问题。
为什么会出现问题?
首先,你的 PHP 项目不可能就一个文件吧,比如你上一个版本 UserService 引入了 MailClass,但是你下一个版本中在 UserService 把 MailClass 删除了,如果你使用覆盖式更新时,如果 MailClass 完成更新删除了,但是 UserService 还没有更新,此时一个请求来了,并不会一次性把你 PHP 项目所有文件载入进去,当文件依赖出问题,你网站直接就 5XX 了

如何不出问题呢?
问题的关键就在于你改动 php 项目时,文件的依赖会发生变化,如果项目文件正处于变化时,文件依赖是处于混乱状况的,此时如果一个请求过来,你项目就 5XX 了。

解决办法:
1.更新代码时,阻断外部请求,将所有请求重定向到与这个项目无关的维护页面。
2.nginx 配置 2 个项目,一个为新,一个为旧的,当你新的更新完毕同时内部测试无误后,切换 nginx 的配置文件,切换到新的。

解决的的核心逻辑是不要在你 php 项目中文件发生变化时运行外部程序请求访问。
zhangtao
2019-09-19 19:20:24 +08:00
太多人喜欢不懂装懂了
CODEWEA
2019-09-19 19:32:25 +08:00
你老大说的:不会,应该是理想状态,或者说 php 项目中就一个 php 文件
jsjscool
2019-09-19 19:52:53 +08:00
先说答案,会有影响,但是发生的概率极低。

简单理解 PHP 的执行流程是这样的:

1. 扫描所有 PHP 文件,并转换成 Token (语言片段)
2. 解析编译 Token 得到 Opocdes
3. 执行 Opocdes

第一步扫描所有 PHP 文件时会将 include,require 等的代码一起加到内存,速度非常快,如果此时更新代码是有可能影响当前请求的。

如果请求进入到 1 之后的阶段,更新代码是不会对正在进行的请求有影响,因为用户的请求是独立的进程,独立的内存空间,内存里面的代码是请求到达 php-fpm 进程时那一刻的快照。

如何避免:
现在发布 PHP 代码都用 CI,CI 的实现方式不是 update 代码,而是每次创建一个新文件夹,全量拷贝代码,再修改软链接。如果使用类似方式发布代码的话就如你老大所说,不会影响用户请求。
kx5d62Jn1J9MjoXP
2019-09-19 20:03:51 +08:00
不管会不会,和 web 都一毛钱关系没有啊,应该和多个文件的写 /读有关。如果你们是像我待的那种公司一样用 ftp 传 PHP 文件的,ftp 和操作系统又不像数据库那样保证多个文件的上传为事务操作啊?
wshcdr
2019-09-19 20:05:05 +08:00
会的啊
CODEWEA
2019-09-19 20:09:02 +08:00
@jsjscool 不是吧? include require 是否真的引入文件还是根据你逻辑来的啊
zsen
2019-09-19 20:16:13 +08:00
同时考虑一下 php.ini 中的 opcache ?
crynocry
2019-09-19 20:40:10 +08:00
@imdong 同一个文件可以保证。 可是替换代码是批量替换,会出现有一部分老代码一部分新代码的情况么
jsjscool
2019-09-19 23:20:25 +08:00
@CODEWEA 我这里描述有误 ,从扫描文件到执行在多文件下是串行的不是并行。
akira
2019-09-19 23:54:12 +08:00
从原理上讲,单一文件肯定是不会。
但是
不管会不会 , 更新发版的时候 截断请求是个好习惯.
x86
2019-09-20 00:51:34 +08:00
细说的话看你动什么文件了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/602265

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX