GraphQL 快速入门【3】GraphQL 架构

【注】本文译自: GraphQL – Quick Guide (tutorialspoint.com)
    GraphQL 是描述 GraphQL 服务器行为的规范。它是一组关于如何处理请求和响应的指南,如支持的协议、服务器可以接受的数据格式、服务器返回的响应格式等。客户端向 GraphQL 发出的请求服务器称为查询。GraphQL 的另一个重要概念是其传输层不可知性。它可以与任何可用的网络协议一起使用,如 TCP、websocket 或任何其他传输层协议。它对数据库也是中立的,因此您可以将它与关系数据库或 NoSQL 数据库一起使用。
    可以使用下面列出的三种方法中的任何一种来部署 GraphQL Server:

  • 带有连接数据库的 GraphQL 服务器
  • 集成现有系统的 GraphQL 服务器
  • 混合方法

    集成连接数据库的 GraphQL 服务器

        这种架构有一个带有集成数据库的 GraphQL 服务器,通常可以用于新项目。收到查询后,服务器读取请求有效负载并从数据库中获取数据。这称为解析查询。返回给客户端的响应遵循官方 GraphQL 规范中指定的格式。

        在上图中,GraphQL 服务器和数据库集成在一个节点上。客户端(桌面/移动)通过 HTTP 与 GraphQL 服务器通信。服务器处理请求,从数据库中获取数据并将其返回给客户端。

    GraphQL 服务器集成现有系统

        这种方法对于拥有遗留基础设施和不同 API 的公司很有帮助。GraphQL 可用于统一现有系统中的微服务、遗留基础设施和第三方 API。

        在上图中,GraphQL API 充当客户端和现有系统之间的接口。客户端应用程序与 GraphQL 服务器通信,后者反过来解析查询。

    混合方法

        最后,我们可以将以上两种方式结合起来,搭建一个 GraphQL 服务器。在这种架构中,GraphQL 服务器将解析收到的任何请求。它将从连接的数据库或集成的 API 中检索数据。这如下图所示:

GraphQL 快速入门【2】环境设置

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

    在本章中,我们将学习 GraphQL 的环境设置。 要执行本教程中的示例,您将需要以下内容:

  • 运行 Linux、macOS 或 Windows 的计算机。
  • 网络浏览器,最好是最新版本的 Google Chrome。
  • 安装了最新版本的 Node.js。建议使用最新的 LTS 版本。
  • 已安装适用于 VSCode 的扩展 GraphQL 的 Visual Studio Code 或您选择的任何代码编辑器。

如何使用 Nodejs 构建 GraphQL 服务器

    我们将详细介绍使用 Nodejs 构建 GraphQL 服务器的步骤,如下所示:

第 1 步 – 验证节点和 Npm 版本

    安装 NodeJs 后,在终端上使用以下命令验证 node 和 npm 的版本:

C:\Users\Admin>node -v
v8.11.3

C:\Users\Admin>npm -v
5.6.0

第 2 步 – 创建项目文件夹并在 VSCode 中打开 项目的根文件夹可以命名为 test-app。

    按照以下说明使用 Visual Studio 代码编辑器打开文件夹:

C:\Users\Admin>mkdir test-app
C:\Users\Admin>cd test-app
C:\Users\Admin\test-app>code.

第 3 步 – 创建 package.json 并安装依赖项

    创建 package.json 文件,该文件将包含 GraphQL 服务器应用程序的所有依赖项。

{
   "name": "hello-world-server",
   "private": true,
   "scripts": {
      "start": "nodemon --ignore data/ server.js"
   },
   "dependencies": {
      "apollo-server-express": "^1.4.0",
      "body-parser": "^1.18.3",
      "cors": "^2.8.4",
      "express": "^4.16.3",
      "graphql": "^0.13.2",
      "graphql-tools": "^3.1.1"
   },
   "devDependencies": {
      "nodemon": "1.17.1"
   }
}

    使用下面给出的命令安装依赖项:

C:\Users\Admin\test-app>npm install

