微服务:从设计到部署——六、选择部署策略

本书主要介绍关于如何使用微服务构建应用程序,这是本书的第六章。第一章介绍了微服务架构模式,讨论了使用微服务的优点与缺点。之后的章节讨论了微服务架构的方方面面:使用 API 网关、进程间通信、服务发现和事件驱动数据管理。在本章中,我们将介绍部署微服务的策略。 6.1、动机 部署单体应用程序意味着运行一个或多个相同副本的单个较大的应用程序。您通常会配置 N 个服务器(物理或虚拟),每台服务器上会运行 M 个应用程序实例。单体应用程序的部署并不总是非常简单,但它比部署微服务应用程序要简单得多。 微服务应用程序由数十甚至上百个服务组成。服务以不同的语言和框架编写。每个都是一个迷你的应用程序,具有自己特定的部署、资源、扩展和监视要求。例如,您需要根据该服务的需求运行每个服务的一定数量的实例。此外,必须为每个服务实例提供相应的 CPU、内存和 I/O 资源。更具挑战性的是尽管如此复杂,部署服务也必须快速、可靠和具有成本效益。 有几种不同的微服务部署模式。我们首先看看单主机多服务实例模式。 6.2、单主机多服务实例模式 部署微服务的一种方式是使用单主机多服务实例(Multiple Service Instances per Host)模式。当使用此模式时,您可以提供一个或多个物理主机或虚拟主机,并在每个上运行多个服务实例。从多方面来讲,这是应用程序部署的传统方式。每个服务实例在一个或多个主机的标准端口上运行。主机通常被当作宠物对待。 图 6-1 展示了该模式的结构: 这种模式有几个变体。一个变体是每个服务实例都是一个进程或进程组。例如,您可以在 Apache Tomcat 服务器上将 Java 服务实例部署为 Web 应用程序。一个 Node.js 服务实例可能包含一个父进程和一个或多个子进程。 此模式的另一个变体是在同一进程或进程组中运行多个服务实例。例如,您可以在同一个 Apache Tomcat 服务器上部署多个 Java Web 应用程序,或在同一 OSGI 容器中运行多个 OSGI 软件包。 单主机多服务实例模式有优点也有缺点。主要优点是其资源使用率相对较高。多个服务实例共享服务器及其操作系统。如果进程或进程组运行了多个服务实例(例如,共享相同的 Apache Tomcat 服务器和 JVM 的多个 Web 应用程序),则效率更高。 这种模式的另一个优点是部署服务实例相对较快。您只需将服务复制到主机并启动它。如果服务是使用 Java 编写的,则可以复制 JAR 或 WAR 文件。对于其他语言,例如 Node.js 或 Ruby,您可以直接复制源代码。在任一情况下,通过网络复制的字节数都是相对较小的。 另外,由于缺乏开销,通常启动一个服务是非常快的。如果该服务是自己的进程,你只需要启动它即可。如果服务是在同一容器进程或进程组中运行的几个实例之一,则可以将其动态部署到容器中或者重新启动容器。 尽管这很有吸引力,但单主机多服务实例模式有一些明显的缺点。一个主要的缺点是服务实例很少或者没有隔离,除非每个服务实例是一个单独的进程。虽然您可以准确地监视每个服务实例的资源利用率,但是您不能限制每个实例使用的资源。一个行为不当的服务实例可能会占用掉主机的所有内存或 CPU。 如果多个服务实例在同一进程中运行,那么将毫无隔离可言。例如,所有实例可能共享相同的 JVM 堆。行为不当的服务实例可能会轻易地破坏在同一进程中运行的其他服务。此外,您无法监控每个服务实例使用的资源。 这种方式的另一个重要问题是部署服务的运维团队必须了解部署的具体细节。服务可以用多种语言和框架编写,因此开发团队必须与运维交代许多细节。这种复杂性无疑加大了部署过程中的错误风险。 正如您所见,尽管这种方式简单,但单主机多服务实例模式确实存在一些明显的缺点。现在让我们来看看可以绕过这些问题部署微服务的其他方式。 6.3、每个主机一个服务实例模式 部署微服务的另一种方式是使用每个主机一个服务实例(Service Instance per Host)模式。当使用此模式时,您可以在主机上单独运行每个服务实例。这种模式有两种不同形式:每个虚拟机一个服务实例模式和每个容器一个服务实例模式。 6.3.1、每个虚拟机一个服务实例模式 当您使用每个虚拟机一个服务实例模式时,将每个服务打包成一个虚拟机(VM)镜像(如 Amazon EC2 AMI)。每个服务实例都是一个使用该 VM 镜像启动的 VM(例如,一个 EC2 实例)。 图 6-2 展示了该模式的结构: 这是 Netflix 部署其视频流服务的主要方式。Netflix 使用 Aminator 将每个服务打包为 EC2 […]

