博客

【注】本文译自:https://www.theserverside.com/tip/Library-vs-framework-How-these-software-artifacts-differ

  库与框架:这两个软件构件的区别库(Libraries)是提供特定功能(如建立网络连接)的低级组件。框架(Framework)是已知的编程环境,比如 Spring Boot。   当软件主管开始构建新的企业应用程序时,他们必须决定要使用哪一组库和框架。 这引出了一个明显的问题:软件库和框架之间有什么区别?   库和软件框架都有助于应用程序的开发。但是,两者之间的主要区别在于它们的任务范围,以及它们减轻开发人员编写代码负担的方式。   库提供了开发人员可以调用来执行特定功能的组件、类和方法。相比之下,框架提供的代码已经执行了通常需要的功能,并在需要定制功能时调用开发人员提供的代码。

库与框架

  库是一组相关的低级组件,开发人员调用这些组件来实现特定结果。常用库函数包括日期格式化和建立网络连接。   框架处理更高级别的问题。框架提供了一个既定的编程环境,它本身建立在低级库之上。   例如,框架可能会处理如何最好地将应用程序中的所有对象映射到相关数据库中的表中。它还可以处理如何向最终用户提供丰富的、基于 Web 的体验。

软件库示例

  一个库的例子是 Java 日期和时间 API。它是一组定义属性和方法的类和接口,开发人员可以使用这些属性和方法来格式化日期、执行时区转换并提供全局日历支持。Java 开发人员在需要时实例化 Date 和 Time 类,并以他们认为合适的任何方式调用库的方法。   另一个 Java 库示例是流行的 java.net 网络 I/O 包。该库由数十个类和接口组成,开发人员使用这些类和接口来打开网络端口、处理传入连接并将数据发送到互连的客户端。   只需要使用 java.net 包,软件开发人员就可以实现处理基于 REST 的 Web 服务或通过 HTTP 协议的基于 HTML 的请求-响应循环所需的所有必要逻辑。java.net 库提供了一组低级 API,任何开发人员都可以使用这些 API 来开发通过网络进行通信的应用程序。

流行的 Java 库

  其他流行的 Java 库,包括已经利用了 Java 框架的 Spring Boot、JHipster 或 Vaadin 等 的库,包括:

  • Apache Commons Math
  • BouncyCastle for cryptography
  • Java Advanced Imaging
  • Java Speech
  • Java 3D
  • JavaMail
  • Joda-Time
  • Apache Collections
  • Jackson for JSON and XML
  • Java Networking

软件框架的作用

  企业项目通常需要开发人员提供一组 RESTful API,以便外部客户端与在线应用程序集成。然而,许多开发人员不仅解决了如何使用低级 java.net 库来处理 RESTful API 调用的问题,而且还将他们的工作作为开源项目来分享。这是软件框架的本质。它是一个现有项目,解决了一个常见且具有挑战性的问题,开发人员可以在自己的项目中使用它。

  框架是解决常见且具有挑战性的问题的现有项目,开发人员可以在自己的项目中使用它。

  在给定的问题域中,通常有许多框架可供选择。在 Java 生态系统中,有许多流行的框架使用标准的 Java 和 Jakarta EE 库来解决如何最好地处理基于 REST 的请求-响应周期的问题,包括:

  • Spring Boot
  • Jersey
  • RESTEasy
  • Restlet
  • Micronaut
  • Apache CFX
  • JAX-RS

框架有观点

  将框架与库区分开来的另一个关键特征是后者通常包括关于如何解决给定问题、问题的范围以及如何以最有效和最有效的方式解决框架目标的观点。   框架将在各种非功能性需求上展开竞争,例如易用性、性能、可插入性和兼容性。

框架和控制反转

  最后,库和框架之间的一个关键区别因素是两者之间的相对控制反转 (IoC)。IoC 通常被称为好莱坞原则。与库不同,框架对开发人员编写的代码采取“不要打电话给我们,我们会打电话给你”的方法。   要使用库开发应用程序,开发人员必须实例化库组件并调用其中存在的类和接口的方法。例如,如果开发人员想要使用 java.net 库来创建他们自己的 RESTful 应用程序,他们将需要调用各种 API 来打开端口、处理 HTTP 连接、将数据格式化为 XML 或 JSON 表示形式来回通信,以及当客户端发起请求时发起一个请求。   另一方面,框架负责支持项目核心功能所需的所有底层管道。只有在需要时,框架才会调用开发人员提供的代码。

