我正在用Java编写一个守护进程,该守护进程接收来自多个提供商的请求,其中提供商将返回服务对象守护进程作为线程运行。
应用程序架构:
主要课程 基本上加载配置文件,初始化所需的库等。一旦守护进程初始化,它将遍历所有提供程序并初始化它们。之后,守护进入无限循环,不断地通过均匀分布的每个提供商,并尝试获取新的服务。
提供商 提供者基本上是第三方服务的适配器。这可以是电子邮件,传真,作业队列,数据库等。初始化提供程序时,它连接到第三方服务。每当应用程序从提供程序中提取新的服务对象时,它都会检查第三方服务,如果找到新请求,则会对其进行解析,然后返回新的服务对象申请。
服务 服务基本上是一项专门的工作。当提供程序获取新请求时,它会返回与请求相关的特定服务类型。当应用程序运行新的服务线程时,它将处理请求然后关闭。
这是一个例子,虽然它可能不会像这样使用。创建一个新的提供程序,用于侦听HTTP端口。一个新的HTTP请求进来,要求处理一个字符串(反转它)并将其存储在数据库中。一个新的请求进入,提供程序将服务返回给应用程序,应用程序启动一个新的服务,其中反转字符串并更新数据库。更新后,应用程序会看到作业已完成,并且可以从另一个提供商中获取新作业。
问题: 是否有像MVC这样的设计模式可以处理这样的架构?我意识到MVC是一个非常糟糕的术语,因为它包含多个模式。我想我要问的是,我的方法还可以吗?采用MVC背后的概念并将其移至此应用程序是否是一个好主意?提供者是控制者,服务是与模型相关的行为?虽然此类应用程序中从未有任何观点。
修改
由于
答案 0 :(得分:3)
根据您需要扩展的规模,您可能需要考虑像JMS这样的消息传递服务。您的生产者和消费者(即提供者和响应者)可以发布和收听适当的JMS主题。
答案 1 :(得分:2)
Web服务器(而不仅仅是HTTP类型)使用请求/响应模式。套接字侦听器等待传入连接,使用请求工厂创建Request对象,然后将其传递给返回响应对象的处理程序(或者工厂也创建响应对象,处理程序只修改它)。
在HTTP世界中,处理程序由URL和URL参数标识,或POST数据变为请求数据。响应(通常是一些HTML页面)从响应对象编码并发送回浏览器。
答案 2 :(得分:2)
你所描述的内容听起来很像enterprise integration patterns解决的问题。
支持这些模式的轻量级Java库是Apache Camel或Spring Integration之类的东西,或者您可以使用像ServiceMix或Mule这样的完整企业服务总线。
以下是您的条款的粗略翻译:
主类 - 在完整的ESB中,这将是ESB本身,即应用程序服务器。您可以自己编写,也可以使用现有的ESB或OSGI等通用应用程序服务器。
提供商 - 渠道适应器。
服务 - 这些将是各种组件。有些可能是EIP组件,如Message Transformers,Service Activators或其他Channel Adapters。
答案 3 :(得分:1)
根据我对您所描述的要求的理解,我确实有一些建议。
免责声明:我并不真正了解您的扩展要求或资源限制,如果您正在运行守护程序,这些可能很重要。与往常一样,即将采取的一些建议。
我最初的反应是,可能没有单一的设计模式可以解决您的整个问题,但是有一些设计模式可能会帮助您完成它的小节。
1)听起来您的Main类将轮询提供者。您可能想要做更多消息驱动的事情。如果/何时需要扩大规模,请查看Observer pattern和相关的publish/subscribe pattern。
2)您可能想要考虑为您的提供商预先分配thread pools。它可能不是绝对必要的,但它可能对您的特定情况有意义。
3)根据您的描述,您可能会进入architecture astronaut领域(即在您需要之前概括所有内容)。除非您要分发API或让很多人在使用/重新使用此代码,否则我会提醒您不要采取这种行为:这是一个很大的时间问题,如此高的目标是令人沮丧的实现初始目标的一小部分。
有些建议可能不会直接适用于您的问题,但我希望它有所帮助。
答案 4 :(得分:1)
非Java特定(我指的是一种通用方法,而不是在使用Java时不适用的方法)是使用Aaron Digulla所述的简单请求/响应方法。这是一个非常常见的场景,但很容易过度工程(实际上,它非常简单易懂,特别是在使用适当的支持库时)。
如果用于添加/删除数据库的web服务的应用程序超过200-300行代码,那么它可能过度设计(即使有合理的错误处理和动态配置)。
如果您的数据库支持锁定和强制执行唯一性(以及事务,如果您需要这种功能),我建议您不要通过编写锁定恶魔来使事情过于复杂 - 只需让数据库处理它并处理例外。
如果你真的需要做锁定(例如,因为你正在写一些外部服务,比如一些硬件)那么你可以使用典型的UNIX方法来锁定资源并编写一个在本地运行的单实例守护进程您的所有Web服务都可以与之通信的套接字 - 取决于它是否指示资源繁忙,它们可以拒绝请求或将它们排队(例如在排队系统的内存中,SQL DB中的表等),并使用守护程序进程排队请求(也与锁定服务对话)。
为了让事情变得非常简单,你总是可以始终从Web服务向队列系统推送请求,我建议除非你需要区分“此行动现在正在执行”和在您提交请求的客户的回复中,“此操作已排队”。
对于界面本身,我个人赞成的东西是广泛认可的开放标准,易于实现和高度可解释,如Document / Literal SOAP服务,优先于RPC / encoded(不赞成和恶意)或JMS(这是专有的,虽然在实践中得到了不同程度的广泛支持)。
如果您正在编写一个专门的内部服务而且您只是一个Java商店,那么JMS非常适合,但如果它不是内部应用程序,那么最好是很好地玩,而不是假设其他人都想要只使用JMS客户端与你的服务交谈(我传播Doc / Lit SOAP,因为它可以通过任何东西进行解析,甚至可以处理基本的XML并且是WS-I认可的。)