Java EE应用程序的单片到微服务重构

您是否曾经想过将现有的Java EE整体应用程序重构为基于微服务的应用程序需要做什么?

该博客解释了一个简单的购物车示例如何转换为基于微服务的应用程序,以及围绕它的一些担忧。 整体和基于微服务的应用程序的完整代码库位于: github.com/arun-gupta/microservices 。

继续阅读以获取更多荣耀!

Java EE Monolith

Java EE整体应用程序通常定义为WAR或EAR档案。 该应用程序的全部功能都打包在一个单元中。 例如,在线购物车可能包含用户,目录和订单功能。 所有网页都在应用程序的根目录中,所有相应的Java类都在WEB-INF/classes目录中,资源在WEB-INF/classes/META-INF目录中。

让我们假设您的整体设计不是设计为一个分散的大泥巴,并且该应用程序是按照良好的软件体系结构构建的。 一些常见的规则是:

  • 分离关注点,可能使用Model-View-Controller
  • 使用定义明确的API的高内聚和低耦合
  • 不要重复自己(干)
  • 接口/ API和实现是分开的,并且遵循Demeter定律 。 类不会直接调用其他类,因为它们恰好位于同一存档中
  • 使用域驱动设计将与域/组件相关的对象保持在一起
  • YAGNI或您不需要它:不要构建您现在不需要的东西

这是一个琐碎的购物车整体WAR存档的外观:

javaee-monolithic

