【问题标题】:How does a server identify php script instance from another server who runs multiple instances?服务器如何从运行多个实例的另一台服务器中识别 php 脚本实例?
【发布时间】:2014-02-06 12:47:03
【问题描述】:

我有 2 台服务器。主服务器充当 server2 的 Web 服务,并且 server2 正在与客户端通信。

Server2 运行一个 php 脚本,从客户端获取一些数据,然后将其发送到主服务器,然后读取主服务器上某个页面的内容(根据客户端的数据生成),并且还读取从主服务器返回的 http 标头以获取 cookie 值。

服务器 2 代码:

some code ...

$postdata = http_build_query(
    array(
        'var1' => 'value1',
        'var2' => $_POST["var2"],
        'var3' => $_POST["var3"]
    )
);
$opts = array('http' =>
    array(
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => $postdata
    )
);

$context = stream_context_create($opts);
file_get_contents("http://www.mainserver.com", false, $context);
$cookieContent = getCookieContent($http_response_header);
SetCookie('myCookie', $cookieContent, $loginTime, '/', $url, false);

more code ....

主服务器不运行 php 脚本,但它按预期写入 cookie 值。 cookie 值是唯一的,是根据 server2 传递的客户端详细信息生成的。

所以,基本上,server2 充当“代理”(或反向代理),应该为每个客户端设置他从主服务器获取的唯一 cookie 值。

我的问题是:

我的逻辑有效吗?我知道它适用于 1 个客户端,但是当多个客户端访问 server2 上的同一脚本时会发生什么?主服务器如何知道将具有正确唯一值的答案返回给 server2 上正确的 php 实例?

换句话说,客户端是否有机会向 server2 发送请求,而 server2 将返回一个具有唯一值的答案,该值属于不同的客户端?

【问题讨论】:

  • 看起来您的 server2 正在充当 reverse-proxy。我想知道你为什么要从头开始构建一个。您是否查看过像 Apache traffic server 这样的现有解决方案?
  • 因为 server2 也做其他事情,也使用自己的数据库,而不仅仅是在客户端和主服务器之间传递信息。
  • 好吧,如果不是全部的话,大多数反向代理也是如此 :) 我在想也许你可以使用现有的软件作为基础,看看你是否可以在它之上实现你的特定功能。
  • 好吧,我不需要比我已经拥有的更多,我只需要了解事情是如何工作的,以确保我的代码能够完成我想要它做的事情。
  • 你的逻辑没问题,但在我能想到的任何情况下都不理想。 “主服务器”是否接受来自任何形式的常规 HTTP 客户端的连接,还是所有请求都来自“服务器 2”和类似主机?您能否更具体地了解“服务器 2”和“主服务器”上正在执行的任务?跨度>

标签: php http proxy parallel-processing multiple-instances


【解决方案1】:

是的,它确实有效,因为服务器 2 上的 PHP 为来自客户端的每个请求独立处理脚本。反过来,PHP 脚本的每个执行实例都从stream_context_create() 接收到它们自己的 HTTP 请求,很可能甚至在不同的 TCP 连接中。 $context 的值不可能在执行实例之间意外交换,并且客户端会收到原本打算发送给另一个客户端的响应。

您的问题甚至不需要»主服务器«。当您编写 PHP 脚本时,有关它如何处理请求的关键信息对您隐藏,这就是您可能会感到困惑的原因。但这是一件好事:

  1. 如果您抽象出有关如何调用 PHP 的详细信息,您的网络服务器在如何处理来自并发客户端的请求方面有许多(可配置的)选择:例如使用多线程,多进程,序列化所有执行,使用线程池。您不想重写您的 PHP 代码,因为您的 Web 服务器必须使用线程而不是进程。如果你编写好 PHP 代码,你可以在不同的上下文中使用相同的 PHP 代码,例如从命令行调用它。

  2. 您获得了某些基本保证,例如没有客户端会意外地获得针对其他客户端的响应。