龙生   02 Mar 2019
View Details

微服务:从设计到部署——五、事件驱动数据管理

本书主要介绍如何使用微服务构建应用程序,这是本书的第五章。第一章介绍了微服务架构模式,讨论了使用微服务的优点与缺点。第二和第三章描述了微服务架构内通信方式的对比。第四章探讨了与服务发现相关的内容。在本章中,我们稍微做了点调整,研究微服务架构中出现的分布式数据管理问题。 5.1、微服务和分布式数据管理问题 单体应用程序通常具有一个单一的关系型数据库。使用关系型数据库的一个主要优点是您的应用程序可以使用 ACID 事务,这些事务提供了以下重要保障: 原子性(Atomicity) — 所作出的更改是原子操作,不可分割 一致性(Consistency) — 数据库的状态始终保持一致 隔离性(Isolation) — 即使事务并发执行,但他们看起来更像是串行执行 永久性(Durable) — 一旦事务提交,它将不可撤销 因此,您的应用程序可以很容易地开始事务、更改(插入、更新和删除)多行记录,并提交事务。 使用关系型数据库的另一大好处是它提供了 SQL,这是一种丰富、声明式和标准化的查询语言。您可以轻松地编写一个查询,组合来自多个表的数据,之后,RDBMS 查询计划程序将确定执行查询的最佳方式。您不必担心如何访问数据库等底层细节。因为您所有的应用程序数据都存放在同个数据库中,因此很容易查询。 很不幸的是,当我们转向微服务架构时,数据访问将变得非常复杂。因为每个微服务所拥有的数据对当前微服务来说是私有的,只能通过其提供的 API 进行访问。封装数据可确保微服务松耦合、独立演进。如果多个服务访问相同的数据,模式(schema)更新需要对所有服务进行耗时、协调的更新。 更糟糕的是,不同的微服务经常使用不同类型的数据库。现代应用程序存储和处理着各种数据,而关系型数据库并不总是最佳选择。在某些场景,特定的 NoSQL 数据库可能具有更方便的数据模型,提供了更好的性能和可扩展性。例如,存储和查询文本的服务使用文本搜索引擎(如 Elasticsearch)是合理的。类似地,存储社交图数据的服务应该可以使用图数据库,例如 Neo4j。因此,基于微服务的应用程序通常混合使用 SQL 和 NoSQL 数据库,即所谓的混合持久化(polyglot persistence)方式。 分区的数据存储混合持久化架构具有许多优点,包括了松耦合的服务以及更好的性能与可扩展性。然而,它也引入了一些分布式数据管理方面的挑战。 第一个挑战是如何实现业务的事务在多个服务之间保持一致性。要了解此问题,让我们先来看一个在线 B2B 商店的示例。Customer Service (顾客服务)维护客户相关的信息,包括信用额度。Order Service (订单)负责管理订单,并且必须验证新订单,不得超过客户的信用额度。在此应用程序的单体版本中,Order Service 可以简单地使用 ACID 事务来检查可用信用额度并创建订单。 相比之下,在微服务架构中,ORDER (订单)和 CUSTOMER (顾客)表对其各自的服务都是私有的,如图 5-1 所示: Order Service 无法直接访问 CUSTOMER 表。它只能使用客户服务提供的 API。订单服务可能使用了分布式事务,也称为两阶段提交(2PC)。然而,2PC 在现代应用中通常是不可行的。CAP 定理要求您在可用性与 ACID 式一致性之间做出选择,可用性通常是更好的选择。此外,许多现代技术,如大多数 NoSQL 数据库,都不支持 2PC。维护服务和数据库之间的数据一致性至关重要,因此我们需要另一套解决方案。 第二个挑战是如何实现从多个服务中检索数据。例如,我们假设应用程序需要显示一个顾客和他最近的订单。如果 Order Service 提供了用于检索客户订单的 API,那么您可以使用应用程序端连接以检索数据。应用程序从 Customer Service 中检索客户,并从 Order Service 中检索客户的订单。但是,假设 Order Service 仅支持通过主键查找订单(也许它使用了仅支持基于主键检索的 NoSQL 数据库)。在这种情况下,没有有效的方法来检索所需的数据。 5.2、事件驱动架构 许多应用使用了事件驱动架构作为解决方案。在此架构中,微服务在发生某些重要事件时发布一个事件,例如更新业务实体时。其他微服务订阅了这些事件,当微服务接收到一个事件时,它可以更新自己的业务实体,这可能导致更多的事件被发布。 您可以使用事件实现跨多服务的业务的事务。一个事务由一系列的步骤组成。每个步骤包括了微服务更新业务实体和发布一个事件来触发下一步骤。下图依次展示了如何在创建订单时使用事件驱动方法来检查可用信用额度。 微服务通过 Message Broker (消息代理)进行交换事件: Order Service (订单服务)创建一个状态为 NEW 的订单,并发布一个 […]

