购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.5 云和基于微服务的应用程序

在本节中,我们将了解如何使用Spring Boot创建微服务,以及为什么云与基于微服务的应用程序有关。

1.5.1 使用Spring Boot来构建微服务

本节不会详细介绍有关如何创建微服务的诸多代码,而只是简单介绍如何创建服务,以便展示使用Spring Boot是多么简单。为此,我们将创建一个简单的REST服务“Hello World”,它包含一个使用GET HTTP动词的主端点。此服务端点将接收请求参数和URL参数(也称为 路径变量 )的形式接收参数。图1-5展示了REST服务将做什么,Spring Boot微服务将会如何处理用户请求的一般流程。

图1-5 Spring Boot抽象出了常见的REST微服务任务(路由到业务逻辑、从URL中解析HTTP参数、JSON与Java对象相互映射),并让开发人员专注于服务的业务逻辑。此图显示了向控制器传递参数的三种不同方式

这个例子并不详尽,甚至没有说明应该如何构建一个生产级的微服务,但它同样值得你注意,因为它只需要写很少的代码。在第2章之前,我们不打算介绍如何设置项目构建文件或代码的细节。如果你想要查看Maven pom.xml文件以及实际代码,你可以在可下载代码的第1章部分找到它。

注意 第1章中的所有源代码都能在本书的配套源代码中找到。

对于本例,我们有一个名为 Application 的Java类,你可以在类文件 com/huaylupo/ spmia/ch01/SimpleApplication/Application.java 中找到它。我们将使用这个类公开一个名为 /hello 的REST端点。代码清单1-1展示了 Application 类的代码。

代码清单1-1 使用Spring Boot的Hello World:一个(非常)简单的Spring微服务
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication    ⇽---  告诉Spring Boot,该类是Spring Boot服务的入口点
@RestController    ⇽---  告诉Spring Boot,要将该类中的代码公开为Spring RestController
@RequestMapping(value="hello")    ⇽---  此应用程序中公开的所有URL将以前缀/hello开头
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @GetMapping(value="/{firstName}")    ⇽---  公开一个基于GET请求的REST端点,其中包含两个参数:通过@PathVariable获取的firstName和通过@RequestParam获取的lastName
    public String helloGET(
        @PathVariable("firstName") String firstName,    ⇽---  将firstName和lastName参数映射到传入hello方法的两个变量
        @RequestParam("lastName") String lastName) {
        return String.format(
               "{\"message\":\"Hello %s %s\"}",    ⇽---  返回我们手工构建的简单JSON字符串(在第2章中,我们不会创建任何JSON)
                  firstName, lastName);
    }
}