IoC 和 Spring Boot

  用 Spring Boot 编写的 RESTful Web 服务很好地体现了 IoC 的好莱坞原则。   使用 Spring Boot RESTful Web 服务,开发人员只需编写在发生基于 HTTP 的 GET 调用时要执行的逻辑。当 GET 调用发生时,Spring Boot 框架会处理它,解释它,将数据交换格式转换为 JSON 或 XML,然后将 RESTful 请求路由到开发人员的业务逻辑。   开发人员只需要编写业务逻辑。由框架决定何时调用业务逻辑。   IoC 框架在 Java 中很常见。以下是十个常见的例子。

  • Hibernate
  • Struts
  • JavaServer Faces
  • Play for Scala
  • Vaadin
  • JHipster
  • JRuby
  • JUnit
  • Quarkus
  • Grails

框架和库一起使用

  虽然框架和库有不同的功能,但它们都可以帮助开发者完成更多工作。当许多常见的编程挑战已经被解决并以许可的开源项目的形式被共享时,没有软件专业人员愿意浪费时间重复发明轮子。   每当您启动一个新的软件开发项目时,选择一个已被证明和建立的软件开发框架非常重要。同时,与您的个人开发和设计理念保持一致。在极少数情况下,特定的情况超出了所选框架的范围,标准库总是在那里帮助您的开发人员弥合差距。

【注】本文译自: Overview of Resource-Oriented Architectures (ROA) | Developer.com

了解面向资源的架构 (ROA)、其价值以及最佳实践。

  面向服务的架构 (Service-Oriented Architecture,SOA) 和面向资源的架构 (Resource-Oriented Architecture,ROA) 是用于实现健壮、可扩展的分布式应用程序架构的架构设计模式。分布式架构由通过定义良好的接口在网络上使用的组件组成。在 ROA 中,这些组件被称为资源,而在 SOA 中,它们被称为服务。本文概述了面向资源的体系结构。

什么是面向资源的架构 (ROA)?

  面向资源的架构 (ROA) 是一种架构风格,它扩展了 REST 架构风格,并提供了更广泛、可扩展、灵活且与传输无关的架构。面向资源的架构 (ROA) 范式建立在资源的概念之上。资源是一个独立的、可识别的实体,其状态可以被分配一个统一的资源定位符 (URI)。服务代表所请求操作的执行,而资源代表可通过一致的标准化接口进行管理的分布式组件。
  面向资源架构的特征之一是与传输无关。因此,必须有特定的机制将面向资源的服务暴露给外部世界。当消费者请求统一资源定位器(Uniform Resource Locator,URL)并指定访问方法(例如,GET、PUT、POST 和 DELETE)时,该 URL 将转换为相对的内部 URI。访问方法被转化为动作。
  面向资源的架构仅围绕四个概念建模:

  • 资源
  • URI
  • 表述
  • 链接和连通性

  以下是面向资源架构的四个属性:

  • 可寻址性
  • 无状态性
  • 连通性
  • 统一的接口

面向资源的架构:资源

  资源是 ROA 的基石;资源是信息的逻辑表示。例如,学生是数据点的抽象集合,可以用多种方式表示,包括 XHTML、JSON 和 XML。 资源名称包括以下内容:

  • 资源的类型
  • 资源标识符
  • 父元素的资源名
  • API 服务的名称

  资源是 REST 或 RESTful 架构中最重要的信息抽象。术语“资源”是指任何可识别的信息。这些信息可以是文档、计算机、汽车、临时服务(例如“俄亥俄州今天的天气”)、其他资源的集合、个人、学生等。
  每个不可变资源表示都可以通过相对的统一资源指示符 (URI) 来标识,它可能包括到其他资源以及其他不可变资源的连接。请注意,一个资源也可以有多个 URI。
  每种资源应具有以下特征:

  • 是唯一的
  • 必须至少有一个表述
  • 具有属性,模式可以被访问并提供上下文

统一资源标识符(URI)

  统一资源标识符 (Uniform Resource Identifier,URI) 是包含资源名称和地址的字符序列,用于标识逻辑或物理资源。请注意,资源必须具有一个或多个 URI。 没有 URI,一条信息不被视为资源,因为它不能被引用或访问。 您可以使用 URI 来标识任何事物,例如现实世界的对象、网页、书籍等。
  下面是一个 URI 的例子:语法::示例:http://payroll/employee/1234 下表说明了如何指定资源的相对 URI:

  • 动作
    相对 URI
    目的
  • Read
    /student/3
    读取 ID 是 3 的学生记录
  • Delete
    /student/4
    删除 ID 是 4 的学生记录

