在通用服务器环境中学习Spring和php的优点


Taking the good parts of both Spring and php in a common server environment

我的建议听起来可能很奇怪,但我有自己的理由。

很长一段时间以来,我们一直有这种基于Spring的API,它最初是作为一组用于CRUD功能的抽象REST服务。然而,随着时间的推移,我们开始在上面构建业务和表示层,直到我们到达了一个死胡同的状态。不要误解我的意思,Spring/HHibernate是很棒的框架,构建在JVM之上有其明确的优势,包括与其他web技术(如PHP)相比的性能。与PHP相比,它为我们提供了一种更深入的控制方式,如事务处理、多线程、处理字节数据、控制原生C++应用程序、使用JNI等

堆栈明显遇到困难的地方,是需求最经常更改的地方,即业务层和表示层。将应用程序转变为现代的、以用户为中心的社交应用程序,我们经历了职业生涯中最严峻的挑战。Java EE表示技术很难使用。此外,由于构建测试和部署大规模Java应用程序的传统障碍,更改业务需求成为一个漫长的循环。

在很大程度上,我们也在努力重新发明轮子。在PHP世界中,已经存在了很多项目,它们为您提供了一个完整的管理系统,与任何类型的后端系统无关(将钩子映射到REST/SOAP端点)。他们中的许多人已经准备好了所有这些功能,允许对场景和规则进行管理友好的更改,并具有模板等。此外,基于PHP意味着在构建和部署方面绝对不会浪费时间。编写更改、测试、确认其有效并切换。

我们现在的想法是找到一种方法,在这样一种基于前端服务器PHP的应用程序中移动业务层和表示层,并将纯后端的东西留给Spring/HHibernate。不过,由于我们对Spring相对缺乏经验,我们有一些担忧。

  1. 如果我们使用PHP方法实现业务方法,我们如何保持事务安全性?我的意思是,如果一个业务方法必须向JAVA发出三个单独的HTTP请求,那么我们如何保证它们都将在同一事务中执行呢?

  2. 有没有办法在两个系统之间使用代理或promise对象?例如,如果PHP业务方法需要调用一个Spring搜索方法,从数据库中获取一个对象集合,然后将其传递给另一个Spring方法,这意味着整个集合必须来回发送。也许,可以将其存储在JAVA端的会话对象中,并简单地将一个空代理发送回前端,前端可以将其发送回另一个jav方法。

  3. 我们的许多基于Spring的功能依赖于使用Spring事件的插件结构。我们如何才能让我们的前端服务器也能在发生的每一个确认事件中得到通知。我有两个想法:一个后处理过滤器,它只需使用一些命名约定向前端服务器上的控制器发出post请求。或使用某种消息队列,如JMS或RabbitMQ,或者为什么不使用像Reddis这样的消息队列,在那里可以观察数据的变化

以前有人这样做过吗?总的来说,这是个好主意吗?如何解决上述问题有什么建议吗?

这不是你所问的,但我认为值得一提的是,你在Java中遇到的一些问题是大多数有经验的Java开发人员有朝一日面临的问题,而且大多数开发人员都找到了一些解决方案。例如,您可以使用Arquillian在Java中进行"更快"的TDD。您可以使用JRebel来执行"代码和刷新"方法,就像在PHP中一样。现代IDE也有助于重构,这有助于"需求更改"场景。

诚然,表示部分仍然是Java的一个大问题。我个人不喜欢JSF,而且(对我来说)大多数其他的表示技术要么不直观,要么很麻烦。

我想说的是,这就是为什么许多Java开发人员正在成为前端采用HTML5和Javascript(backbone.js、undercore.js、jquery…)的原因,后端采用REST。有没有需要有PHP在中间。

恐怕我无法回答您的其他问题,但也许一个好的开始是看看PHP是否可以在JavaEE容器中运行?我知道这适用于Ruby和Python应用程序,因为JRuby和Jython将负责连接两个世界的桥梁。

在很大程度上,您想要做的是我们所说的:SOFEA

在这种情况下,PHP是您的前端,Java是您的服务层。

问题1

基于传统REST或WS的事务是PITA。要么考虑聚合您的服务调用来做更多的工作,使整个事务处于一个服务调用中,要么让Java处理您的前端。否则,请参阅Finagle的问题3

问题2

我建议您保持无状态,并执行REST或RCP。这听起来像是你关心速度,我认为你不应该担心,直到它成为问题。但是,如果您确实想对对象进行基于用户的缓存,我会使用Redis及其pub/sub功能(或RabbitMQ+memcache)。

问题3

使用RabbitMQ、Redis或/和Finagle。

我的最终意见

我认为您不需要PHP,特别是如果您了解Java的话今天的网络应用程序世界大部分都在向Javascript(在客户端)发展,当有更好的选项(如Node.js)或只是坚持使用Java时,我认为使用PHP这样的服务页面没有任何好处。

而@jpkrohling是对的。。。模板化和frotend过去在Java中很糟糕,但现在好多了,尤其是因为大多数UI代码都是用Javascript编写的。如果你需要一个Java中更现代的web内容的例子,请看看这个项目:MWA,以及同一作者的:Java中的Handlebars。

总结一下我的观点,回到SOFEA:backend=Java和frontend=Javascript

以前没有这样做过,不确定这是否是个好主意,但以下是对您的问题的一些想法:

  1. 首先,在PHP世界中,每个请求(无论是否使用keep-alive)都是作为一个独立的进程运行的,因此这种情况通常是闻所未闻的;可以使用持久数据库连接,但是在请求完成后,任何未提交的事务都会自动回滚。现在,这就是我对Spring缺乏了解的地方,因为我不确定只要使用相同的HTTP连接,Java是否可以在请求之间保持数据库连接的相同状态;如果是这样,您可以使用PHP+cURL来执行三个HTTP请求,同时重用网络连接。

  2. PHP和Java之间的对象(取消)封送可能不会很好地工作;集合的表示可能必须以结果标识符的形式进行,该标识符可以由PHP通过REST获取,并作为不透明字符串传递回Java。

  3. 需要注意的是,PHP请求通常是短暂的,这使得它成为水平扩展的一个很好的候选者;因此,长时间运行的进程,如Pub/Sub系统的进程,很少出现。就我个人而言,我更喜欢使用发送HTTP请求的替代方案,这样前端缓存就可以从Java服务中抽象出来。

当我想到其他问题时,我会添加更多,如果我的回答给你更多的问题,请告诉我:)

绝对没有直接的解决办法。您必须重写后端控制器层,该层向PHP公开REST调用。您需要对一些细粒度服务进行分组,并使它们具有粗粒度。

一句忠告——你可以通过在这里和那里进行调整,引入队列或另一个框架或库等,让事情在最后一天正常工作——但你也会引入很多意外的复杂性。。在未来的维护、错误修复、升级等过程中,情况可能会变得非常糟糕。

如果开发速度是一个问题,可以探索其他替代方案,如Play Framework 1.2.x框架,这样您就可以按原样重用服务器端代码。