步骤 4 – 在数据文件夹中创建平面文件数据库

    在这一步中,我们使用平面文件来存储和检索数据。创建文件夹 data 并添加两个文件 student.jsonColleges.json
    以下是 Colleges.json 文件:

[
    {
       "id": "col-101",
       "name": "AMU",
       "location": "Uttar Pradesh",
       "rating":5.0
    },

    {
       "id": "col-102",
       "name": "CUSAT",
       "location": "Kerala",
       "rating":4.5
    }
 ]

    以下是 student.json 文件:

[
    {
       "id": "S1001",
       "firstName":"Mohtashim",
       "lastName":"Mohammad",
       "email": "mohtashim.mohammad@tutorialpoint.org",
       "password": "pass123",
       "collegeId": "col-102"
    },

    {
       "id": "S1002",
       "email": "kannan.sudhakaran@tutorialpoint.org",
       "firstName":"Kannan",
       "lastName":"Sudhakaran",
       "password": "pass123",
       "collegeId": "col-101"
    },

    {
       "id": "S1003",
       "email": "kiran.panigrahi@tutorialpoint.org",
       "firstName":"Kiran",
       "lastName":"Panigrahi",
       "password": "pass123",
       "collegeId": "col-101"
    }
 ]

第 5 步 – 创建数据访问层

    我们需要创建加载数据文件夹内容的数据存储。在这种情况下,我们需要集合变量、学生和大学。每当应用程序需要数据时,它就会使用这些集合变量。
    在项目文件夹中创建文件 db.js,如下所示:

const { DataStore } = require('notarealdb');

const store = new DataStore('./data');

module.exports = {
   students:store.collection('students'),
   colleges:store.collection('colleges')
};

第 6 步 – 创建模式文件,schema.graphql

    在当前项目文件夹中创建模式文件并添加以下内容:

type Query  {
   test: String
}

第 7 步 – 创建解析器文件,resolvers.js

    在当前项目文件夹中创建解析器文件并添加以下内容:

const Query = {
    test: () => 'Test Success, GraphQL server is up & running !!'
 }
 module.exports = {Query}

第 8 步 – 创建 Server.js 并配置 GraphQL

    创建服务器文件并按如下方式配置 GraphQL:

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const db = require('./db');

const port = process.env.PORT || 9000;
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')

const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

app.use(cors(), bodyParser.json());

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

app.listen(
   port, () => console.info(
      `Server started on port ${port}`
   )
);

第 9 步 – 运行应用程序并使用 GraphiQL 进行测试

    验证项目 test-app 的文件夹结构如下:

test-app /
   -->package.json
   -->db.js
   -->data
      students.json
      colleges.json
   -->resolvers.js
   -->schema.graphql
   -->server.js

    运行命令 npm start,如下所示:

C:\Users\Admin\test-app>npm start

    服务器运行在 9000 端口,因此我们可以使用 GraphiQL 工具测试应用程序。打开浏览器并输入 URL http://localhost:9000/graphiql 。在编辑器中输入以下查询:

{
  test
}

    来自服务器的响应如下:

{
    "data": {
        "test": "Test Success, GraphQL server is running !!"
    }
}

GraphQL 快速入门【1】简介

【注】本文节译自: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 和智能代码完成功能。

如何构建 Spring Boot 12 因素应用

【注】本文译自: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 将帮助您的团队保持云原生合规性。

技术白皮书:现代企业架构设计

【注】本文节译自: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 知识交流使您可以与同行和专家实时共享现实世界的信息。

面向资源的架构(ROA)概述

【注】本文译自: 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。

软件库与框架的区别

【注】本文译自: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

框架和库一起使用

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

面向服务体系结构的领域驱动设计