龙生   02 Mar 2019
View Details

微服务:从设计到部署——四、服务发现

本书主要介绍如何使用微服务来构建应用程序,现在是第四章。第一章已经介绍了微服务架构模式,并讨论了使用微服务的优点与缺点。第二章和第三章介绍了微服务间的通信,并对不同的通信机制作出对比。在本章中,我们将探讨服务发现(service discovery)相关的内容。 4.1、为何使用服务发现 我们假设您正在编写某些代码,这些代码调用了有 REST API 或 Thrift API 的服务。为了发送一个请求,您的代码需要知道服务实例的网络位置(IP 地址与端口)。在运行于物理硬件上的传统应用中,服务实例的网络位置是相对静态的。例如,您的代码可以从偶尔更新的配置文件中读取网络位置。 然而,在现代基于云的微服务应用中,这是一个更难解决的问题,如图 4-1 所示。 服务实例具有动态分配的网络位置。此外,由于自动扩缩、故障与升级,整组服务实例会动态变更。因此,您的客户端代码需要使用更精确的服务发现机制。 有两种主要的服务发现模式:客户端发现(client-side discovery)与服务端发现(server-side discovery)。让我们先来看看客户端发现。 4.2、客户端发现模式 当使用客户端发现模式时,客户端负责确定可用服务实例的网络位置和请求负载均衡。客户端查询服务注册中心(service registry),它是可用服务实例的数据库。之后,客户端利用负载均衡算法选择一个可用的服务实例并发出请求。 图 4-2 展示了该模式的结构 服务实例的网络位置在服务注册中心启动时被注册。当实例终止时,它将从服务注册中心中移除。通常使用心跳机制周期性地刷新服务实例的注册信息。 Netflix OSS 提供了一个很好的客户端发现模式示例。Netflix Eureka 是一个服务注册中心,它提供了一组用于管理服务实例注册和查询可用实例的 REST API。Netflix Ribbon 是一个 IPC 客户端,可与 Eureka 一起使用,用于在可用服务实例之间使请求负载均衡。本章稍后将讨论 Eureka。 客户端发现模式存在各种优点与缺点。该模式相对比较简单,除了服务注册中心,没有其他移动部件。此外,由于客户端能发现可用的服务实例,因此可以实现智能的、特定于应用程序的负载均衡决策,比如使用一致性哈希。该模式的一个重要缺点是它将客户端与服务注册中心耦合在一起。您必须为您使用的每种编程语言和框架实现客户端服务发现逻辑。 现在我们已经了解了客户端发现,接下来让我们看看服务端发现。 4.3、服务端发现模式 服务发现的另一种方式是服务端发现模式。图 4-3 展示了该模式的结构: 客户端通过负载均衡器向服务发出请求。负载均衡器查询服务注册中心并将每个请求路由到可用的服务实例。与客户端发现一样,服务实例由服务注册中心注册与销毁。 AWS Elastic Load Balancer(ELB)是一个服务端发现路由示例。ELB 通常用于负载均衡来自互联网的外部流量。然而,您还可以使用 ELB 来负载均衡虚拟私有云(VPC)内部的流量。客户端通过 ELB 使用其 DNS 名称来发送请求(HTTP 或 TCP)。ELB 负载均衡一组已注册的 Elastic Compute Cloud(EC2)实例或 EC2 Container Service(ECS)容器之间的流量。这里没有单独可见的服务注册中心。相反,EC2 实例与 ECS 容器由 ELB 本身注册。 HTTP 服务器和负载均衡器(如 NGINX Plus 和 NGINX)也可以作为服务端发现负载均衡器。例如,此博文描述了使用 Consul Template 动态重新配置 NGINX 反向代理。Consul Template 是一个工具,可以从存储在 Consul 服务注册中心中的配置数据中定期重新生成任意配置文件。每当文件被更改时,它都会运行任意的 shell 命令。在列举的博文描述的示例中,Consul […]

