我思考我理解为什么会话是邪恶的,但为了获得更好的客户端用户体验,我不想在每次 HTTP 请求时都重新查询数据库。(相比之下,Java servlet 可以毫不费力地在内存中保存大量会话对象。)
是否可以将 PHP 设置为执行此操作,或者它是否必须进行序列化,因为它从 CGI/FastCGI 运行,因此根据定义,每次收到请求时都是一个新进程?我将使用 LAMP 运行 PHP。
答案1
实际上,PHP 处理会话的方式比您的 Servlet 示例要好得多。让我解释一下。
使用 PHP(默认情况下),会话由文件系统上的文件表示。当您调用时session_start()
,它会检查文件是否存在,如果存在,则加载该文件。如果不存在,它会创建一个文件然后锁定它。这有两个主要好处。首先,它允许同一服务器上的许多进程“共享”会话数据。其次,如果有人试图对您的站点进行 DDOS 攻击,会话数据不会将其关闭(您的瓶颈将在其他地方,您不必担心交换或耗尽内存空间,因为您有很多会话)。
php 中的序列化/反序列化方法实际上非常高效,因为它们是用 C 编写的,因此需要编译。所以这不是瓶颈。PHP 的会话经常被调用的原因evil
是它们是阻塞的。当您打开会话文件时,它会获得对文件的独占锁定(或阻塞直到完成)。它会保留该锁定直到会话关闭(在脚本结束时或结束时)session_write_close()
。这是可取的,因为它可以防止并发问题。但请注意,如果您有一个长时间运行的请求并在其执行时尝试发出另一个请求,您将被阻塞。
现在,PHP 方法的真正美妙之处在于,您可以用用户空间会话处理程序替换会话处理程序(将会话数据存储在数据库、memcached、NoSQL db 等中)。为什么这样做很好?因为这样您就可以使用完全相同的代码从一台服务器迁移到多台服务器。您需要做的就是调用session_set_save_handler()
...
现在,至于您的“我不想在每次请求时重新查询数据库”,我想问为什么不呢?您所做的只是一个简单的 PK 查找。除非您真的破坏了架构,否则即使是更新/写入/删除语句也应该非常高效。我建议使用内存表(在 MySQL 中),因为它更快,而且您并不真正关心服务器重新启动时维护数据。如果您这么担心,请安装 memcached 并让它处理会话的存储(这样您就不需要 SQL)...