了解mod_proxy和Apache 2编写彗星服务器

我目前试图为某种彗星技术实现一个简单的HTTP服务器(长轮询XHR请求)。 由于JavaScript对跨域请求非常严格,我有几个问题:

  1. 据我了解,任何apache工作人员在提供请求时都会被阻止,所以如果所有工作人员都有请求提供服务,那么将“脚本”作为通常的网站来封锁apache。 – >不行!
  2. 我想出了一个想法,写一个自己的简单HTTP服务器只为服务这个长的轮询请求。 这个服务器不应该被阻塞,所以每个worker可以同时处理多个请求。 由于我的网站也包含内容/图片等,我的服务器不需要服务器的内容,我开始他在不同的端口,然后80.现在的问题是,我不能交互我的JavaScript与我的彗星服务器运行在不同的端口,因为一些跨域的限制。 – >不行!
  3. 然后我想出了使用mod_proxy将我的服务器映射到一个新的子域的想法。 我真的不知道如何mod_proxy作品,但我可以想象,我知道有同样的效果,我的第一个方法?

创build这种types的经典网站和这些长轮询XHR请求的最佳方式是什么? 我是否需要在自己的服务器上实现内容交付?

我很确定使用mod_proxy会在处理请求时阻塞一个worker。

如果您可以使用2个IP,则有一个相当简单的解决方案。 假设IP A是1.1.1.1,IP B是2.2.2.2,假设你的域是example.com。

这是如何工作的:

– 配置Apache在端口80上侦听,但仅在IP A上侦听

– 在端口80上启动另一台服务器,但仅在IP B上启动。

– 将XHR请求配置在您的域的子域上,但使用相同的端口。 所以跨域限制并不妨碍他们。 因此,您的网站是example.com,例如,XHR请求转到xhr.example.com。

– 配置您的DNS,以便将example.com解析为IP A,并将xhr.example.com解析为IP B.

-你完成了。

如果你有两台服务器,每台服务器都有自己的IP地址,这个解决方案就可以工作,如果你有一台带有两个IP地址的服务器,这个方案也可以工作。

如果你不能使用两个IP,我可能有另一个解决方案,我正在检查它是否适用于你的情况。

这是一个难题。 即使您经历了您遇到的安全问题,您最终也不得不为每个正在查看网页的客户端保持一个TCP连接。 您将无法创建线程来处理每个连接,并且您将无法从单个线程“选择”所有连接。 以前这样做,我可以告诉你,这并不容易。 你可能想看看libevent , memcached使用类似的结束。

到了一定程度,你可能会放弃设置很长的超时时间,并允许Apache有大量的工作人员,其中大部分将在大多数时间闲置。 我相信,仔细的选择和配置Apache工作模块将把这个扩展到数以千计的并发用户。 然而,在某些时候,它不会再扩大规模。

我不知道你的基础架构是什么样的,但是我们在称为F5的网络机架中有负载平衡盒。 它们提供了一个外部域,但根据响应时间将请求重定向到多个内部服务器,请求头中的Cookie等。它们可以配置为将虚拟域内的某个路径的请求发送到特定的服务器。 因此,您可以将example.com/xhr/foo请求映射到特定的服务器来处理这些彗星请求。 不幸的是,这不是一个软件解决方案,而是一个相当昂贵的硬件解决方案

无论如何,你可能需要某种负载平衡系统(或者你已经有了一个),也许可以配置成比Apache更好地处理这种情况。

几年前,我遇到了一个问题,那就是希望使用具有专有二进制协议的客户端 – 服务器系统的客户能够访问我们的端口80上的服务器,因为他们在系统使用的自定义端口上持续存在防火墙问题。 我所需要的是一个代理,将生活在端口80上,并将流量导向到Apache或应用服务器,具体取决于来自客户端的前几个字节。 我寻找一个解决方案,发现没有什么适合的。 我考虑编写一个Apache模块,一个用于DeleGate的插件等,但最终还是通过自定义的内容传感代理服务进行推广。 我认为,对于你要做的事情来说,这是最坏的情况。

回答关于mod-proxy的具体问题: 是的 ,你可以设置mod_proxy来提供服务器(或服务)生成的内容,而服务器(或服务)不是公用的(即只能通过内部地址或本地主机)。

我已经在生产环境中完成了这个工作,并且工作得非常好。 Apache通过AJP工作人员将一些请求转发给Tomcat,其他人通过mod代理将其转发给GIS应用服务器。 正如其他人所指出的,跨站点安全性可能会阻止您在子域上工作,但没有理由不能将请求代理到mydomain.com/application


谈谈你的具体问题 – 我认为你真的陷入了“长期请求”的困境 – 也就是说,当你提出这样的要求时,整个过程就需要停止。 看起来好像你正试图通过改变系统架构来解决应用程序体系结构的问题。 事实上,你需要做的就是像这样处理这些背景请求。 和多线程吧:

  • 客户端向远程服务器发出请求“ 用数据A,B和C执行任务X
  • 您的服务接收到请求:将其传递到调度程序,该调度程序为请求发出唯一的票证/标记。 然后该服务将此令牌返回给客户端“ 谢谢,您的任务是在令牌Z下运行的队列中
  • 然后客户端挂在这个令牌上,显示一个“加载/请稍候”框,并设置一个计时器,每隔一秒
  • 当定时器触发时,客户端向远程服务器发出另一个请求“ 你的结果是我的任务,它是令牌Z
  • 您后台服务可以与您的调度程序进行核对,并可能会返回一个空的文件“ 不,尚未完成 ”或结果
  • 当客户得到结果时,它可以简单地清除计时器并显示它们。

只要你对线程相当舒服(如果你已经指出你正在编写你自己的HTTP服务器,那么你必须是这样,这应该不会太复杂 – 在http listener部分之上:

  • 调度器对象 – 单例对象,真的只是包装了“先进先出”堆栈。 新任务进入堆栈的最后,可以从一开始就将作业从关闭:只要确保发出作业的代码是线程安全的(少于两个作业从堆栈中抽取相同的作业)。
  • 工作者线程可以非常简单 – 访问调度程序,请求下一个工作:如果有工作,那么工作发送结果,否则睡觉一段时间,重新开始。

这样,你永远不会阻止Apache的时间超过需求,因为你所做的只是发出“do x”或“给我结果给x”的请求。 您可能需要在几个方面构建一些安全功能,例如处理失败的任务,并确保客户端有超时,因此不会无限期地等待。

对于号码2:您可以通过使用JSONP解决跨域限制。

三种选择:

  1. 使用nginx 。 这意味着你运行3个服务器:nginx,Apache和你自己的服务器。
  2. 在自己的端口上运行你的服务器
  3. 使用Apache mod_proxy_http (作为你自己的建议)。

我已经确认mod_proxy_http(Apache 2.2.16)可以代理在GlassFish 3.1.1中运行的Comet应用程序(由Atmosphere 0.7.1支持)。

我的测试应用程序完整的源代码在这里: https : //github.com/ceefour/jsfajaxpush