龙生   01 Mar 2019
View Details

微服务:从设计到部署——三、进程间通信

本书主要介绍如何使用微服务架构构建应用程序,这是本书的第三章。第一章介绍了微服务架构模式,将其与单体架构模式进行对比,并讨论了使用微服务的优点与缺点。第二章描述了应用程序客户端通过扮演中间人角色的 API 网关与微服务进行通信。在本章中,我们来了解一下系统中的服务是如何相互通信的。第四章将详细探讨服务发现方面的内容。 3.1、简介 在单体应用程序中,组件可通过语言级方法或者函数相互调用。相比之下,基于微服务的应用程序是一个运行在多台机器上的分布式系统。通常,每个服务实例都是一个进程。 因此,如图 3-1 所示,服务必须使用进程间通信(IPC)机制进行交互。 稍后我们将了解到多种 IPC 技术,但在此之前,我们先来探讨一下涉及到的各种设计问题。 3.2、交互方式 当为服务选择一种 IPC 机制时,首先需要考虑服务如何交互。有许多种客户端 — 服务交互方式。可以从两个维度对它们进行分类。第一个维度是交互方式是一对一还是一对多: 一对一 — 每个客户端请求都由一个服务实例处理。 一对多 — 每个请求由多个服务实例处理。 第二个维度是交互是同步的还是异步的: 同步 — 客户端要求服务及时响应,在等待过程中可能会发生阻塞。 异步 — 客户端在等待响应时不会发生阻塞,但响应(如果有)不一定立即返回。 下表展示了各种交互方式。 – 一对一 一对多 同步 请求/响应 – 异步 通知 发布/订阅 异步 请求/异步响应 发布/异步响应 表 3-1、进程间通信方式 一对一交互分为以下列举的类型,包括同步(请求/响应)与异步(通知与请求/异步响应): 请求/响应客户端向服务发出请求并等待响应。客户端要求响应及时到达。在基于线程的应用程序中,发出请求的线程可能在等待时发生阻塞。 通知(又称为单向请求)客户端向服务发送请求,但不要求响应。 请求/异步响应客户端向服务发送请求,服务异步响应。客户端在等待时不发生阻止,适用于假设响应可能不会立即到达的场景。 一对多交互可分为以下列举的类型,它们都是异步的: 发布/订阅客户端发布通知消息,由零个或多个感兴趣的服务消费。 发布/异步响应 客户端发布请求消息,之后等待一定时间来接收消费者的响应。 通常,每个服务都组合着使用这些交互方式。对一些服务而言,单一的 IPC 机制就足够了,但其他服务可能需要组合多个 IPC 机制。 图 3-2 显示了当用户请求打车时,打车应用中的服务可能会发生交互。 服务使用了通知、请求/响应和发布/订阅组合。例如,乘客的智能手机向 Trip Management 微服务发送一条通知以请求一辆车。Trip Management 服务通过使用请求/响应来调用 Passenger Management 服务以验证乘客的帐户是否可用。之后,Trip Management 服务创建路线,并使用发布/订阅通知其他服务,包括用于定位可用司机的 Dispatcher。 现在我们来看一下交互方式,我们先来看看如何定义 API。 3.3、定义 API 服务 API 是服务与客户端之间的契约。无论您选择何种 IPC 机制,使用接口定义语言(interface definition language,IDL)来严格定义服务 API 都是非常有必要的。有论据证明使用 API 优先法定义服务更加合理。在对需要实现的服务的 API 定义进行迭代之后,您可以通过编写接口定义并与客户端开发人员进行审阅来开始开发服务。这样设计可以增加您成功的机率,以构建出符合客户端需求的服务。 正如您将会在后面看到,定义 API 的方式取决于您使用何种 IPC […]