面向资源架构ROA的特性

  以下是面向资源的架构的四个基本属性:

可寻址性

  可寻址性是面向资源架构的一个基本特征。如果应用程序将其数据集的感兴趣方面发布为服务端点,则可以认为该应用程序是可寻址的。这些服务可以反过来用于处理应用程序的数据。由于 ROA 中的资源使用 URI 公开,因此应用程序应使用 URI 公开其数据。

无状态

  无状态是面向资源架构的另一个特征,这意味着该架构中的每个 HTTP 请求都是独立发生的。换句话说,当客户端向服务器请求资源时,客户端必须提供服务器请求成功所需的所有信息。服务器从不存储来自先前请求的信息,也就是说,服务器上不存储状态信息。如果服务器需要来自较早请求的信息来处理请求,则客户端必须在另一个请求中再次发送该信息。

连通性

  在面向资源的架构中,表述是超媒体:包含数据和其他资源链接的文档。RESTful Web 服务遵循超媒体作为应用程序状态引擎 (Hypermedia As the Engine Of Application State, HATEOS) 原则。这是数据格式影响应用程序中转换状态的原则。到其他资源的链接嵌入在响应中,但对于相同的资源,它们可能会根据其当前状态而有所不同。
  网络最重要的特征之一是它的互连性。也就是说,互联网上的几乎所有信息都通过超链接链接在一起。超链接可用于将互联网上可访问的任何资源连接到另一个资源。基于 ROA 构建的应用程序应将其所有资源相互链接,反之亦然。当我们为资源选择合适的表述时,我们可以在应用程序中实现连通性。

统一接口

  您应该有一组定义良好的方法来操作应用程序中的资源。例如,HTTP 提供了以下您可能通常需要在任何应用程序中执行的常见操作:

HTTP GET – 获取一个资源

HTTP POST – 创建新资源

HTTP PUT – 修改一个存在的资源

HTTP DELETE – 删除一个存在的资源

HEAD 和 OPTIONS HTTP 方法

  下面是您应该了解的另外两个重要的 HTTP 方法:

HTTP HEAD – 用于检索资源的元数据表述

HTTP OPTIONS – 用于检查特定资源支持哪些 HTTP 方法

总结

  面向资源的体系结构是无状态的,并以资源为中心。URI 用于标识每个资源。您总是可以在计算机上同时拥有同一资源的多个副本。一个资源也可以有多个 URI。

/ / REST, ROA, SOA, 原创翻译

【注】本文节译自:APIs and microservices: How to create modern enterprise architectures (bitpipe.com)

    创建和发展现代化的企业架构并非易事:这意味着打破单一的、集中的系统,转而使用 API 和微服务等工具支持更多云功能和自适应环境。在本指南中,我们研究了这些类型的云连接架构的关键属性,并提供了有助于培养以 API 为中心的现代架构的实用建议。接下来,我们来探讨一下渐进式 Web 应用程序的出现。
    云应用程序被认为是一种易于部署、修改、扩展和计量的服务。这为现代企业架构和应用程序设计须如何发展提供了线索。这就是为什么,以及未来是什么样子。
    云服务本身建立在高度分布式的基础架构上,旨在对故障具有弹性,并且在不影响用户的情况下轻松移动和调整大小。使用应用程序接口或 API 访问和控制抽象服务,将用户与实现细节完全隔离。用户几乎不知道或不关心服务在哪里运行或在什么类型的系统上运行。这些核心属性巩固了云服务相对于传统单体软件的众多优势。
    然而,这些相同的特性可以而且应该应用于构建在一个或多个云上的企业应用程序。事实上,使用共享、按需、可伸缩的云服务的细粒度微服务设计是任何现代企业架构的虚拟需求,这些架构期望满足数字业务的需求,服务于数百万移动客户、智能机器和连接的传感器。

互联的数字企业

    企业架构必须改变的原因是高速连接和数十年来计算能力指数级摩尔定律改进的融合。这使得廉价智能手机市场趋于饱和,公用事业规模的 IT 服务提供商得以创建云服务。这些技术共同推动了业务的巨大变化。无论您将其称为“新连接经济学 ”(Gartner) 还是“无界企业 ”(AT&T Bell Labs),它都意味着企业以及随之而来的 IT 系统和应用程序将越来越多地与人交互,还将以自动化业务流程和智能设备的形式与设备、虚拟对象和其他软件交互。这是一种交互的爆炸式增长,Gartner 称之为数字网格。
    这对企业架构的影响变得更像是大型云服务——想想谷歌、Facebook 和 AWS——而不是使用单体的、集中的系统来处理不断增长和越来越不可预测的工作负载。事实上,随着双模 IT、DevOps 和敏捷开发等概念的引入以加快数字业务创新的步伐,其影响将远远超出企业架构,深入到 IT 如何开展业务的核心。但是我们这里的重点是体系结构框架。