【注】本文译自:https://www.thoughtworks.com/insights/blog/domain-driven-design-services-architecture
  这篇文章是关于软件设计的选择。特别是大型系统,这些系统可能会以服务端点的形式分为多个可部署的对象。我不会特别谈论服务端点设计,但是我想讨论创建多个服务应用的构思阶段。

  当我们面对复杂的问题时,我们通常试图理解复杂的单个部分。通过分解问题,我们将其变成为更易于理解和管理的部分。
  正如在许多产品/项目管理周期中所描述的,对于现实生活中的问题,这通常是由本能驱动的。 我们不会使用公式来了解去一个需要签证的国家需要做什么。我们知道我们需要签证才能旅行,我们慢慢掌握需要的文件文件,需要填写哪些表格以及如何填写这些表格。当我们执行其中一个步骤时,我们不会将流程的所有细节都牢记在心,而只是要做手头的任务。这与要完成的任务的大小有关。潜在的真实标准是关于时间或进度、我们的执行力、我们的认知能力及其与任务熟悉程度的关系,甚至可能是执行这些任务的物理位置( 领事馆与 Photoshop 等)。
  在软件开发领域并没有什么不同。多年来,瀑布式的配方已被应用到软件开发过程中,最终,主要是基于启发式和基于经验的评估技术(计划扑克、T – 恤尺寸)和敏捷过程。在现实生活中,我们试着不去详述整个过程,而是通过观察我们的最新表现来尝试和理解整个旅程。
  同样适用于我们针对问题建模的软件。我们开始将它们分解为不同的应用的是方便管理单个应用,以更少的依赖关系更快地开发和部署,最后带来更多的技术选择自由。我们意识到,我们无法制定出适合所有人的完整流程。我们着眼于各个部分,并认识到我们在设计模式或技术方面的集体经验,并尝试应用其中最好的选择。
  理解和解决复杂性的一个有趣的软件设计技术是领域驱动设计(DDD)。领域驱动设计提倡基于与我们的用例相关的业务现实进行建模。由于 DDD 方法现在已经过时,而且宣传水平正在下降,我们许多人都忘记了 DDD 方法确实有助于理解手头的问题,并朝着对解决方案的普遍理解来设计软件。在构建应用DDD 会以域和子域的形式讨论的问题。它将问题的独立步骤/领域描述为边界上下文,强调使用一种通用语言来讨论这些,并添加了许多技术概念,如实体、值对象和聚合根规则以支持实现。有时,这些技术规则被视为是实施 DDD 的硬障碍,但最终,人们往往会忘记重要的部分是根据业务问题组织代码工件,并使用与(1)相同的通用语言。

设计为服务应用的边界上下文

  我想谈论的架构风格与微服务非常相似。它是关于将单体应用分离为多个独立的服务应用,或者从一开始就在边界上下文(DDD概念)的帮助下单独开发它们。
  有许多资源都强调了微服务叙述中更细粒度的服务的优点。越来越多的文章、博客和其他内容是关于陷阱和在向细粒度服务过渡之前或过渡期间应该拥有的安全网的。我将尽量不重复微服务或其他支持元素的好处,这些是迁移到这样的体系结构中所需要。我不想强调结果服务的“小型”性质,而是想强调如何通过应用领域驱动的设计概念来更好地分离这些服务。
  让我们使用一个真实的示例来实现我们的想法-借记卡/信用卡获取域。这个领域可以(不幸的是,很多时候都是这样)作为一组单体应用来实现。我们拥有多个应用的唯一原因是由于不同的应用中的存在严格的技术限制(例如希望执行批处理)。

  我所看到的大多数成功的架构都认识到,通过数据库进行集成是一种糟糕的实践,因为它使技术应用和业务职责之间的界限变得模糊,使业务逻辑泄漏到数据库中,并通过添加更多的应用服务器来阻止水平扩展。因此,以单体应用的的服务集成的形式发展到更好的架构。

  现在,应用之间的界限更加清晰了。但是,您可以看到,仍然存在隐藏的数据库交互,这一次是在各个应用内部发生的。我称它们为隐藏的,因为通常一开始它们通常很难被注意到。随着时间的流逝,代码的纠缠将使原先分离的业务流程人为地关联起来,并在业务开发中引入更多的摩擦,因为这种共置托管需要联合部署单独的功能,这可能会减慢速度。
  如果您幸运地有一个领域模型来指导的话,则领域建模可帮助您识别和分离复杂的实现。如果您还没有现有应用的域模型(在大多数情况下通常是这样),则无需遍历代码以了解不同的职责,而是构建域模型并将功能映射到手边的应用可能是一个更好的方法。这既能节省时间,又能避免被细节淹没的风险。此外,如果业务与开发团队之间存在差距(这可能是域模型最初不存在的主要原因),那么讨论域模型并映射到现有应用的功能将有助于缩小这一差距。

  我们设计演进的下一步是将域边界分离反映到我们的架构以及边界上下文中。一个域具有多个边界上下文意味着在同一域中可以有多个服务应用运行。有了适当的域模型,潜在的分离点就更可见了,这使我们可以从潜在的更细粒度的应用中受益(诸如单独发行和版本控制的好处,具有更多功能驱动的纯服务端点的潜力等,其中大多数已经在微服务文章中进行了讨论)。尽管许多微服务讨论都围绕技术不可知论和开发规范(避免/破坏整体),但对于我们大多数人所从事的应用而言,非常有价值的一项是领域和设计方面。一旦过渡到微服务架构(借助域模型),DDD 和更细粒度的服务便可以协同工作、相互支持。

  这还将为团队提供一定程度的独立性,更完善的服务功能以及更分离的交互,如许多微服务文章所述.
  同样,从我们的示例信用卡付款获取域中可以看出,这并不是我们的服务可以做到的最细粒度的分离。相反,这是在我们的领域知识所指导下最有意义的分离。重点不是规模,而是业务能力。我相信这是“正确的 SOA”,正如许多圈子所说的那样。