龙生   27 Feb 2019
View Details

微服务:从设计到部署——二、使用 API 网关

本书的七个章节是关于如何设计、构建和部署微服务。第一章介绍了微服务架构模式。它阐述了使用微服务的优点与缺点,以及尽管如此,微服务通常是复杂应用的理想选择。该系列的第二章将探讨使用 API 网关构建微服务。 当您选择将应用程序构建成为一组微服务时,您需要决定应用程序客户端将如何与微服务进行交互。单体应用程序只有一组端点(endpoint),通常使用复制(replicated)结合负载均衡来分配流量。 然而,在微服务架构中,每个微服务都暴露一组通常比较细颗粒的端点。在本文中,我们将研究如何改进客户端通信,并提出一个使用 API 网关的方案。 2.1、简介 我们假设您正在为一个购物应用开发一个原生移动客户端。您可能需要实现一个产品详细信息页面,用于展示给定商品的信息。 例如,图 2-1 展示了在 Amazon 的 Android 移动应用中滚动产品信息时所看到的内容。 这是一个智能手机应用,产品详细信息页面展示了许多信息。不仅有基本的产品信息,如名称、描述和价格,页面还展示了: 购物车中的物品数量 订单历史 客户评价 低库存警告 配送选项 各种推荐,包括了购买此产品的客户购买的其他产品 选择性购买选项 在使用单体应用架构的情况下,移动客户端通过对应用程序进行单个 REST 调用来检索此数据,例如:

负载均衡器将请求路由到几个相同应用程序实例中的其中一个。之后,应用程序查询各个数据库表并返回响应给客户端。相比之下,当使用微服务架构时,产品详细页面上展示的数据来自多个微服务。以下是一些微服务,可能拥有给定产品页面展示的数据: 订单服务 — 订单历史 目录(catalog)服务 — 基本的产品信息,如产品名称、图片和价格 评价服务 — 客户评价 库存服务 — 低库存警告 配送服务 — 配送选项、期限和费用,由配送方的 API 单独提供 推荐服务 — 推荐类目 我们需要决定移动客户端如何访问这些服务。让我们来看看有哪些方法。 2.2、客户端与微服务直接通信 理论上,客户端可以直接向每个微服务发送请求。每个微服务都有一个公开的端点:

