代理-服务器拓扑结构中的服务器推送与客户端拉取

8
我需要创建一个由两个组件组成的系统:
- 一个单一的服务器,用于处理和存储数据。它还会定期向代理发送更新。 - 多个代理安装在远程端点。这些代理在长时间运行的操作中收集数据,但不总是如此,这些数据需要传送到服务器。
我正在使用C# .NET,并希望使用符合标准的通信方法(即可以与Java一起使用的理论上可行的方法,因为我们未来可能也会使用Java代理)。除了Web服务外,还有其他选择吗?我的选项是什么?
在使用Web服务时,我认为有三种选择,并已做出以下观察:
- 客户端拉取
- 代理无需打开端口,因为它充当客户端 - 需要轮询服务器以获取更新
- 服务器推送
- 代理需要打开端口,因为它充当服务器 - 服务器必须轮询代理以获取结果
- 混合
- 代理需要打开端口,因为它既充当客户端又充当服务器 - 不需要轮询;服务器在需要时推送更新,客户端在结果可用时发送结果
“混合”(代理既是客户端又是服务器)似乎是显而易见的选择,但该应用程序通常会安装在企业和政府环境中,我担心他们可能会对代理打开端口有问题。我在过度考虑这个问题吗?
我是否遗漏了其他的优缺点?
4个回答

6

我们的朋友在 http://www.infrastructures.org 上推崇基于拉取(pull-based)的机制:http://www.infrastructures.org/papers/bootstrap/bootstrap.html

他们更喜欢客户端拉取而不是服务器推送的主要原因是,客户端可能会关闭,而且客户端必须(一般情况下)应用服务器推送的所有操作。如果您的情况没有这个标准很重要,也许他们的结论并不适用于您的情况,但我认为值得阅读他们的论文中 "Push vs Pull" 部分来自己判断。


关于端口的问题:我认为大多数网络管理员会意识到,无论是起点还是终点发起的网络通信都具有相同的风险,如果打开代理的端口可以实现更清晰的架构,那么就应该允许。只需威胁将所有流量隧道化通过80号端口,他们就会明白拥有自己的端口是一种好处了。 :) - sarnold
呵呵,虽然我很想这么做,但我认为如果我这么说,NIST可能不会太高兴 :) - Cocowalla
1
此外,您只需要不断保持一个节点处于“上线”状态,系统就能持续运行。一旦修复,重新启动一个已停止的拉取客户端比处理一个已停止的推送客户端更容易。 - Jon Hanna

3
我认为在当今时代,你可以严肃考虑只使用拉取技术。推送技术存在问题,因为客户端通常隐藏在网络地址穿透设备(NAT)后面,例如无线路由器、宽带调制解调器或公司防火墙,通常情况下无法从服务器访问到客户端。
主动建立出站连接(“phone-home”),特别是在像HTTP/HTTPS这样的众所周知的端口上,基本上可以假定在大多数受限网络中都是“可能”的。

我认为这个应用程序只会在企业环境中使用(当然涉及到防火墙)。我不认为代理向服务器发出的外部连接是一个问题,但企业可能不愿意允许代理的入站连接 - 你怎么看? - Cocowalla
企业网络管理员通常对于开放新的入站端口非常挑剔。如果您可以遵守“客户端始终在 HTTP 上提取”的限制(即应用程序可以在 Web 浏览器中运行),部署将更加轻松。当然,并非每个应用程序都能满足这样的约束条件,我无法了解您的具体情况。 - Remus Rusanu

2
如果您使用某种消息服务器(Java的JMS,对于C#不确定),那么您的消息服务器是唯一需要打开端口的服务器,您可以从代理到消息服务器和从服务器到消息服务器进行双向通信。这将使您能够实现混合模型,而无需在代理服务器上打开端口。

我也考虑过在.NET中进行双向通信,但像RMI一样,它不符合标准 :) - Cocowalla

2

在我看来,我认为你最好的选择是拉取选项。它可以满足以下主要系统要求:

第一部分:数据需要到达服务器,显然可以通过调用将该数据作为参数发送的Web方法来完成。

第二部分:(服务器定期向代理发送更新):您仍然可以通过某种Web服务方法来进行客户端(常规)轮询,以“询问”自上次轮询以来的更新(获取它错过的更新的时间戳)。

混合方法对我来说有点奇怪,因为我认为代理是系统的一部分,可能会经常“离线”,如果发生这种情况,服务器会怎么做?这通常是一个棘手的问题/决策,特别是如果您不确定这是否是预期的“离线”还是系统/网络故障等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接