处理“连通性”

    但是,如果组织选择实施它,演进的现代企业架构将类似于云。应用程序是否最终运行在 AWS 和 Azure 等共享的公共服务上;基于 Azure Stack、OpenStack 或 vCloud 等软件构建的私有基础设施;或者两者结合,架构必须假定共享的可用性,即使仅在组织内部,计量软件服务也可以立即实例化、修改、扩展和互连。随着组织构建的数字服务看起来更像 Facebook 和 Uber,应用架构必须类似于云原生服务,而不是隔离在单个盒子上的单体系统。
    现代架构应具有以下关键属性:

  • 将客户端接口与业务服务分离:应用程序将采用移动和浏览器设计范式,客户端专门用于 UI 和后端服务的业务处理。
  • 天然分布式:后端应用程序将能够运行多个实例,提供弹性和可扩展性,同时支持持续、敏捷开发流程所需的无中断更新。
  • 使用微服务:后端服务将针对特定功能而设计。它还可以在许多消费者之间共享,并可以轻松链接到特定应用程序的服务链中。将微服务视为用于构建任意复杂功能的构件。服务可以在自己的 VM 中隔离运行,也可以作为共享操作系统实例的容器运行。它们还具有固有的自计量功能,以支持基于消费的计费、细粒度的性能跟踪和自动扩展。
  • 异步服务间通信:服务将使用消息总线交换信息,而不是到网络套接字和文件共享的持久连接。
  • 丰富的服务组合:服务将公开元数据,允许它们作为广泛服务组合的一部分进行管理、使用和编排,包括移动和物联网应用后端、数据存储和分析、消息传递、监控和安全。
  • 应用程序模板和设计模式库:
        该组合是模板的基础,这些模板将服务组合在一起,以解决各种应用开发需求和设计模式,比如 Azure 提供的。开发人员库还包括标准数据模型,用于选择合适的数据服务,如对象存储、NoSQL、SQL、大数据,例如 Hadoop 和 Spark;以及满足特定需求的数据转换管道。
  • 以 API 为中心:API 是主要的,通常也是唯一的服务接口。 客户端访问通常是无状态的,但任何状态都通过消息总线和后端数据服务处理,并且只有最少的客户端支持。
  • 自动化基础设施:服务链可以从用于部署、扩展、移动和停用云实例的基础设施模板中实例化。 服务计量和仪表用于对资源使用情况发出警报、活动、错误状态、并触发自动修复,例如缩放、重启和人工通知。
  • 细粒度的安全性:对单个服务的访问通过基于角色的访问控制列表进行控制,策略定义为应用程序模板的一部分。 用户身份和角色被集中管理,并可能与来自业务合作伙伴或公共在线服务的外部身份管理系统联合。

    待办事项清单

        拥有正确的企业架构可能是未来数字业务计划成败的关键。 对于 CIO 和 IT 高管来说,这意味着架构应该是执行层的优先级,它是通过 IT、应用程序开发人员和业务线经理之间的密切协作开发。 对于 IT 经理和技术专业人士来说,企业架构的重要性需要一个由多学科专家组成的专门团队——例如 IT 运营、AppDev、DevOps、云运营和数据科学家等——他们的重点是开发、改进、更新和实施架构。
        不断发展的企业架构是不断发展的 IT 的一部分,它必须专注于灵活的服务创新、开发和实施,以响应动态的数字业务需求。因此,它可能会伴随 IT 内部的结构和文化变化,例如双模式和 DevOps 组织以及持续交付流程。对于 IT 专业人员来说,这是最具挑战性但又最激动人心的时刻之一。

    在网页和原生应用之间架起桥梁

        移动应用和网站在用户体验方面历来采用不同的模式。让用户访问网站比安装应用程序要容易得多。但移动应用往往会促进更具吸引力的用户体验。一种全新的全渠道应用交付模式,称为渐进式 Web 应用,有望提供两全其美的服务,并且是旧金山 O’Reilly Fluent 会议的热门话题。
        谷歌 Chrome 团队的一名资深软件工程师 亚历克斯·拉塞尔(Alex Russell)表示,他们之所以选择“渐进式 Web 应用”这个词,是因为它们可以在标签中开始生活,并逐渐变得像应用程序一样。有几个因素正在推动这一趋势,包括更好的缓存技术和使 Web 应用的行为更像移动应用的新技术。
        一些先驱企业已经证明了使用新模式有利于增加用户访问量和在网站上花费的时间。Flipkart 开始实施渐进式应用,并且发现用户花在新网站上的时间增加了三倍,每周访问者增长 40%。他们还发现 63% 转化率来自主界面访问者,他们甚至还没有发布推送通知。

    解决分布式问题

        “我认为分发是软件中最困难的问题,”Russell 说。在早期,用户必须从软盘安装应用程序。现在,让用户安装应用程序要容易得多,但要让用户主屏上花费更多的精力和空间,仍然有很多阻力。网络是最便捷的分发平台,但令人惊讶的是,我们还没有转向通过 URL 分发移动应用。Web 应用程序可以更定期地更新,也可以通过单击链接进行更新,开发无需通过应用商店的审批流程。
        但根据 comScore Inc. 的研究,用户往往会将大约 87% 的时间花在移动应用上,而花在智能手机上的移动 Web 应用上的时间只占 13%。另一方面,大多数用户将大部分时间花在顶级应用上,而其他人则处于休眠状态。由于这些趋势,企业最终会花费大量资金让用户安装其软件的移动应用版本。许多这些应用最终成为永远不会被使用的僵尸应用。这需要付出很大代价,因为其中许多应用都无法进入顶层。
        与此同时,移动网站也吸引了许多未安装该应用的独立访问者。这对于应用使用较少的企业(例如零售商)很重要。用户平均每月使用 27 个应用,但访问超过 100 个移动网站。Russell 表示,用户对下载原生移动应用的空间、带宽和时间感到焦虑。

    超越技术

        一些处理密集型应用可能会像原生移动一样表现得更好。但 Russell 表示,他相信移动网络平台对于当今的大多数应用来说已经足够了。他说,阻碍移动网络应用使用的三个主要因素是缺少主屏、缺少推送通知托盘访问和缺少离线访问。

    主屏访问

        Chrome 团队最近发布了 Web 应用清单(Web App Manifest)规范。早期版本可在所有 Android 平台上运行。这提供了一个框架,用于告诉移动浏览器某个特定链接实际上是一个移动应用。 这样可以更轻松地将站点作为单独的窗口重新启动,该窗口的外观和行为类似于其他本机应用程序。
        开发人员只需在站点上包含一个清单文件,其中包含一个指向图标和应用名称的链接。Russell 说这是必要的,因为 Web 还没有应用结构的概念。直觉上,人们知道博客与博客中的条目是不同的。清单提供了一种向浏览器显式声明这种区别的方法。

    突破新极限

        去年,Chrome 团队在 Chrome 桌面版和 Android 版上推出了推送通知。 这使得 Web 应用程序可以更轻松地将更新定向到推送通知托盘中。 此功能也可用于三星和 Firefox 浏览器,并生成行为与本机应用程序非常相似的通知——即使在浏览器关闭时也是如此。 用户必须提供从特定站点接收通知的权限。
        这种策略对零售商的网站很有效,例如,他们可能想向访问商店的用户推出优惠券。它将允许用户接收这些更新,而无需在主屏上安装任何应用程序。零售商 Beyond The Rack 报告称,其 50% 的访客来自发布推送通知。他们还发现在网站上花费的时间和转化率有所增加。

    使用 Service worker 进行更好的缓存

        最后一个阈值是支持有效的离线功能。谷歌多年来一直致力于解决这个问题。最初,Google Gears 允许通过一组狭窄的方式来考虑打造离线体验。应用程序缓存与现在被纳入 HTML5 规范的设计相同。
        谷歌现在引入了服务工作者的概念。这种方法允许开发人员指定服务工作者在移动设备离线或在线时的行为方式。Russell 说离线只是网络连接不稳定的一个特例。这种方法允许应用程序提供令人满意的用户体验,而不管其连通性如何。应用程序外壳可以在重复访问时立即缓存和加载。“现在,有了 Service Worker,你可以在没有 DNS、http 或 TLS 辅助的情况下将内容投放到屏幕上,”Russell 说。个人、网络广播、播客、视频、虚拟贸易展览、研究报告等——利用技术提供商的丰富研发资源来应对市场趋势、挑战和解决方案。我们的现场活动和虚拟研讨会为您能够就您每天面临的问题和挑战获得中立的供应商评论、专家评论和建议。我们的社交社区 IT 知识交流使您可以与同行和专家实时共享现实世界的信息。