该 URL 将映射到用于跨可用实例分发请求的微服务负载均衡器。为了检索特定的产品页面信息,移动客户端将向上述的每个微服务发送请求。 不幸的是,这种方式存在着挑战与限制。第一个问题是客户端的需求与每个微服务暴露的细粒度的 API 不匹配。在此示例中,客户端需要进行七次单独请求。如果在更加复杂的应用中,它可能需要做更多的工作。例如,Amazon 展示了在产品页面渲染中如何牵涉到数百个微服务。虽然客户端可以通过 LAN 发送许多请求,但在公共互联网下效率低下,在移动网络必然是不切实际。 客户端直接调用微服务存在的另一个问题是有些可能使用了非 web 友好协议。一个服务可能使用了 Thrift 二进制 RPC,而另一个则可能使用 AMQP 消息协议。这两个协议无论是对浏览器还是防火墙都是不友好的,最好是在内部使用。应用程序在防火墙之外应该使用 HTTP 或者 WebSocket 之类的协议。 这种方法的另一个缺点是它难以重构微服务。随着时间推移,我们可能会想改变系统划分服务。例如,我们可能会合并两个服务或者将服务拆分为两个或者多个。然而,如果客户端直接与服务进行通信,实施这类的重构将变得非常困难。 由于存在这些问题,很少有客户端直接与微服务进行通信。 2.3、使用 API 网关 通常更好的方法是使用 API 网关。API 网关是一个服务器,是系统的单入口点。它类似于面向对象设计模式中的门面(Facade)模式。API 网关封装了内部系统架构,并针对每个客户端提供一个定制 API。它还可用于认证、监控、负载均衡、缓存和静态响应处理。 图 2-3 展示了 API 通常如何整合架构 API 网关负责请求路由、组合和协议转换。所有的客户端请求首先要通过 API 网关,之后请求被路由到适当的服务。API […]

龙生   27 Feb 2019
View Details

微服务:从设计到部署——一、微服务简介

