本地应用之间使用Restful通信是一个好主意吗?

9
我想知道让本地应用程序(在同一服务器上)完全通过Restful API相互通信是否是一个好主意?
我知道这不是什么新鲜事物,因为我们已经有像CouchDB这样的应用程序使用HTTP REST进行通信,即使是与本地应用程序也是如此。
但我想将其提升到更高的级别,创建像大型应用程序的模块一样的应用程序,它们也可以成为另一个应用程序的模块,依此类推。换句话说,会有很多本地应用程序/模块通过Restful API进行通信。
这样,这些应用程序/模块可以使用任何语言,并且它们可以在服务器之间通过网络进行通信。
但我有一些问题:
  • 这是一个好主意吗?
  • 它们之间的数据传输会很慢吗?
  • 如果我这样做,那么每个应用程序/模块都必须是一个HTTP服务器,对吗?因此,如果我的应用程序使用100个应用程序/模块,那么每个应用程序/模块都必须是一个本地HTTP Web服务器,每个运行在不同的端口上(http://localhost:81,http://localhost:82http://localhost:83等),对吗?
  • 有什么最佳实践/陷阱需要我知道的吗?
5个回答

6
  • 这是一个好主意吗?

也许吧。

  • 它们之间的数据传输会很慢吗?

是的!但与什么相比呢?与本地内部调用相比,绝对会很慢。与其他网络API相比,嗯,并不一定更慢。

  • 如果我这样做,那么每个应用程序/模块都必须成为HTTP服务器,对吗?因此,如果我的应用程序使用100个应用程序/模块,我必须启动100个本地HTTP Web服务器,并且每个服务器都有不同的端口(http://localhost:81,http://localhost:82http://localhost:83等)?

不,没有理由为每个模块分配一个端口。有各种方法可以做到这一点。

  • 有任何最佳实践/要注意的问题吗?
唯一成功的方法是使用足够粗糙的服务。这些服务必须是大型、黑盒子式的,使得调用它们的费用值得。每次交易都会产生连接成本、数据传输成本和数据编组成本。因此,您希望这些交易尽可能少,并且要让有效载荷尽可能大以获得最佳效益。
您是在实际使用REST架构还是只是通过HTTP来回发送信息?(这些是不同的事情)REST会产生自己的成本,包括嵌入式链接、普遍和常见的数据类型等。
最后,您可能根本不需要这样做。这可能很“酷”,是“好事”,“白板上看起来不错”,但如果您真的不需要它,那就不要做。只需遵循隔离内部服务的良好实践,以便稍后决定执行此类操作时,可以插入必要的粘合层来管理通信等。添加远程分布将增加风险、复杂性并降低性能(扩展≠性能),因此必须有充分的理由才能这样做。
可以说,这是所有最佳实践中最好的一个。
编辑 - 回应评论:

您的意思是我运行一个Web服务器来处理所有传入的请求?但是这样一来,模块就不会成为独立的应用程序,这违背了整个目的。我希望每个模块都能够自己运行。

不,这并不违背初衷。

具体来说:

假设您有三个服务。

一眼看去,这似乎是三个不同的服务,在三台不同的机器上运行,分别在三个不同的Web服务器上。
但事实上,这些服务都可以在同一台机器上运行,甚至可以(将其推向极致)运行完全相同的逻辑。
HTTP允许您映射各种内容。HTTP本身是抽象机制。
作为客户端,您只关心使用的URL和要发送的有效负载。它最终与哪台机器通信,或者它执行的实际代码不是客户端的问题。
在架构层面上,您已经实现了一种抽象和模块化方式。 URL使您能够根据您想要的任何逻辑布局来组织系统。 物理实现与逻辑视图不同。
这三个服务可以在单个机器上运行,由单个进程提供服务。另一方面,它们也可以代表1000台机器。您认为有多少台机器响应“www.google.com”?
您可以轻松地将所有3个服务托管在单个机器上,而不共享任何代码,除了Web服务器本身。这使得将服务从原始机器移动到其他机器变得容易。
主机名是将服务映射到计算机的最简单方法。任何现代Web服务器都可以为任意数量的不同主机提供服务。每个“虚拟主机”可以在该主机名称空间内为任意数量的个别服务端点提供服务。在“主机”级别,如果必要,可以轻松地将代码从一台计算机转移到另一台计算机。
您应该更多地探索现代Web服务器将任意请求指向服务器上实际逻辑的能力。您会发现它们非常灵活。

不需要为每个模块分配一个端口,这样做没有必要。有很多方法可以解决这个问题。如果每个模块/应用程序都是本地Web服务器,那么它们如何在不运行在不同端口的情况下使用? - ajsie
1
正如其他人所提到的,不要在单独的Web服务器上运行它们。一个Web服务器可以处理任意数量的应用程序。这真的取决于服务器资源。考虑一堆CGI脚本,所有脚本都组织在一个目录树中。考虑一个Java Web应用程序服务器,每个WAR文件都是单独部署的,但每个WAR都有自己的上下文,来自同一个主机URL。甚至考虑虚拟主机,一个单独的Web服务器托管100个不同的主机,所有主机共享相同的IP和端口。这些都是在单个服务器上部署多个应用程序的技术。 - Will Hartung
那么你的意思是我运行一个Web服务器来处理所有传入请求?但是这样模块就不会是独立的应用程序了,这违背了整个目的。我希望每个模块都能够自己运行。 - ajsie

5

这是一个好主意吗?

是的。这是常见做法,例如所有的数据库服务器都是这样工作的。Linux中有很多通过TCP/IP通信的客户端/服务器应用程序。

它们之间的数据传输会很慢吗?

不会。TCP/IP使用localhost作为快捷方式来节省实际网络I/O。

HTTP协议不是专用连接的最佳选择,但它简单且得到了广泛支持。

如果我这样做,那么每个应用程序/模块都必须是一个HTTP服务器,对吗?

不一定。有些模块可以是客户端而没有服务器。

所以,如果我的应用程序使用了100个应用程序/模块,那么每个应用程序/模块都必须是一个本地HTTP Web服务器,每个服务器运行在不同的端口上(http://localhost:81、http://localhost:82http://localhost:83等),是吗?

是的。这就是它的工作方式。

有什么最佳实践/注意事项需要我知道吗?

不要“硬编码”端口号。

不要使用“特权”端口号(小于1024)。

使用WSGI库,将所有模块转换为WSGI应用程序,这样您就可以使用一个简单的2行HTTP服务器来包装您的模块。

阅读这篇文章。 http://docs.python.org/library/wsgiref.html#examples


2

在应用程序集成中使用restful解决方案,我认为这是一个好主意,并在另一个问题中表达了类似的观点。


0
坦白说,我认为你不需要为100个应用程序使用100台服务器,也许只需在同一台服务器上使用100个端口即可。
此外,RESTful接口将为您提供灵活性,使您能够扩展服务器并启用负载平衡,如果您想要潜力扩大规模。

实际上我指的是100个本地Web服务器(而不是100个物理Web服务器)。我会编辑一下让它更明确。所以你的意思是,即使我旨在模块化级别而不是全栈应用程序,这也是一个好主意? - ajsie
@weng:很抱歉,我仍然不太明白为什么要有100个Web服务器来提供100个Web应用程序的想法。我相信大多数Web应用程序,如果不是全部都可以部署到同一台服务器上并且良好协作,只要它们不在监听端口上发生冲突。 - Michael Mao
@weng:此外,RESTful Web服务依赖于URL模式来匹配您正在调用的应用程序。因此,多个应用程序可以在共享默认80端口的同一Web服务器上工作。 - Michael Mao
现在我明白为什么我的问题让人困惑了。所以我会尽量更准确地表达。我所说的100个Web服务器实际上是指100个应用程序,它们本身就是Web服务器,而不是为100个应用程序提供信息的100个Web服务器。我已经编辑了我的帖子,使其更加清晰明了。 - ajsie
如果多个应用程序在同一个端口上运行,难道我不需要在这些应用程序前面放置一个路由器吗?但是如果我这样做的话,每个应用程序都不会成为一个Web服务器,因此它们将无法使用RESTful通信。而且,这样做会使一个应用程序无法被单独使用。 - ajsie

0

如果没有充分的理由,那么这不是一个好主意。最好将应用程序的代码分层,以便在以后需要时可以进行“休息”(或者进行任何被认为必要的性能改进)。“基于服务器的层”的部署复杂性增加是不这样做的一个很好的理由。我建议:

  • 编写结构良好、代码清晰的应用程序。
  • 使用预期的生产负载进行测试
  • 如果需要-重构成为服务器层-但是.....

更好的方法是负载均衡整个应用程序。如果你正在做像Rails这样的应用程序服务器中没有状态的事情,那么并行运行几个实例应该不成问题。

如果你正在寻找复杂性,请忽略我的答案。 :-)


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