GCP App Engine上的PHP应用POST请求后偶尔丢失会话数据求助
Hey Beverly,看到你的问题了——昨天下午开始,你部署在GCP App Engine上的PHP应用偶尔会在提交POST请求后丢失会话数据,对吧?结合你贴的代码和App Engine的运行环境,我给你梳理几个最可能的排查方向,咱们一步步来解决:
先排查会话存储的核心问题:App Engine是多实例自动扩缩容的环境,PHP默认的会话是存在实例本地文件里的。如果你的POST请求被处理完后,跳转的请求被分配到了另一个实例,那新实例根本读不到之前存在旧实例本地的会话数据,自然就“丢”了。
解决办法很直接:把会话存储换成GCP的共享存储服务,比如Cloud Datastore或者Memorystore(Redis)。如果用Datastore的话,只要在你的php.ini里加一行配置就行:session.save_handler = gcpphpsession这样所有实例都会从Datastore读写会话数据,就不会出现跨实例的会话丢失问题了。
强制会话数据及时写入:你现在的代码是设置完SESSION后直接跳转并die,但PHP默认会在脚本执行结束时才把会话数据写入存储。如果跳转+die的动作太快,会话数据可能还没来得及持久化就中断了。
给你的代码加一行session_write_close(),强制把会话数据写入存储后再跳转,修改后的代码如下://if data passed via post, put it in session and reload page if (isset($_POST['form_data'])) { $_SESSION['form_data'] = $dp->clean_input_data($_POST['form_data']); $_SESSION['action'] = 'submit'; session_write_close(); // 先确保会话数据写入存储 header("location: ".$_SERVER['REQUEST_URI']); die; }检查会话Cookie的传递是否正常:打开浏览器开发者工具,对比POST请求和跳转后GET请求的
PHPSESSIDCookie值是否一致。如果不一样,说明会话ID没正确传递,自然读不到之前的数据。
可以检查php.ini里的session.cookie_domain和session.cookie_path设置,确保Cookie的域名和路径覆盖了你的应用页面,避免因为路径或域名不匹配导致Cookie无法携带。排查实例生命周期的影响:如果你的应用流量波动大,App Engine可能会快速启停实例。如果处理POST请求的实例在写完会话前被回收,也会导致数据丢失。不过用上边的
session_write_close()就能规避这个问题——写完会话再跳转,就算实例立刻被回收,数据已经存在共享存储里了。
先从这几个方向排查,尤其是前两个,是App Engine上PHP会话丢失最常见的原因,应该能解决你的问题!
备注:内容来源于stack exchange,提问作者Beverly Sobelman