如今微服务倍受关注:文章、博客、社交媒体讨论和会议演讲。微服务正在迅速朝着加德纳技术成熟度曲线(Gartner Hype cycle)的高峰前进。与此同时,也有持怀疑态度的软件社区人员认为微服务没什么新鲜可言。反对者声称它的思想只是面向服务架构(SOA)的重塑。然而,无论是炒作还是怀疑,不可否认,微服务架构模式具有非常明显的优势 — 特别是在实施敏捷开发和复杂的企业应用交付方面。 本书的七个章节主要介绍如何设计、构建和部署微服务,这是本书的第一章。在此章节中,您将了解到微服务的由来和与传统单体应用模式的对比。这本电子书描述了许多关于微服务架构方面的内容。无论是在项目意义还是实施方面,您都能了解到微服务架构模式的优点与缺点。 我们先来看看为什么要考虑使用微服务。 1.1、构建单体应用 我们假设,您开始开发一个打车应用,打算与 Uber 和 Hailo 竞争。经过初步交流和需求收集,您开始手动或者使用类似 Rails、Spring Boot、Play 或者 Maven 等平台来生成一个新项目。 该新应用有一个模块化的六边形架构,如图 1-1 所示: 该应用的核心是由模块实现的业务逻辑,它定义了服务、领域对象和事件。围绕核心的是与外部世界接口对接的适配器。适配器示例包括数据库访问组件、生产和消费消息的消息组件和暴露了 API 或实现了一个 UI 的 web 组件。 尽管有一个逻辑模块化架构,但应用程序被作为一个单体进行打包和部署。实际格式取决于应用程序的语言和框架。例如,许多 Java 应用程序被打包成 WAR 文件部署在如 Tomcat 或者 Jetty 之类的应用服务器上。其他 Java 应用程序被打包成自包含(self-contained)的可执行 JAR。类似地,Rails 和 Node.js 应用程序被打包为有目录层次的结构。 以这种风格编写的应用是很常见的。他们很容易开发,因为我们的 IDE 和其他工具就是专注于构建单体应用。这些应用程序也很容易测试,您可以通过简单地启动并使用如 Selenium 测试包来测试 UI 以轻松地实现端到端(end-to-end)测试。单体应用同样易于部署,你只需拷贝打包好的应用程序到服务器上。您还可以通过运行多个副本和结合负载均衡器来扩展应用。在项目的早期阶段,它可以良好运作。 1.2、走向单体地狱 不幸的是,这种简单的方法有很大的局限性。成功的应用有一个趋势,随着时间推移而变得越来越臃肿。您的开发团队在每个冲刺阶段都要实现更多的用户需求,这意味着需要添加许多行代码。几年之后,小而简单的应用将会逐渐成长成一个庞大的单体。为了给出一个极端示例,我最近和一位开发者做了交谈,他正在编写一个工具,该工具用于从他们的数百万行代码(lines of code,LOC)应用中分析出数千个 JAR 之间的依赖。我相信这是大量开发者在多年齐心协力下创造出了这样的野兽。 一旦您的应用程序成为了一个庞大、复杂的单体,您的开发组织可能会陷入了一个痛苦的境地,敏捷开发和交付的任何一次尝试都将原地徘徊。一个主要问题是应用程序实在非常复杂,其对于任何一个开发人员来说显得过于庞大,这是可以理解的。最终,正确修复 bug 和实现新功能变得非常困难而耗时。此外,这种趋势就像是往下的螺旋。如果基本代码都令人难以理解,那么改变也不会变得正确,您最终得到的将是一个巨大且不可思议的大泥球。 应用程序的规模也将减缓发展。应用程序越大,启动时间越长。我调查过开发者们的单体应用的大小和性能,一些报告的启动时间为 12 分钟。我也听说过应用程序启动需要 40 分钟以上的怪事。如果开发人员经常要重启应用服务器,那么很大一部分时间都是在等待中度过,他们的生产力将受到限制。 另一个大问题是,复杂的单体应用本身就是持续部署的障碍。如今,SaaS 应用发展到了可以每天多次将变更推送到生产环境。这对于复杂的单体来说非常困难,因为您需要重新部署整个应用程序才能更新其中任何一部分。联想到我之前提到的漫长启动时间,这也不会是什么好事。此外,因变更所产生的影响通常不是很明确,您很可能需要做大量的手工测试。因此,持续部署是不可能做到的。 当不同模块存在资源需求冲突时,单体应用可能难以扩展。例如,一个模块可能会执行 CPU 密集型图像处理逻辑,理想情况下是部署在 Amazon EC2 Compute Optimized 实例中。另一个模块可能是一个内存数据库,最适合部署到 EC2 Memory-optimized 实例。然而,由于这些模块被部署在一起,您必须在硬件选择上做出妥协。 单体应用的另一个问题是可靠性。因为所有模块都运行在同一进程中。任何模块的一个 bug,比如内存泄漏,可能会拖垮整个进程。此外,由于应用程序的所有实例都是相同的,该错误将影响到整个应用的可用性。 最后但同样重要,单体应用使得采用新框架和语言变得非常困难。例如,我们假设您有 200 万行代码使用了 XYZ 框架编写。如果使用较新的 ABC 框架来重写整个应用,这将非常昂贵(在时间和成本方面),即使框架非常好。因此,这对于采用新技术是一个非常大的障碍。在项目开始时,您无论选择何种新技术都会感到困扰。 总结一下:您有一个成功的关键业务应用程序,它已经发展成为一个只有少数开发人员(如果有的话)能够理解的巨大单体。它使用了过时、非生产性技术编写,这使得招聘优秀开发人员变得非常困难。应用程序变得难以扩展,不可靠。因此敏捷开发和应用交付是不可能的。 那么您能做些什么呢? 1.3、微服务 — […]