领域驱动设计(DDD)

【注】本文译自: https://www.geeksforgeeks.org/domain-driven-design-ddd/

  领域驱动设计(Domain-Driven Design)是程序员 Eric Evans 于 2004 在他的《 领域驱动设计:解决软件核心中的复杂性》一书中提出的一个概念。
  这是一种自顶向下的软件设计方法。首先,让我们尝试重点介绍一下在这种情况下领域的含义。

什么是领域?

  在软件开发的上下文中,“域”指的是业务。在应用程序开发过程中,通常使用术语域逻辑或业务逻辑。基本上,业务逻辑是应用程序逻辑所围绕的知识领域。 应用程序的业务逻辑是一组规则和指导原则,用于解释业务对象应如何相互交互以处理建模数据。
注意:
  软件工程领域的领域是要在其上构建应用程序的业务。

领域驱动设计:

  假设我们的软件已经使用了所有最新技术堆栈和基础设施,这样的软件设计架构非常棒,但是当我们在市场上发布这个软件时,最终还是要由最终用户来决定我们的系统是否优秀。另外,如果系统不能解决业务需求,对任何人都没有用处;不管它看起来有多漂亮,或者它的基础设施有多好。根据 Eric Evans 的说法,当我们在开发软件时,我们的重点不应该主要放在技术上,而应该主要放在业务上。记住:

“客户的工作不是知道他们想要什么“—史蒂夫·乔布斯

  领域驱动设计涉及两种设计工具,一种是战略设计工具,另一种是战术设计工具。程序员或开发人员通常处理战术设计工具,但如果我们有战略设计工具的知识和良好的理解,它将帮助我们构建好的软件。
  Spring 数据家族下的大多数框架都是根据领域驱动的设计方法构建的。

战略设计:

  战略设计工具帮助我们解决所有与软件建模相关的问题。它是一种类似于面向对象设计的设计方法,在面向对象设计中,我们被迫从对象的角度思考问题。在战略设计方面,我们被迫从环境的角度来思考。

