微服务背后的大理念是将大型、复杂且历时长久的应用在架构上设计为内聚的服务,这些服务能够随着时间的流逝而演化。本文主要介绍了利用 Java 生态系统构建微服务的多种方法,并分析了每种方法的利弊。

快速预览

在 Java 生态系统中构建微服务的策略主要有:container-less, self-contained 和 in-container;

Container-less 微服务把应用程序及其所有依赖打包成单一的 jar 文件;

Self-contained 微服务也会将应用及其依赖打包成单一的Jar文件,但它还包含可能含有第三方库的嵌入式框架;

In-container 微服务会打包一个完整的 Java EE 容器,并且它的服务是在 Docker image 中实现。

基于微服务的架构设计是架构师和程序员们面临的一项新挑战。然而,随着语言及工具的不断更新,架构师们完全有能力征服这样的挑战。Java 也不例外,本文探讨了使用Java生态系统来构建微服务的几种不同方式。

介绍

本文不会讨论微服务的好与坏,也不会建议你提前为微服务设计应用程序,或当它们出现在你庞大的应用中时,是否应该剥离这些微服务。

本文介绍的方法并不是唯一的,但应该可以达到抛砖引玉的效果。尽管本文的重点是使用 Java 生态系统来构建微服务,但这些概念同样可以转移到其它语言和技术中。

笔者把本文用到的方法命名为 container-less、self-contained 和 in-containe。这些名称或许不是非常正式,但足以区分相互间的差别。接下来,笔者会详细描述每种方法。

Container-less

在此方法中,开发者会将 JVM 之上的任何事物视为应用程序的一部分。

container-less 方法会启用所谓的单 jar 部署(也可称作“fat jar部署”),这也就意味着,应用程序及其所有依赖都会被打包成单一的jar文件,并且作为独立的Java进程运行。

$java -jar myservice.jar

该方法的第一个优点就是当对应用的规模进行伸缩时,服务很容易按需求快速启动和停止;另一优点是方便部署,你只需要传递一个 jar 文件即可。

该方法的缺点就是库的兼容性。对于事务支持这类问题,你需要自己来实现,或必须引入第三方库才能实现。而后,如果你需要更多支持,例如持续性问题的支持,你就需要解决第三方库之间的兼容性问题。

Self-contained

另一种单 jar 部署就是使用一个嵌入式框架来构建服务。在此方法中,框架提供了所需服务的实现方法,开发者可以选择在项目中包括哪些服务。

你可能会认为这个方法与 container-less 完全一样,但笔者认为,两者的区别在于,self-contained 方法会提供一套相互兼容的第三方库。所以,该方法不存在库兼容性问题。

该方法可能涉及 Spring Boot、Wildfly Swarm 之类的工具。

Spring Boot

在Java中, Spring Boot 和 Spring Cloud Netflix 项目对构建微服务提供了很好的支持。 Spring Boot 允许你选择各种 Spring 工具和其它流行的工具,然后把它们和你的应用打包成一个 jar 文件。 Spring Initializr 提供了一个简单的复选框列表来完成上面这些事。一个简单的Hello World服务示例如下: Gist Snippet

Wildfly Swarm

在 Java EE 中,和 Spring Boot 相对应是 Wildfly Swarm 。它允许你根据自己的需求挑选 Java EE 规范,然后把它们和你的应用程序打包成一个 jar 文件。这里有一个简单的 Hello World 示例: Gist Snippet 。

self-contained 方法的优点是你可以自主选择用于服务运行的项目。

这种方法的缺点是配置更加复杂,由于它在实际的服务中构建所需的容器功能,由此产生的 jar 文件也会稍大一些。

In-container

虽然在 Java EE 容器中部署微服务的开销似乎很大,然而,一些开发者认为,微服务中的“微”并不表示该服务的小或者简单。

在这些案例中,将 Java EE 容器作为所需平台似乎是合适的。因此,你唯一需要的依赖就是 Java EE API 。注意,由于该依赖的实现是由容器提供的,因此该依赖项已经满足了,这也就意味着所产生的 war 文件是非常精简的,该服务的实现与上面 Wildfly Swarm 的例子是一样的: Gist Snippet 。

该方法的优点是,容器通过标准 API 提供了经过测试和验证的标准功能的实现。因此,开发者可以完全聚焦于业务功能,并在应用代码之外维护底层代码。

另一个优点是,应用程序代码不依赖 Java EE 应用服务器,无论该应用部署到 GlassFish 、 WildFly 、 WebLogic 、 WebSphere 还是任何与 Java EE 兼容的其他实现系统。

该方法的缺点是你需要把服务部署到容器中,这样就增加了部署的复杂性。

Docker

现在来谈谈 Docker 。通过把 Java EE 容器和服务实现打包到 Docker 镜像,你可以得到与单一 jar 部署相似的结果。唯一的不同是服务打包在 Docker 镜像中,而不是在 jar 文件中。

DockerfileFROM jboss/wildfly:9.0.1.FinalADD myservice.war/opt/jboss/wildfly/standalone/deployments

在 Docker 引擎中启动 Docker 镜像可以唤醒服务:

$ dockerrun-it-p8081:8080myorganization/myservice

Snoop

细心的读者可能已经在先前的 Spring Boot 代码段中注意到了 @EnableEurekaClient 注解。该注解在 Eureka 中注册服务,使其能够被服务消费者发现。 Eureka 是 Spring Cloud Netflix 包的一部分,并且是一个极易使用和配置服务发现的解决方案。

