• 1
  • 2
  • 3
  • 4
  • 5
阿里云应用开发 首 页  »  帮助中心  »  云服务器  »  阿里云应用开发
怎样使用 Java 和 Docker 构建微服务
发布日期:2016-7-9 21:7:47

  快速浏览

  在Java生态中,构建微服务的策略包括Container-less,Self-contained,以及In-container等。

  Self-contained微服务也是打包成一个单一的Jar文件,但是它还包括一个嵌入式框架,这个框架含有可选的第三方lib,当然这些lib是兼容的。

  Container-less微服务将应用以及其依赖打包成一个单一的jar文件。

  In-container微服务打包成一个完整的Java EE容器,该服务在Docker镜像中实现。 基于微服务的架构给架构师和开发者带来了新的挑战,然而随着语言的升级和工具数量的增加,开发者和架构师完全有能力应对这样的挑战。Java也不例外,本文探讨了在Java生态系统内构建微服务的不同方法。

  介绍

  本文不会探讨微服务是好还是坏,也不会建议你应该事先使用微服务设计你的app,或当他们在monolith应用出现的时候,就应该提取这些服务。这里所描述的方法并不是唯一的,但是它可让你对这些可能性有一个良好的纵览。即使Java生态是本文所关注的领域,但是这些理念也可以传递到其他语言和技术中。在文中,我将这几种方法分别称为Self-contained,Container-less及In-container。这些术语也许尚未被完全确立,但是在这里,它们可达到区分这几种方法的目的。我会在接下来的几个部分中阐述它们的意义。

  Spring Boot

  Spring Boot和Spring Cloud Netflix 项目对使用Java构建微服务有着很好的支持。Spring Boot允许你挑选各种Spring生态系统中的工具,及流行的第三方工具,并将这些工具和你的应用打包在一起。Spring Initializr使得你可使用简单复选框列表的方式完全这一工作,这里有一个简单的Hello World服务的例子,Gist Sinppet。

  Self-contained

  另一个单一JAR部署的变形是使用嵌入式框架构建微服务。在该方法中,框架提供了所需服务的实现,同时,开发者可选择哪一些东西要包含在该服务中。你可能认为这与Container-less的解决方案一样,但我在这里要区分一下它们,因为self-cotained方法允许你使用第三方lib库,并且你知道这些lib库是兼容的。

  

  该方法涉及到像Spring Boot和Wild Swarm之类的工具。

  Wildfly Swarm

  在Java EE中,与Spring Boot相对应的就是Wildfly Swarm。它允许你挑选所需的部分Java EE规范,并将其和应用以JAR文件的形式打包在一起。Hello World的例子,Gist Snippet。Self-contained方法的优点是你可只挑选足以让服务运行的组件。该方法的缺点是配置有点复杂,及由此产生JAR文件有点大,因为它的构建是为了实际服务中所需的容器功能。

  container-less

  在Container-less方法中,开发者要将所有位于JVM顶层的一切事物作为应用的一部分。Container-less方法使得所谓的单一JAR部署成为可能(也称作“fat JAR”部署),这意味着,应用以及其依赖可打包在一个单一的JAR文件,并作为一个独立的Java程序运行。

  

  $ java -jar myservice.jar

  这种方法的优点是:当应用在进行扩展和收缩的时候,服务的启动和停止是极其轻松的。另一个优点是部署简单,你只需要传递一个JAR文件。该方法的缺点是lib库的兼容性,你需自己独立解决一些像事务处理之类的事情,或需引入第三方lib库为方案提供支持。若你需像持久性之类的支持,你也许需面对lib库兼容性的问题。

  In-container

  虽然要求一个完整的Java EE容器能部署一个微服务,似乎需很大的开销,但需记住的是:一些开发者主张微服务的“微”不意味着这个服务要微小或者简单。

  

  在这些案例中,将Java EE容器视为所需要平台似乎是合适的,因为你所需的唯一依赖是Java EE API。注意:因为其实现是由容器提供,所以该依赖项已满足。这意味着由此产生的WAR文件是极其精实的,该服务的实现和上述Wildfly Swarm的例子一样,参考这里,Gist Snippet。这种方法的优点是该容器通过标准APIs提供了测试和验证标准功能的实现,因此作为一名开发者,你可完全集中于业务功能,且在应用代码之外维护底层代码。

  该方法的另一个优点是实际应用程序代码并不依赖于部署该代码的Java EE应用服务器,无论是GlassFish,Weblogic,WildFly,WebSphere,或者其他Java EE兼容性实现。该方法的缺点是你需将该服务部署在容器中,这增加了部署的复杂性。

  Docker

  Docker从这里开始。通过将Java EE容器和服务实现打包进Docker镜像,你可或多或少地取得和单一JAR开发同样效果。不同的是服务现在位于容器内,而不是JAR文件中。

  Dockerfile

  FROM jboss/wildfly:9.0.0.1.final

  ADD myservice.war /opt/jboss/wildfly/standalone/deployments

  通过启动Docker引擎中的Docker镜像,唤醒该服务。

  docker run -it -p 8081:8080 myorganization/myservice

  Snoop

  细心的读者可能之前注意到Spring Boot代码段中的@EnableErekaClient注解,该注解在Eureka中进行服务注册,使得它可被服务请求者所发现。Eureka是 Spring Cloud Netflix包中的一部分,它是一种极其容易使用和配置的服务发现解决方案。

  Java EE没在外部提供这样的机能,但是这里有几种开源方案。其中一种就是Snoop,其功能与Eureka类似。为了使一个Java EE微服务可用于服务查找,唯一需要做的是使用@EnableSnoopClient注解,如本例所示:Gist Snippet。

  总结

  在构建微服务的时候,Java是一个很好的选择。这里所描述的方法都可很好地完成任务。至于你个人的特殊情况,最佳方法取决于其服务需求。对于简单的服务,一个container-less或self-contained服务是最佳选择,但是借助于in-container的实现,开发者可更快,更简单地实现高级服务。总之,对于微服务的实现,Java是一种行之有效的生态系统。

  更多关于微服务的见解,JVM语言,以及在Java中的趋势,可在 DZone Guide to the Java Ecosystem!获取到。