class HelloRequest{    ⇽---  包含用户发送的JSON结构的字段
    private String firstName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

在代码清单1-1中,主要是使用GET HTTP动词公开一个端点,该端点将在URL上取两个参数( firstName lastName ):一个来自路径变量( @PathVariable ),另一个来自请求参数( @RequestParam )。这个端点返回一个简单的JSON字符串,它的净荷包含消息 "Hello firstName lastName" 。如果在服务上调用了端点 /hello/illary?lastName=huaylupo ,返回的结果将会是:

{"message":"Hello illary huaylupo"}

让我们启动Spring Boot应用程序。为此,我们在命令行执行下面的命令:

mvn spring-boot:run

这个Maven命令使用pom.xml文件中定义的Spring Boot插件来使用嵌入式Tomcat服务器启动应用程序。一旦你执行了 mvn spring-boot:run 命令,并且一切启动正确,你应该会在命令行窗口中看到图1-6所示的内容。

注意 如果你从命令行运行命令,请确保你位于根目录中。根目录是包含pom.xml文件的目录。否则,你会遇到这个错误:No plugin found for prefix 'spring-boot' in the current project and in the plugin groups。

Java与Groovy以及Maven与Gradle

Spring Boot框架支持Java和Groovy编程语言。Spring Boot还支持Maven和Gradle构建工具。Gradle引入了基于Groovy的DSL(domain specific language,领域特定语言)来声明项目配置,而不是像Maven那样的XML文件。虽然Gradle是一个强大、灵活的一流工具,但Java开发人员社区仍在使用Maven。因此,本书将只包含Maven中的示例,以保持本书的可管理性,并使内容更聚焦,以便于照顾到尽可能多的读者。

图1-6 Spring Boot服务通过控制台与服务端口通信

要执行服务,你需要使用基于浏览器的REST工具。你会发现,许多工具(包括图形和命令行)都可用于调用基于REST的服务。本书将使用Postman。图1-7和图1-8展示了对端点的两次不同的Postman调用以及从服务中返回的结果。

图1-7 向/hello端点发出GET请求,响应以JSON净荷的形式展示了请求的数据

图1-8 向 /hello 端点发出POST请求,响应以JSON净荷表示请求和响应的数据

图1-8展示了如何使用POST HTTP动词进行调用的简单示例。必须强调的是,这个示例只是用于演示。在接下来的几章中,你将看到,当涉及在我们的服务中创建新记录时,POST方法是首选。

这个简单的示例代码没有展示Spring Boot的全部功能,也没有展示创建一个服务的最佳实践,而是展示了只用几行代码就能用Java编写一个完整的HTTP JSON REST服务,其中带有基于URL和参数的路由映射。虽然Java是一门强大的编程语言,但与其他编程语言相比,它却获得了啰唆冗长的名声,但有了Spring,我们只需要少量行数的代码即可实现诸多功能。接下来,让我们看看为什么以及何时适合使用微服务方法来构建应用程序。

1.5.2 云计算到底是什么

云计算是通过互联网交付计算和虚拟化IT服务——数据库、网络、软件、服务器、分析等,以提供灵活、安全、易于使用的环境。云计算在公司的内部管理中提供了显著的优势,比如低额初始投资、易于使用和维护、可伸缩性等。

云计算模型允许用户选择这些模型提供的信息和服务的控制级别。云计算模型以其首字母缩写而闻名,通常称为XaaS——它是一个缩写,意思是“anything as a service”。最常见的云计算模型有以下几种,图1-9展示了这些模型之间的差异。

基础设施即服务 (Infrastructure as a Service,IaaS)——供应商提供的基础设施,向用户提供服务器、存储和网络等计算资源的访问。在这个模型中,用户负责一切与基础设施维护和应用程序可伸缩性相关的东西。IaaS平台包括AWS(EC2)、Azure虚拟机(Azure Virtual Machines)、谷歌计算引擎(Google Compute Engine)和Kubernetes等。

容器即服务 (Container as a Service,CaaS)——此模型介于IaaS和PaaS之间,它指的是一种基于容器的虚拟化形式。与IaaS模型不同,使用IaaS的开发人员必须管理部署服务的虚拟机,而使用CaaS则可以将微服务部署在一个轻量级、可移植的虚拟容器(如Docker)中,并将其部署到云供应商。云供应商不但运行容器运行所在的虚拟服务器,而且提供用于构建、部署、监控和缩扩容的综合工具。CaaS平台包括谷歌容器引擎(Google Container Engine,GKE),亚马逊的弹性容器服务(Elastic Container Service,ECS)。在第11章中,我们将看到如何将构建的微服务部署到Amazon ECS。

平台即服务 (Platform as a Service,PaaS)——此模型提供平台和环境,让用户专注于应用程序的开发、执行和维护,甚至可以使用供应商提供的工具来创建这些应用程序(例如操作系统、数据库管理系统、技术支持、存储、托管、网络等)。用户不需要在物理基础设施上投入资金,也不需要花时间来管理它,这使得用户可以专注于应用程序的开发。PaaS平台包括Google App Engine、Cloud Foundry、Heroku和AWS Elastic Beanstalk。

函数即服务 (Function as a Service,FaaS)——也称为无服务器架构,尽管名字如此,但这个架构并不意味着在没有服务器的情况下运行特定的代码,它真正的意思是在云中执行功能的一种方式,供应商在云中提供所有必需的服务器。无服务器架构允许我们只关注服务的开发,而不必担心缩扩容、供应和服务器管理。相反,我们可以只专注于上传我们的函数,而不处理任何管理基础设施。FaaS平台包括AWS(Lambda)、Google Cloud Function和Azure Function。

软件即服务 (Software as a Service,SaaS)——也称为按需软件,此模型使用户无须进行任何部署或维护就可以使用特定的应用程序。在大多数情况下,通过Web浏览器访问应用程序。在这个模型中,一切都由服务供应商管理:应用程序、数据、操作系统、虚拟化、服务器、存储和网络。用户只需租用服务并使用软件即可。SaaS平台包括Salesforce、SAP和Google Business。

图1-9 不同的云计算模型归结于用户或云供应商各自要负责什么

注意 如果你不小心,基于FaaS的平台就会将你的代码锁定到一个云供应商平台上,因为你的代码会被部署到供应商特定的运行时引擎上。使用基于FaaS的模型,你可能会使用通用的编程语言(Java、Python、JavaScript等)编写服务,但你仍然会将自己束缚在底层供应商的API和部署函数的运行时引擎上。

1.5.3 为什么是云和微服务

微服务架构的核心概念之一就是每个服务都被打包和部署为离散的独立制品。服务实例应该迅速启动,服务的每一个实例都是完全相同的。在编写微服务时,你迟早要决定是否将服务部署到下列某个环境之中。

物理服务器 ——虽然你可以将微服务构建和部署到物理机器上,但由于物理服务器的局限性,很少有组织会这样做。你无法快速提高物理服务器的容量,并且在多个物理服务器之间水平伸缩微服务的成本可能会非常高。

虚拟机镜像 ——微服务的主要优点之一是能够快速启动和关闭实例,以响应可伸缩性和服务故障事件。虚拟机是主要云供应商的心脏和灵魂。

虚拟容器 ——虚拟容器是在虚拟机镜像上部署微服务的自然延伸。许多开发人员不是将服务部署到完整的虚拟机,而是将他们的服务作为Docker容器(或等效的容器技术)部署到云端。虚拟容器在虚拟机内运行,使用虚拟容器,你可以将单个虚拟机隔离成共享相同虚拟机镜像的一系列独立进程。微服务可以被打包,然后开发人员可以在IaaS私有或公有云中快速部署和启动服务的多个实例。

基于云的微服务的优势是以 弹性 的概念为中心。云服务供应商允许开发人员在几分钟内快速启动新的虚拟机和容器。如果服务的容量需求下降,开发人员可以关闭容器,从而避免产生额外的费用。使用云供应商部署微服务可以显著地提高应用程序的水平可伸缩性(添加更多的服务器和服务实例)。

服务器弹性也意味着应用程序可以更具弹性。如果其中一个微服务遇到问题并且处理能力正在不断地下降,那么启动新的服务实例可以让应用程序保持足够长的存活时间,让开发团队能够从容而优雅地解决问题。

在本书中,所有的微服务和相应的服务基础设施都将使用Docker容器部署到基于CaaS的云供应商。这是用于微服务的常见部署拓扑结构。CaaS云供应商最常见的特征是:

简化基础设施管理 ——CaaS云供应商让开发人员能够对自己的服务拥有更多的控制权。可以通过简单的API调用启动和停止新服务。

大规模的水平可伸缩性 ——CaaS云供应商允许开发人员快速简便地启动服务的一个或多个实例。这种功能意味着可以快速扩大服务以及绕过表现不佳或出现故障的服务器。

通过地理分布实现高冗余 ——CaaS供应商必然拥有多个数据中心。通过使用CaaS云供应商部署微服务,可以比使用数据中心里的集群拥有更高级别的冗余。

为什么不是基于PaaS的微服务

本章前面讨论了5种云平台——基础设施即服务(IaaS)、容器即服务(CaaS)、平台即服务(PaaS)、函数即服务(FaaS)和软件即服务(SaaS)。本书专注于使用基于CaaS的方法构建微服务。虽然某些云供应商可以让你抽象出微服务的部署基础设施,但本书将教你如何独立于供应商,部署应用程序的所有部分(包括服务器)。

例如,Cloud Foundry、AWS Elastic Beanstalk、Google App Engine和Heroku可以让你无须知道底层应用程序容器即可部署你的服务。它们提供了一个Web接口和一个命令行接口(CLI),以允许你将应用程序部署为WAR或JAR文件。应用程序服务器和相应的Java容器的设置和调优都与你无关。虽然这很方便,但每个云供应商的平台都有与其各自的PaaS解决方案相关的不同特点。

本书中构建的服务都会打包为Docker容器。本书选择Docker的主要原因是,Docker可以部署到所有主要的云供应商之中。在后面的章节中,我们将了解Docker是什么,以及如何集成Docker来运行本书中使用的所有服务和基础设施。 eyIv+DW89S2HA4A3BRK9D1OJw0z5vBvwXzhYkl3uI4EbK1KSv7swDaa2h6THipmK

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开