上下文(Context):

  我们可以把这个词看作是一个英语单词,它指的是某一事件、事件、陈述或想法的情况,它的意思可以根据这些情况来确定。
  除了上下文之外,战略设计还讨论了模型、泛在语言和边界语境。这些是领域驱动设计的战略设计中常用的术语。让我们逐一理解。

  • 模型:
      充当核心逻辑并描述领域的选定方面。它用于解决与该业务有关的问题。
  • 通用语言:
      所有团队成员使用的一种公共语言,用于连接团队围绕领域模型的所有活动。与领域专家和团队成员交谈时,可以将其视为对类、方法、服务和对象使用通用动词和名词。
  • 边界上下文:
      指的是上下文的边界条件。它是对边界的描述,并充当一个阈值,在这个阈值中定义并适用于特定的域模型。

    战术设计:

      战术设计讨论实现细节,即建模领域。它通常会处理有界上下文中的组件。我们可能听说过或使用过诸如服务、实体、存储库和工厂之类的东西。它们都是通过域驱动设计创造并流行的。战术设计过程发生在产品开发阶段。
      让我们讨论一些重要的战术设计工具。 这些工具是高级概念,可用于创建和修改域模型。

    1. 实体:
        基于面向对象原则工作的程序员可能知道类和对象的概念。在这里,实体是具有某些属性的类。这些类的实例具有全局标识,并且在整个生命周期中都保持相同的标识。请记住,属性状态可能会发生变化,但身份永远不会改变。简而言之,实体可以实现一些业务逻辑,并且可以使用 ID 进行唯一标识。在编程的上下文中,它通常在 DB 中作为行持久保存,并且由值对象组成。
    2. 值对象:
        它是不可变的轻量级对象,没有任何标识。值对象通过执行复杂的计算,将繁重的计算逻辑与实体隔离开来,从而降低了复杂性。

        在上图中,User 是一个实体,Address 是一个值对象,地址可以更改很多次,但用户的身份证号永远不会更改。每当地址更改时,都会实例化一个新地址并将其分配给用户。
    3. 服务:
        服务是无状态的类,可以适合实体或值对象以外的其他地方。简而言之,服务是一种功能,存在于实体和值对象之间的某个位置,但它既不与实体相关,也不与值对象相关。
    4. 聚合:
        当我们有更大的项目时,对象图也变得更大,更大的对象图更难维护。聚合是位于单个事务边界下的实体和值的集合。基本上是聚合,控制变化,有一个根实体叫做聚合根。根实体以聚合的方式管理其他实体的生命周期。

        在上面的示例中,如果根实体 UserOrder 被删除,则与该根实体关联的其他实体将毫无用处,并且该关联的信息也将被删除。这意味着聚合在本质上总是一致的,这是在域事件的帮助下完成的。生成域事件是为了确保最终的一致性。
        在上面的例子中,如果用户的地址已经改变,那么它必须同样反映在订单上。为此,我们可以触发一个从 User 到 Order 的域事件,以便 Order 更新地址,这样我们就有了最终的一致性,Order 也将最终一致。
        聚合和聚合根的其他例子可以是对帖子的评论、问答细节、银行事务细节等。ORM 工具如 hibernate 在创建一对多或多对一关系时使用了大量聚合。
    5. 工厂和存储库:
        工厂和存储库用于处理聚合。工厂帮助管理聚合生命周期的开始,而存储库帮助管理聚合生命周期的中间和末端。工厂帮助创建聚合,而存储库帮助持久化聚合。我们应该总是为每个聚合根创建存储库,而不是为所有实体创建存储库。
        工厂是 GoF 的设计模式,工厂是有用的,但在聚合规则的上下文中不是强制性的。

      领域驱动设计的优点:

  • 提高了我们的技艺
  • 提供了灵活性
  • 更倾向于域而不是接口
  • 通过通用语言减少了团队之间的沟通差距

    领域驱动设计的缺点:

  • 需要一个具有很强领域专业知识的专业人员
  • 鼓励团队遵循迭代实践

三大业界大佬的DevOps解决方案

  DevOps 在商业界的一些解决方案,主要包括:

  1. 微软公司的 Azure DevOps
  2. 亚马逊公司的 Aws DevOps
  3. 阿里云的 云效 DevOps