【注】本文译自:How to build a Spring Boot 12-Factor app (theserverside.com)
在这里,我们看看 Spring Boot 框架如何支持十二因素应用的方法,以及 GitHub、Docker 和 Kubernetes 等工具填补了哪些空白。
    没有国际标准组织指定 Spring Boot 应用作为微服务必须满足的标准。Heroku 联合创始人 Adam Wiggins 向部署到 Heroku 平台的开发人员提供的 12 条建议是开发人员最接近的一套云原生开发指南。
    这 12 条戒律被称为“十二因素应用方法论”,已成为创建现代的以 Docker 和 Kubernetes 为部署目标的现代云原生微服务的事实标准。
    开发基于 Java 的微服务最流行的平台是 Spring Boot。以下是 Spring Boot 如何支持十二因素应用方法论的原则。

1. Spring Boot 代码库

    并非每个 12 因素的原则都直接映射到 Spring Boot。代码库原则就是责任落在 Spring 框架之外的一个例子。
    根据十二因素应用,每个 Spring Boot 微服务都应该有自己独立的代码库。这可以通过创建单个 Git 存储库来实现,开发人员可以在其中贡献代码、合并分支和修复错误。如果您的 Spring Boot 应用托管在其自己的 Git 存储库中,那么您已经正确地实现了 12 因素代码库要求。