Java EE 在外部并没有提供这样的功能,但是有一些开源解决方案可以使用,其中一个就是 Snoop , 它的功能与Eureka相似 。要使 Java EE 微服务支持任务查找,唯一要做的是使用 @EnableSnoopClient 注解,如本例所示: Gist Snippet 。

总结

在构建微服务时, Java 是一个非常好的选择。本文中介绍的任何一种方法都可以实现微服务。当然,最好的方法还是根据服务需求而定。对于简单的服务, container-less 或者 self-contained 服务就是不错的选择。不过,借助 in-container ,开发者可以更快更简单地实现更高级的服务。无论针对哪种服务,Java 生态系统都能提供行之有效的实现方法。

写在最后:欢迎留言讨论,欢迎关注,持续更新!

十年阿里顶级架构师教你怎么使用Java来搭建微服务的更多相关文章

  1. 阿里高级架构师教你使用Spring Cloud Sleuth跟踪微服务

    随着微服务数量不断增长,需要跟踪一个请求从一个微服务到下一个微服务的传播过程,Spring Cloud Sleuth 正是解决这个问题,它在日志中引入唯一ID,以保证微服务调用之间的一致性,这样你就能 ...

  2. 阿里高级架构师教你使用Spring JMS处理消息事务源码案例

    消费者在接收JMS异步消息的过程中会发生执行错误,这可能会导致信息的丢失.该源码展示如何使用本地事务解决这个问题.这种解决方案可能会导致在某些情况下消息的重复(例如,当它会将信息储存到数据库,然后监听 ...

  3. 阿里高级架构师教你如何使用Spring Cloud Ribbon重试请求

    在微服务调用中,一些微服务圈可能调用失败,通过再次调用以达到系统稳定性效果,本文展示如何使用Ribbon和Spring Retry进行请求再次重试调用. 在Spring Cloud中,使用load b ...

  4. Kubernetes实战 - 从零开始搭建微服务 1 - 使用kind构建一个单层架构Node/Express网络应用程序

    使用kind构建一个单层架构Node/Express网络应用程序 Kubernetes实战-从零开始搭建微服务 1 前言 准备写一个Kubernetes实战系列教程,毕竟cnblogs作为国内最早的技 ...

  5. 阿里P8架构师深度概述分布式架构

    简介 作为一名架构师,我们要专业,要能看懂代码,及时光着臂膀去机房,也能独挡一面!及时同事搞不定问题,或者撂挑子,你也能给老大一个坚定的眼神:不怕,有我在!还能在会议室上滔滔不绝,如若无人,让不懂技术 ...

  6. 阿里P8架构师谈:MySQL慢查询优化、索引优化、以及表等优化总结

    更多内容:https://www.toutiao.com/i6599796228886626829/?tt_from=weixin&utm_campaign=client_share& ...

  7. 阿里P8架构师谈:数据库分库分表、读写分离的原理实现,使用场景

    本文转载自:阿里P8架构师谈:数据库分库分表.读写分离的原理实现,使用场景 为什么要分库分表和读写分离? 类似淘宝网这样的网站,海量数据的存储和访问成为了系统设计的瓶颈问题,日益增长的业务数据,无疑对 ...

  8. Java开发不懂Docker,学尽Java也枉然,阿里P8架构师手把手带你玩转Docker实战

    转: Java开发不懂Docker,学尽Java也枉然,阿里P8架构师手把手带你玩转Docker实战 Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一 ...

  9. 百度架构师带你进阶高级JAVA架构,让你快速从代码开发者成长为系统架构者

    百度架构师带你进阶高级JAVA架构,让你快速从代码开发者成长为系统架构者 1.

随机推荐

  1. PAT 甲级 1042 Shuffling Machine (20 分)(简单题)

    1042 Shuffling Machine (20 分)   Shuffling is a procedure used to randomize a deck of playing cards. ...

  2. PAT 甲级 1035 Password (20 分)(简单题)

    1035 Password (20 分)   To prepare for PAT, the judge sometimes has to generate random passwords for ...

  3. (九)UML之活动图

    一.概念 二. 在Rational rose 中画活动图 2.1 创建Activity Diagram 2.2 画图

  4. Spring Cloud(7.2):配置Producer Server

    我们首先创建一个生产者服务.这里以一个商品价格服务为例,这个微服务可以对商品-价格信息进行增删改查,当有商品-价格信息被更新或删除,则该微服务发送消息,告诉其他调用它的系统这条信息已经被修改. 配置p ...

  5. 【数据库开发】MySQL修改root密码

    方法1: 用SET PASSWORD命令 mysql -u root mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass ...

  6. Spring 使用复选选按钮

    模型层需要提供数据选项,设置错误信息 关键代码 @NotNull @Size(min = 1, max = 5, message = "选择课程") private String[ ...

  7. Lamda

  8. [转帖]关于DDR4内存颗粒、单双面、主板布线和双通道的那些事儿

    我们200期的期中测试大家都做了吧,今天我们放出了完整的答案,想知道自己错在哪儿的同学赶紧过去看哟=><这次期中考试你拿到满分了吗?没有就快去补习吧> https://www.exp ...

  9. Navicat 导入,导出数据 etc

    Navicat 不仅做了分页查询, 显示 `SELECT *,rowid "NAVICAT_ROWID" FROM "main"."Table_100 ...

  10. 解决RabbitMQ消息丢失问题和保证消息可靠性(一)

    原文链接(作者一个人):https://juejin.im/post/5d468591f265da03b810427e 工作中经常用到消息中间件来解决系统间的解耦问题或者高并发消峰问题,但是消息的可靠 ...