Azure DevOps


  Azure DevOps 也称为 Microsoft Visual Studio 团队服务(VSTS)。它是为云构建的一组协作开发工具。 VSTS 通常被用作独立术语,Azure DevOps 是一个由几种不同产品组成的平台,例如:

  • Azure 测试计划
  • Azure 看板
  • Azure 存储库
  • Azure 流水线
  • Azure 制品

  Azure DevOps是将创意转化为工作软件所需的一切。您可以使用 Azure 工具计划项目。

  Azure 流水线是 Azure DevOps 的 CI 组件。Azure 流水线是微软的云原生连续集成服务器,它使团队可以从云中连续构建、测试和部署所有组件。Azure 流水线可以连接到任意数量的源代码存储库,例如 Azure Repos、GitHub、Tests,以获取代码和制品以进行应用交付。

Azure DevOps 服务器

  Azure DevOps Server 是微软的一个产品,提供版本控制、需求管理、报告、软件库管理、项目管理、测试、自动生成和发布管理功能。它涵盖了应用的整个生命周期,并启用了 DevOps 功能。
  Azure DevOps 可以用作众多集成开发环境的后端,但针对 Microsoft Visual Studio 和 Eclipse 的所有平台上进行了定制。

Azure DevOps 服务

  微软宣布在 Microsoft Azure 平台上发布该软件即 Visual Studio 的服务产品,当时微软将其称为在线Visual Studio。

  微软为 Azure DevOps 服务提供了 Visual Studio,基本和利益干系人访问级别。基本计划是免费的,最多可容纳五个用户。订阅了 Visual Studio 的用户可以免费添加到项目中。

AWS DevOps

  AWS 是最好的云服务提供商,DevOps 是软件开发生命周期的实现。

  以下是使 AWS DevOps 成为非常受欢迎的组合的一些原因,例如:

  • AWS CloudFormation
  • AWS EC2
  • AWS CloudWatch
  • AWS CodePipeline

  让我们简要地看一下这些,例如:

AWS CloudFormation


  与开发团队相比,DevOps 团队需要更频繁地创建和发布云实例和服务。诸如 EC2 实例,ECS 容器和 S3 存储桶之类的 AWS 资源模板使您可以设置整个堆栈,而不必将所有内容放在一起。

AWS EC2

  您可以在 EC2 实例中运行容器。因此,您可以利用 AWS 安全和管理功能。

  Amazon EC2 提供最广泛、最深入的实例选择,这些实例构建于最新的计算、存储和网络技术,进行了高性能和安全设计。

AWS CloudWatch


  该监控工具可跟踪 AWS 必须提供的所有资源。轻松使用第三方工具进行监视,例如sumo logic 等。

AWS CodePipeline


  代码流水线是 AWS 的一项重要功能,它极大地简化了你管理 CI / CD 工具集的方式。它与 Jenkins、GitHub 和 CodeDeploy等工具集成,使你可以直观地控制从构建到生产的应用更新流程。

云效 DevOps


  阿里云云效,云原生时代新 DevOps 平台,支持公共云、专有云和混合云多种部署形态,通过云原生新技术和研发新模式,助力创新创业和数字化转型企业快速实现研发敏捷和组织敏捷,打造“双敏”组织,实现 10 倍效能提升。

项目

一站式项目管理

  以项目为维度,管理需求、任务、缺陷、迭代、里程碑、风险和文档。大型项目管理
  支持父子项目以分级管理战略专题项目,支持项目集合以联合管理双十一等大型协作项目。

快速迭代项目管理

  支持Scrum、看板等多种敏捷实践。

应用

应用全生命周期管理

  以应用为单位,申请、创建和配置软件运行所需资源、环境和中间件服务,提供变更、发布、监控和运维等应用全生命周期管理服务。

多种部署运行方式

  支持Docker等多种部署运行方式

交付

持续交付流

  多人协作开发集成、多种编程语言构建打包和分布式集群部署发布等服务。

质量与安全保障

  轻松搭建从代码提交、集成、构建到测试环境、预发环境、线上环境部署发布验证的持续交付流水线,质量和安全层层把关。

运营

用户反馈跟踪

  用户反馈秒级必答,产品知识智能回复。

产品动态监测

  问卷调查和舆情监测,把握产品动态。

数据驱动优化

  分析研发和运营数据,数据驱动效能提升和产品优化创新。