2. 外部化依赖管理

    如果您使用 Spring Boot 初始化器创建一个项目,则必须在 Gradle 或 Maven 之间进行选择作为项目的构建工具。这两个工具都将管理依赖项外部化。
    如果您将 JAR 文件放在项目的 lib 目录之外,并在 Maven POM 或 Gradle 构建文件中列出程序的所有外部依赖项,则您的 Spring Boot 应用程序将正确实现 12 因素 依赖项管理。

3. Spring Boot 和 Kubernetes 配置

    根据十二因素应用方法论,Spring Boot 应用程序应该从环境中读取其配置数据。 例如,如果将云原生 Spring Boot 应用程序部署到 Docker 容器并在 Kubernetes 集群中进行管理,则应用程序应该从 Kubernetes ConfigMap 读取其配置数据——而不是从 JavaBean 字段甚至应用程序属性文件。Spring 的级联配置处理系统完全满足了这个 12-因素要求。
    任何用 Spring @ConfigurationProperties 注解修饰的 JavaBean 都会在多个地方寻找配置数据。 @ConfigurationProperties 修饰的 bean 的规则是始终使用最高外部化级别的配置。在 JavaBean 中硬编码的属性将被 ApplicationProperties 文件中的数据覆盖,这些数据将被 JVM 参数覆盖,最终将被 Docker 或 Kubernetes ConfigMap 提供的参数覆盖。
    使用 @ConfigurationProperties 注解,您的 12 因素 Spring Boot 应用将符合配置。

4. 支持服务和 Spring Boot

    将支持服务视为附加资源的能力自 Java 语言一开始就已经融入到 Java 语言中,因此即使开发人员齐心协力,也很难违反这个 12 因素 约束。
    例如,所有通过 Java 数据库连接 (JDBC) 访问的数据库都需要一个 URL 和驱动程序,这隐式地使数据库成为附加资源。 如果不将数据库视为支持服务,就不可能在 Java 中执行 JDBC 或 JPA。 NoSQL 数据库、Kafka 队列和 RESTful Web 服务也是如此。如果您在 Jakarta EE 或 Spring Boot 中编写代码,则几乎必须按照 12-因素指南将所有外部资源视为支持服务。

5. 构建、发布和运行

    开发人员遵循严格的构建、发布和运行策略的建议似乎有些不言而喻。 具有讽刺意味的是,这也可能是最常违反的 12 因素规则之一。
    这里的想法是您应该始终从您的代码库构建您的代码。发布是与版本化配置文件相关联的标记构建。它是您在服务器上部署和运行的标记构建和版本化配置数据的组合。
    不应更新在服务器上运行的代码来修复错误。不应在运行时调整配置设置来克服 Java 性能问题。进入部署的所有代码都来自构建,它基于在裸 Git 存储库中进行版本控制的代码。
    一旦与构建配对以创建发布,配置数据就不得更改。如果需要更改,团队必须再次经历完整的构建、发布和运行周期。 不应该有违反 12 因素构建、发布和运行原则的捷径。