此整体应用程序具有:

  • 网页,例如.xhtml文件,用于用户,目录和订单组件,打包在归档的根目录中。 这些网页还打包了在不同网页之间共享的所有CSS和JavaScript资源。
  • 这三个组件的类在WEB-INF/classes目录中的单独软件包中。 多个类使用的所有实用程序/公共类也都打包在这里。
  • 每个组件的配置文件打包在WEB-INF/classes/META-INF目录中。 该应用程序的任何配置文件(例如分别连接和填充数据存储的persistence.xmlload.sql也都打包在此处。

它具有众所周知的体系结构,IDE友好,易于共享,简化测试,易于部署等常见优点 。 但同时也具有诸如敏捷性受限,持续交付的障碍,技术堆栈“卡住”,技术债务增加等缺点 。

即使微服务如今已成为热门,但整体还是不错的。 即使那些对您不起作用的服务,也可能不会立即迁移到微服务中,从而受益匪浅。 其他方法,例如更好的软件工程和体系结构,可能会有所帮助。 微服务既不是免费的午餐也不是灵丹妙药,它需要大量的投资才能成功,例如服务发现,服务复制,服务监视,容器,PaaS,弹性等等。

除非您的系统过于复杂而无法作为一个整体进行管理,否则甚至不要考虑使用微服务。

微服务高级版

Java EE的微服务架构

好了,我已经听说了所有这些内容,但是想知道之前/之后的内容,即整体代码库的外观以及重构后的微服务代码库的外观。

首先,让我们看一下整体架构:

javaee-microservices

该体系结构的关键部分是:

  • 在将用户,订单和目录组件打包为单独的WAR文件的情况下,应在功能上分解应用程序。 每个WAR文件应具有该组件所需的相关网页( #15 ),类和配置文件。
    • Java EE用于实现每个组件,但是对堆栈没有长期承诺,因为不同的组件使用定义良好的API( #14 )相互通信。
  • 每个档案都有自己的数据库,即不共享数据存储。 这允许每个微服务发展和选择最合适的数据存储类型-关系,NoSQL,平面文件,内存中或其他。
  • 每个组件都将向服务注册中心注册。 这是必需的,因为每个服务的多个无状态实例可能在给定的时间运行,并且它们的确切端点位置仅在运行时才知道( #17 )。 Netflix Eureka , Etcd , Zookeeper是该领域的一些选项( 更多详细信息 )。
  • 如果组件之间需要相互通信(这很常见),则可以使用预定义的API进行通信。 实现同步的REST或实现异步通信的Pub / Sub是实现此目的的常用方法。在我们的案例中,Order组件发现用户和目录服务,并使用REST API与它们进行对话。
  • 该应用程序的客户端交互是在另一个应用程序(在本例中为Shopping Cart UI)中定义的。 该应用程序主要从服务注册表中发现服务并将其组合在一起。 它应该主要是一个哑代理,在其中调用不同组件的UI页面以显示界面( #18 )。可以通过提供标准CSS / JavaScript资源来实现常见的外观。

该应用程序相当琐碎,但至少强调了一些基本的体系结构差异。

整体与微服务

下面比较了基于单体和基于微服务的应用程序的一些统计信息:

特性 整体式 微服务
档案数量 1个 5
  • 合同(JAR,〜4 KB)
  • 顺序(WAR,〜7 KB)
  • 用户(WAR,〜6 KB)
  • 目录(WAR,〜8 KB)
  • Web UI(WAR,27 KB)
网页 8 8(见下文)
配置文件 4
  • web.xml
  • template.xhtml
  • persistence.xml
  • load.sql
每个档案3个
  • persistence.xml
  • load.sql
  • web.xml
类文件 12 26
  • 每个档案的服务注册
  • 服务发现类
  • 每个档案的应用程式类别
档案总大小 24 KB 〜52 KB(总计)

  • 整体应用程序的代码库位于: github.com/arun-gupta/microservices/tree/master/monolith/everest
  • 支持微服务的应用程序的代码库位于: github.com/arun-gupta/microservices/tree/master/microservice

问题和待办事项

以下是将整体重构为基于微服务的应用程序时遇到的问题和TODO:

  • Java EE已经允许使用EAR打包对应用程序进行功能分解。 应用程序的每个组件都可以打包为WAR文件,并捆绑在EAR文件中。 他们甚至可以通过这种方式共享资源。 现在这不是真正的微服务方式,但这可能是使您入门的过渡步骤。 但是,请注意, @FlowScoped bean没有在EAR中正确激活( WFLY-4565 )。
  • 使用JSF资源库模板提取所有模板文件。
    • 目前,所有网页都在everest模块中,但它们应该位于每个组件中( #15 )。
  • 将整体数据库拆分为多个数据库需要为每个应用程序使用单独的persistence.xml和DDL / DML脚本。 同样,需要相应地创建迁移脚本,例如使用Flyway。
  • 必须为所有组件创建一个REST接口,该接口需要被另一个组件访问。
  • UI仍在单个Web应用程序中。 而是应将其包含在已分解的WAR( #15 )中,然后再在哑代理中进行组合。 闻起来像portlet吗?
  • 在PaaS中部署多个WAR文件( #12 )
  • 每个微服务都应易于部署在容器中( #6 )

这是单片应用程序的类的完整列表:

./target/classes/org/javaee7/wildfly/samples/everest/cart/Cart.class
./target/classes/org/javaee7/wildfly/samples/everest/cart/CartItem.class
./target/classes/org/javaee7/wildfly/samples/everest/catalog/CatalogItem.class
./target/classes/org/javaee7/wildfly/samples/everest/catalog/CatalogItemBean.class
./target/classes/org/javaee7/wildfly/samples/everest/catalog/CatalogItemType.class
./target/classes/org/javaee7/wildfly/samples/everest/checkout/Order.class
./target/classes/org/javaee7/wildfly/samples/everest/checkout/OrderBean.class
./target/classes/org/javaee7/wildfly/samples/everest/checkout/OrderItem.class
./target/classes/org/javaee7/wildfly/samples/everest/checkout/Shipping.class
./target/classes/org/javaee7/wildfly/samples/everest/uzer/Uzer.class
./target/classes/org/javaee7/wildfly/samples/everest/uzer/UzerBean.class
./target/classes/org/javaee7/wildfly/samples/everest/uzer/UzerItem.class

这是基于微服务的应用程序的类的完整列表:

./catalog/target/classes/org/javaee7/wildfly/samples/everest/catalog/ApplicationConfig.class
./catalog/target/classes/org/javaee7/wildfly/samples/everest/catalog/CatalogItem.class
./catalog/target/classes/org/javaee7/wildfly/samples/everest/catalog/CatalogItemREST.class
./catalog/target/classes/org/javaee7/wildfly/samples/everest/catalog/CatalogItemType.class
./catalog/target/classes/org/javaee7/wildfly/samples/everest/catalog/ServiceRegistration.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/cart/Cart.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/cart/CartItem.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/catalog/CatalogBean.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/catalog/CatalogItem.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/checkout/Order.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/checkout/OrderBean.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/checkout/OrderItem.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/checkout/Shipping.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/ServiceDiscovery.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/ServiceDiscoveryStatic.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/ServiceDiscoveryURI.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/ServiceDiscoveryZooKeeper.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/uzer/UzerBean.class
./everest/target/classes/org/javaee7/wildfly/samples/everest/uzer/UzerItem.class
./order/target/classes/org/javaee7/wildfly/samples/everest/order/ApplicationConfig.class
./order/target/classes/org/javaee7/wildfly/samples/everest/order/Order.class
./order/target/classes/org/javaee7/wildfly/samples/everest/order/OrderItem.class
./order/target/classes/org/javaee7/wildfly/samples/everest/order/OrderREST.class
./user/target/classes/org/javaee7/wildfly/samples/everest/uzer/ApplicationConfig.class
./user/target/classes/org/javaee7/wildfly/samples/everest/uzer/UserREST.class
./user/target/classes/org/javaee7/wildfly/samples/everest/uzer/Uzer.class
  • 同样,完整的代码库位于github.com/arun-gupta/microservices 。

未来话题

本系列中的一些未来主题将是:

  • 微服务是否需要容器?
  • 如何使用容器部署多个微服务?
  • 如何轻松监控所有这些服务?
  • A / B测试
  • 使用微服务和容器进行连续部署

您还想看些什么?

请享用!

翻译自: https://www.javacodegeeks.com/2015/06/monolithic-to-microservices-refactoring-for-java-ee-applications.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java代码韦伯分布_第十五节、韦伯局部描述符(WLD,附源码)

纹理作为一种重要的视觉线索,是图像中普遍存在而又难以描述的特征,图像的纹理特征一般是指图像上地物重复排列造成的灰度值有规则的分布。纹理特征的关键在于纹理特征的提取方法。目前,用于纹理特征提取的方法有很多,最具有代表性…

windows和linux删除文件方法

Windows下bat文件内容如下;复制代码 代码如下: echo offforfiles -p "D:\servers\apache2.2\logs" -s -m *.log -d -15 -c "cmd /c del path"forfiles -p "D:\servers\mysql\logs" -s -m *.log -d -15 -c "cmd /c del path"…

JavaFX真实世界应用程序:欧洲电视网广播联盟

我荣幸地与今年在德累斯顿Saxonia 系统公司工作的Alexander Casall一起在JavaOne上展示了多个JavaFX Real-World应用程序。 在准备本次演讲时,我们向客户和合作伙伴发送了一份调查表,并向他们询问了一些与他们的项目,他们的应用程序以及他们对…

java 三大集合_java中的三大集合入门笔记(简单实用)

为什么使用集合框架如图:集合的好处:集合弥补了数组的缺陷,它比数组更灵活更实用,可大大提高软件的开发效率,而且不同的集合适用于不同的场合。Java集合主要分为以下3种类型Java集合框架提供了一套性能优良、使用方便的…

java POI 写入百万数据到 excel

.xls文件只支持6w的数据写入 .xlsx文件只支持104w数据的写入 在java中jxl工具类只能操作.xls的文件,不能操作.xlsx的文件 POI工具类能够支持.xlsx的文件操作。 excel的数据读写都相应的简单,网上也有很多的代码,我这里要说的是怎么样写入100w…

摆脱困境:将运行时配置作为JSON返回

如果需要确定部署到远程服务器的Spring Web应用程序的运行时配置,则需要读取从远程服务器找到的属性文件。 这很麻烦。 幸运的是,有更好的方法。 这篇博客文章描述了我们如何 启动我们的Web应用程序时,将运行时配置写入日志文件。 返回运行…

网络爬虫依赖的架包

网络爬虫依赖的架包 commons-codec-1.3.jarcommons-httpclient-3.1.jarcommons-logging-1.0.4.jarhtmllexer.jarhtmlparser.jar 转载于:https://www.cnblogs.com/aicpcode/p/4194898.html

调用布尔变量java_关于java的参数的调用,还有布尔的理解,这有一段代码,我有些不太理解,希望能够帮我分析下,谢谢...

第一段代码public class CustomerBiz {String[] namesnew String[30]; //创建学生姓名数组//实现姓名的添加public void addName(String name){for(int i0;iif(names[i]null){names[i]name;break;}}}public void showName(){ //显示姓名for(int i0;iif(names[i]!null){System.o…

优化哈希策略的简介

总览 用于哈希键的策略可以直接影响哈希集合(例如HashMap或HashSet)的性能。 内置的哈希函数被设计为通用的,并且可以在各种用例中很好地工作。 我们可以做得更好,特别是如果您对用例有一个很好的了解吗? 测试哈希策…

java中报错convension_LambdaConversionException与泛型:JVM错误?

此错误不是完全固定的。我只是LambdaConversionException在1.8.0_72中遇到了一个问题,发现Oracle的错误跟踪系统中有未解决的错误报告: link1,link2。(编辑:据报告,链接的错误已在JDK 9 b93中关闭)作为一种简单的解决方…

java初学者指南_Java初学者指南

java初学者指南Java编程的第一步。 对于Java中的入门教程,请参阅Sun的官方帮助这里 除了核心语言外,还有几种技术和API 介绍。 我们建议首先阅读涵盖 基础知识,并继续其余的教程。 我们建议: 保持代码简单明了且易于阅读 拆…

Java面试题2019简书_2019最新Spring面试题大全含答案之Spring Beans(2019最全Spring超级葵花宝典)...

1.什么是Spring beans?Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中 的形式定义。Spring 框架定义的beans都是单件bean…

javascript练习----复选框全选,全不选,反选

第一种方式&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><style>body{color: #000}</style> <script> document.write("<ul>&quo…

使用此首选项可加快Eclipse m2e配置

谁不认识他们。 Eclipse中的旧式JFace对话框可以使您直观地看到实际上是一个相当简单的XML或属性文件。 对于m2e&#xff0c;它看起来像这样&#xff1a; 不幸的是&#xff0c;此屏幕的加载速度有点慢&#xff0c;除了检查版本号和您将永远不会更改的其他内容之外&#xff0c…

php 判断两个数组差集,php array_udiff_assoc 计算两个数组的差集实例

php array_udiff() 函数用于比较两个(或更多个)数组的键名和键值&#xff0c;并返回差集。此比较是通过用户提供的回调函数来进行的。如果认为第一个参数小于&#xff0c;等于&#xff0c;或大于第二个参数时必须分别返回一个小于零&#xff0c;等于零&#xff0c;或大于零的整…

【百度地图API】发布静态图API啦!只需一个网址,即可展示定制百度地图!

【百度地图API】发布静态图API啦&#xff01;只需一个网址&#xff0c;即可展示定制百度地图&#xff01; 原文:【百度地图API】发布静态图API啦&#xff01;只需一个网址&#xff0c;即可展示定制百度地图&#xff01;摘要&#xff1a; 百度地图静态图API&#xff01;您无须执…

脚本在流程中的性能影响

我们经常看到人们出于各种目的而使用脚本&#xff08;例如&#xff0c;在服务任务&#xff0c;执行侦听器等中&#xff09;。 使用脚本和Java逻辑通常很有意义&#xff1a; 它不需要打包到jar中并放在classpath上 它使流程定义更易于理解&#xff1a;无需查看其他文件 逻辑是…

php 弹出变量,php取变量出现Notice: Undefined variable 的解决方法

Notice: Undefined variable: email in D:\PHP5\ENOTE\ADDNOTE.PHP on line 9Notice: Undefined variable: subject in D:\PHP5\ENOTE\ADDNOTE.PHP on line 9Notice: Undefined variable: comment in D:\PHP5\ENOTE\ADDNOTE.PHP on line 9........本来php是不需要定义变量的&am…

PowerDesigner使用教程

原文&#xff1a;http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html PowerDesigner是一款功能非常强大的建模工具软件&#xff0c;足以与Rose比肩&#xff0c;同样是当今最著名的建模软件之一。Rose是专攻UML对象模型的建模工具&#xff0c;之后才向数据库建模…

mac os java_适用于Mac OS X的官方Java 7 –状态

mac os java希望到目前为止&#xff0c;每个人都知道苹果公司去年加入了OpenJDK项目。 那是什么意思&#xff1f; 苹果将​​把用于私有Mac Java构建的代码作为GPL代码贡献给OpenJDK Oracle将接管Java的Mac端口 随着时间的流逝&#xff0c;Mac平台将成为Java世界中完全一流的…