但是,如果您希望“主服务器”知道它正在为不同的客户端提供服务,则必须相应地通知它。这可以与传递 cookie 一起工作(在您的情况下,您将 cookie 从 »主服务器« 传递到客户端,但将 cookie 从客户端传递到 »主服务器« 丢失)。

【讨论】:

  • 我不需要主服务器知道他为不同的客户服务,他只根据他得到的post数据生成一个页面和一个cookie值,这对我来说已经足够了。如果我正确理解您的答案,我不需要更改我的代码或向主服务器发送额外数据以使其适用于多个客户端。顺便说一句,这两个服务器及其功能对我来说是既定事实,我别无选择,所以我不能放弃主服务器。
  • 我不想说您应该删除»主服务器«,我只是想通过将其排除在等式之外来简化问题。
【解决方案2】:

看来你想实现自己的反向代理系统。

基本上你的代理(在你的例子中是server2)需要记住所有需要的东西

  • 将客户端请求传递给服务器,
  • 服务器生成所需页面后回复客户端
  • 处理服务器不响应的情况(即请求超时)

在简单的客户端-服务器交换中,服务器将使用客户端发送的 HTTP 标头来产生即时回复,因此这些标头不需要记忆。

在代理架构中,代理不会立即回复(而是向服务器询问实际回复)。

在服务器产生回复所需的时间内,代理必须记住原始客户端请求的引用,以

  • 在服务器最终生成最终回复后,使用它重新创建最终回复,
  • 从客户端处理请求取消

这意味着代理必须异步处理两个双向通信通道,而简单的服务器可以同步处理请求。

您的示例显示的是从代理到服务器的上行链路。

在此上行链路中,代理必须透明地提供客户端传递的所有信息,并添加一些指示服务器应如何将完成的请求回传给他。

您示例的$context 变量应包含客户端传递的 HTTP 标头,以及一些到代理的反向链接,服务器将使用这些反向链接将其响应定向到代理而不是客户端。

反过来,服务器将处理请求,就好像它是由客户端直接发送的一样。但是,一旦请求被处理,它将使用反向链接来回答代理。

代理将从服务器获得响应,并使用记忆的请求上下文来决定如何处理结果。客户端可能同时放弃了请求,在这种情况下,结果将被简单地忽略。否则,它将使用请求上下文将响应传递给客户端。

话虽如此,服务器提供的唯一 ID 并不是必需的,因为服务器永远不会直接与客户端对话。重要的是代理和服务器可以清楚地识别他们正在处理的请求。

简而言之,唯一需要的是服务器和代理之间的请求标识符。

您仍然可以根据 cookie 或 IP 地址或任何其他方式为每个客户端生成唯一 ID,但这与无代理客户端-服务器架构中的会话处理没有什么不同。

【讨论】:

  • 这是一个很好的答案,但我已经完成了实现部分。我的问题是关于我的代码/算法。我试图了解 file_get_contents 是如何工作的。如果它在主服务器和 server2 之间打开一个唯一连接,那么当 server2 再次运行脚本时,将打开一个不同的连接。在这种情况下,我不需要记住任何东西。连接是唯一的,服务器可以同时在不同的连接上进行通信。
  • file_get_contents 只是从流中读取,直到到达输入的末尾。有趣的部分是第三个“上下文”参数,它允许在结果中添加任何你想要的东西。可以设置此上下文以从请求中收集 HTTP 标头。有关详细信息,请参阅HTTP context options。这有点像在一个函数调用中读取服务器的完整响应。上下文也可用于调整对请求的响应。
  • 你控制着整个链条?我要么选择这个解决方案,要么因为你的 server2 目前不是反向代理,实际上正在运行 php,然后让它成为网络服务器并进行 cookie 管理。那么主服务器基本上是一个权威的信息来源,您可以像 server2 的 Web 服务一样有效地使用它来从中获取数据。在某些时候,您可以将主服务器换成其他任何东西,然后甚至将其全部整合到 server2 上。
猜你喜欢
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
  • 2023-03-14
  • 2015-08-10
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
相关资源
最近更新 更多