6. 无状态 Spring Boot 进程

    Java 和 Jakarta EE API 有许多类和接口,它们隐式地向应用程序添加状态,其中最重要的是 Servlet 和 JSP API 的 HttpSession 对象。
    为了实现 12 因素合规性,Spring Boot 为 HttpSession 提供了一个替代品,称为 Spring Session。这有助于外部化数据,否则这些数据将被有状态地保存在 Tomcat 或 Jetty 等应用程序服务器上。这是 Spring Boot 如何提供额外 API 并重新实现常用类以确保应用程序和微服务保持 12 因素合规性的一个主要示例。
    此外,Spring Boot 允许开发人员轻松地将 NoSQL 数据库(如 Cassandra 和 MongoDB)中的状态外部化,这也有助于简化无状态微服务的开发。
    必须指出的是,确保微服务作为无状态进程运行的责任也很大程度上落在了软件开发人员的肩上。如果开发人员决定将用户状态保存在一个实例变量中,而不是在共享资源中将该数据外部化,那么 Spring、Docker 或 Kubernetes 无法让该应用程序作为无状态进程进行扩展。

7. 端口绑定

    端口绑定是另一个 12 因素 原则,它超出了 Spring Boot 框架的范围。相反,Docker 容器会将 Tomcat 或 Undertow 服务器使用的内部端口映射到公共端口。在集群环境中,kubectl 实用程序会将 Kubernetes Pod 的端口绑定为公共服务。无论哪种方式,Spring Framework 都不负责端口绑定要求。
    Spring 确实提供了更改打包的 Spring Boot 应用程序内部使用的端口的能力,但 Kubernetes 或 Docker 将负责外部端口绑定,使云原生应用程序可公开访问。

8. 并发性

    根据十二因素应用方法论,云原生应用应该能够横向扩展,以支持来自客户端的大容量并发请求-响应周期。只要 Spring Boot 应用是无状态的,Kubernetes 副本集就会负责使用 Docker 容器创建新的 Pod,这些容器可以同时处理不断增加的工作负载。

9. 快速启动和关闭

    十二因素应用方法论的第 9 条原则是可处置性,它坚持微服务应该快速启动并优雅地关闭。
    为了便于处理,Spring Boot 实现了延迟加载设计模式。它还执行智能初始化以减少在云原生微服务启动时创建的对象数量。此外,当开发人员使用 Spring 框架提供的资源类时,控制能力的反转确保资源在 Kubernetes 节点耗尽或 Docker 容器下线时优雅地终止。

10. 环境之间的奇偶校验

    开发、用户验收测试、预生产和生产环境之间总会存在差异。但十二因素方法坚持这些环境尽可能相似。
    为了促进环境对等,Spring Boot 构建将创建一个可运行的 JAR 文件,其中嵌入了一个应用程序服务器,例如 Tomcat。 打包在 Docker 容器中的相同嵌入式 Tomcat JAR 文件将用于每个不同的部署环境。 由于每个环境都部署了相同的编译代码和应用服务器,最终实现了环境间的对等。
    此外,Spring Profiles 提供了一种简单的方法来定义和配置需要从一个环境更改到另一个环境的属性,从而允许开发人员解决不可避免地发生的环境之间的差异。

11. 日志作为事件流

    十二因素应用坚持将日志视为事件流。
    Spring Boot 使用的所有标准 Java 日志框架都将它们的数据写入事件流,该事件流被保存到运行 Docker 容器的 Kubernetes 节点上的公共目录中。然后这些日志文件很容易被 Kubernetes DaemonSets 使用,比如 FluentD 或 Logstash。这些 DaemonSet 然后将日志流式传输到 Elasticsearch 和 Logstash 等工具以供使用。
    只要您使用框架标准的 Java 日志框架,您就可以放心,在日志消耗方面,您拥有一个符合 12 因素标准的 Spring Boot 应用程序。

12. 管理进程管理

    应用通常需要运行管理进程,这些进程与处理客户端-服务器交互的请求-响应循环没有直接联系的。根据十二因素应用,不应将实现这些过程的代码放在单独的代码库中。管理进程应打包为标准的、受版本控制的构建的一部分,并且进程本身应在应用使用的相同运行时环境中执行。
    在云原生 Spring Boot 应用程序中添加对管理进程的支持非常容易。Spring Batch 项目可以轻松添加对运行一次并退出的作业的支持。 此外,任何 Git 存储库都可以配置为包含文件夹,这些文件夹允许添加可以在需要时在 REPL shell 中运行的脚本。
    云原生微服务的开发没有明确的标准,但十二要素应用方法很接近。如果您是一名 Java 开发人员并且想要创建 12 因素应用,Spring Boot 将帮助您的团队保持云原生合规性。

