我正在开发一个程序,该程序将具有多个线程,需要来自可以处理请求的网络服务的信息,例如:
“给我 [Var1, Var2, Var3]
用于 [Object1, Object2, ... Object20]
”
在这种情况下,得到的回复将给我一个 20 节点的 XML(每个对象一个),每个节点有 3 个子节点(每个 var 一个)。
我面临的挑战是,针对此 Web 服务发出的每个请求都会花费组织的钱,无论是针对 1 个对象的 1 个变量还是针对 20 个对象的 20 个变量,成本都是相同的。
因此,既然如此,我正在寻找一种架构:
- 在需要数据时在每个线程上创建一个请求
- 有一个中间层“聚合器”来获取所有请求
- 一旦聚合了 X 数量的请求(或达到了时间限制),中间层将执行 Web 服务的单个请求
- 中间层接收来自网络服务的回复
- 中间层将信息路由回等待对象
目前,我的想法是使用像NetMQ 这样的库。我的中间层作为服务器,每个线程作为轮询器,但我陷入了实际的实现,在深入兔子洞之前,我希望已经有一个设计模式/库可以做到这比我想象的要有效得多。
请理解我是菜鸟,因此,非常感谢任何帮助/指导!!
谢谢!!!
最佳答案
概览
从架构的角度来看,您只是草拟了一个解决问题的好方法:
- 在请求应用程序和远程 Web 服务之间插入代理
- 在代理中,将请求放入请求队列,直到至少发生以下事件之一
- 请求队列达到给定长度
- 请求队列中最早的请求达到一定年龄
- 将请求队列中的所有请求归为一个请求,删除重复的对象或属性
- 将此请求发送到远程网络服务
- 将请求移入(等待)响应队列
- 等待响应,直到发生以下情况之一
- 响应队列中最早的请求达到一定年龄(超时)
- 收到回复
- 获取响应(如果适用)并将其映射到响应队列中的相应请求
- 回答响应队列中所有有答案的请求
- 为所有早于超时限制的请求发送超时错误
- 从响应队列中删除所有已响应的请求
技术
您可能找不到完全符合您要求的现成产品或框架。但是,您可以使用多种框架/架构模式来构建解决方案。
C#:RX 和 LINQ
当你想使用 C# 时,你可以使用 reactive extensions以获得正确的时间和分组。
然后您可以使用 LINQ从请求中选择属性以构建响应,并在响应队列中选择与响应的特定部分匹配或超时的请求。
Scala/Java:阿卡
您可以使用多个参与者将解决方案建模为参与者系统:
- 作为请求网关的参与者
- 持有请求队列的参与者
- 参与者将请求发送到远程 Web 服务并获得响应
- 持有响应队列的参与者
- 发送响应或超时的参与者
Actor 系统可以轻松处理并发并以可测试的方式分离关注点。
当使用 Scala 时,您可以使用其“monadic”集合 API(filter
、map
、flatMap
)来完成与在 C# 方法中使用 LINQ。
当您想要测试单个元素时,actor 方法非常有用。这很容易to test each actor individually ,而不必模拟整个工作流程。
Erlang/Elixir:Actor 系统
这类似于 Akka 方法,只是使用不同的(函数式!)语言。 Erlang/Elixir 对分布式 actor 系统有很多支持,所以当你需要一个超稳定或可扩展的解决方案时,你应该研究一下这个。
NetMQ/ZeroMQ
这可能级别太低,只涉及很少的基础设施。当您使用 actor 系统时,您可以尝试引入 NetMQ/ZeroMQ 作为传输系统。
关于java - 用于 coSTLy 请求的请求聚合器/中间层设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30667389/