龙生   25 Feb 2019
View Details

SOA(面向服务的架构)

面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。 面向服务架构,它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署、组合和使用。服务层是SOA的基础,可以直接被应用调用,从而有效控制系统中与软件代理交互的人为依赖性。 SOA是一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。SOA可以看作是B/S模型、XML(标准通用标记语言的子集)/Web Service技术之后的自然延伸。 SOA将能够帮助软件工程师们站在一个新的高度理解企业级架构中的各种组件的开发、部署形式,它将帮助企业系统架构者以更迅速、更可靠、更具重用性架构整个业务系统。较之以往,以SOA架构的系统能够更加从容地面对业务的急剧变化。 Soa系统是一种企业通用性架构。 from:https://baike.baidu.com/item/SOA/2140650?fr=aladdin

龙生   25 Feb 2019
View Details

CSS实现两端对齐效果

两端对齐,从概念上来说,其实不难理解。如果不明白什么叫两端对齐,可以玩玩word等办公软件。 下面谈谈如何实现文本的两端对齐。我所知道的大概有以下几种方法 text-align w3school指出,text-align用于设置块级元素内文本的水平对齐方式。如果想使inline元素或inline-block元素居中对齐,可以使用text-align: center方法,对于block元素无法使用text-align实现居中对齐。如果想让block元素居中对齐,可以使用margin: auto方法。 text-align属性下有一个justify值可以设置元素的两端对齐。但是text-align: justify属性有一些不足之处: 在单行文本下,无法实现两端对齐效果。 在多行文本下,无法实现最后一行文本的两端对齐效果。 单行文本

对于多行文本而言,如下图,按照我们的理解应该如右图显示,可是在设置text-align: justify之后,会按照左图显示。无法是西安最后一行文本的两端对齐效果。 解决方法 如果要真正的实现两端对齐效果,可以用以下方法解决。

如果感觉最后多了空行,可以为元素设置一个高度,并且设置overflow: hidden隐藏掉即可。 justify-content CSS3新增的flex布局下,有一个justify-content属性,此属性可以控制伸缩项目的水平对齐方式。其中有两个值,可以实现两端对齐。但是justify-content存在兼容性问题,IE10以上,FF,Chrome都支持。而所有浏览器都支持text-align属性

justify-content: space-around; justify-content: space-between text-justify 还有一个text-justify属性,这个属性估计很少人会使用到,因为只有IE浏览器和FF55以上的浏览器才支持。因为兼容性实在不好,就不说了..   from:https://www.cnblogs.com/unclekeith/p/7073536.html

龙生   25 Feb 2019
View Details

XMPP

全称:可扩展通讯和表示协议 简介:可扩展通讯和表示协议 (XMPP) 可用于服务类实时通讯、表示和需求响应服务中的XML数据元流式传输。XMPP以Jabber协议为基础,而Jabber是即时通讯中常用的开放式协议。XMPP is the IETF’s formalization of the base XML streaming protocols for instant messaging and presence developed within the Jabber open-source community in 1999 XMPP(可扩展消息处理现场协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线现场探测。它在促进服务器之间的准即时操作。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。 XMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。XMPP目前被IETF国际标准组织完成了标准化工作。标准化的核心结果分为两部分; 核心的XML流传输协议 基于XMLFreeEIM流传输的即时通讯扩展应用 XMPP的核心XML流传输协议的定义使得XMPP能够在一个比以往网络通信协议更规范的平台上。借助于XML易于解析和阅读的特性,使得XMPP的协议能够非常漂亮。 XMPP的即时通讯扩展应用部分是根据IETF在这之前对即时通讯的一个抽象定义的,与其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。 XMPP的扩展协议Jingle使得其支持语音和视频。 XMPP的官方文档是RFC 3920. from:https://baike.baidu.com/item/XMPP/3430617?fr=aladdin

龙生   24 Feb 2019
View Details
1 159 160 161 432