【注】本文节译自:GraphQL – Quick Guide (tutorialspoint.com)

    GraphQL 是 Facebook 开发的一种开源服务器端技术,用于优化 RESTful API 调用。它是一种执行引擎和一种数据查询语言。在本章中,我们将讨论使用 GraphQL 的优势。

为什么使用 GraphQL

    RESTful API 遵循清晰且结构良好的面向资源的方法。但是,当数据变得更复杂时,路由会变得更长。有时无法通过单个请求获取数据。这就是 GraphQL 派上用场的地方。GraphQL 以图的形式构建数据,其强大的查询语法用于遍历、检索和修改数据。
    以下是使用 GraphQL 查询语言的优势:

询问你想要的 – 并得到它

    向您的 API 发送 GraphQL 查询并准确获取您需要的内容。GraphQL 查询总是返回可预测的结果。使用 GraphQL 的应用程序且稳定。与 Restful 服务不同,这些应用程序可以限制应该从服务器获取的数据。
    以下示例将帮助您更好地理解这一点:
    让我们考虑一个具有属性 idfirstNamelastNameCollegeName 的业务对象 Student。假设一个移动应用只需要获取 firstNameid。 如果我们设计一个像 /api/v1/students 这样的 REST 端点,它最终会为一个 Student 对象的所有字段获取数据。这意味着,数据被 RESTful 服务过度获取。 这个问题可以通过使用 GraphQL 来解决。
    考虑下面给出的 GraphQL 查询:

{
  {
    id
    firstName
  }
}

    这将仅返回 id 和 firstname 字段的值。该查询不会获取学生对象的其他属性的值。上面说明的查询的响应如下所示:

{
    "data": {
        "students": [
            {
                "id": "S1001",
                "firstName": "Mohtashim"
            },
            {
                "id": "S1002",
                "firstName": "Kannan"
            }
        ]
    }
}

在单个请求中获取多个资源

    GraphQL 查询有助于顺利检索关联的业务对象,而典型的 REST API 需要从多个 URL 加载。GraphQL API 在单个请求中获取您的应用程序所需的所有数据。即使在缓慢的移动网络连接上,使用 GraphQL 的应用程序也可以很快。
    让我们再考虑一个业务对象 College,它具有以下属性:名称和位置。 Student 业务对象与 College 对象具有关联关系。如果我们使用 REST API 来获取学生及其大学的详细信息,我们最终将向服务器发出两个请求,如 /api/v1/students/api/v1/colleges。这将导致每个请求的数据获取不足。 因此,移动应用被迫多次调用服务器以获取所需的数据。
    但是,移动应用可以使用 GraphQL 在单个请求中获取 Student 和 College 对象的详细信息。
    以下是用于获取数据的 GraphQL 查询:

{
  students {
    id
    firstName
    lastName
    college {
      name
      location
    }
  }
}

    上述查询的输出正好包含我们要求的那些字段,如下所示:

{
    "data": {
        "students": [
            {
                "id": "S1001",
                "firstName": "Mohtashim",
                "lastName": "Mohammad",
                "college": {
                    "name": "CUSAT",
                    "location": "Kerala"
                }
            },
            {
                "id": "S1002",
                "firstName": "Kannan",
                "lastName": "Sudhakaran",
                "college": {
                    "name": "AMU",
                    "location": "Uttar Pradesh"
                }
            },
            {
                "id": "S1003",
                "firstName": "Kiran",
                "lastName": "Panigrahi",
                "college": {
                    "name": "AMU",
                    "location": "Uttar Pradesh"
                }
            }
        ]
    }
}

描述类型系统的可能性

    GraphQL 是强类型的,查询基于字段及其关联的数据类型。如果 GraphQL 查询中存在类型不匹配,服务器应用程序会返回清晰且有用的错误消息。这有助于客户端应用顺利调试和轻松检测错误。 GraphQL 还提供了客户端库,可以帮助减少显式数据转换和解析。
    下面给出了 StudentCollege 数据类型的示例:

type Query {
  students: [Student]
}

type Student {
  id: ID!
  firstName: String
  lastName: String
  fullName: String
  college: College
}

type College {
  id: ID!
  name: String
  location: String
  rating: Float
  students: [Student]
}

使用强大的开发工具更快地响应

    GraphQL 为文档和测试查询提供了丰富的开发工具。GraphiQL 是一个出色的工具,可以生成查询及其模式的文档。 它还提供了一个查询编辑器,用于在构建查询时测试 GraphQL API 和智能代码完成功能。