图片来源:Modern Afflatus的Ash
为什么要使用微服务
传统上,服务被设计成单体架构,所有终端点都由单个服务支持。这种方法的结果是,同一产品的不相关功能最终会放在同一个服务器中。例如,支持你的产品报告需求的服务终端点不一定与其登录或计费终端点相关。然而,它们都存在于同一个服务器中。
这种架构的一个明显问题是,对代码的任何小部分进行微小更改都需要重新部署整个代码库。随着产品越来越大,使用这种方法进行开发和部署变得非常繁琐。为了进行更改和部署,开发人员必须与处理服务器代码的每个团队协调。这种方法显然不够可扩展或敏捷,无法适应快速开发周期。
这就是微服务的用武之地。在基于微服务的架构中,你不再将所有模块放在同一个单体服务中,而是为不同模块设计独立的小型服务。例如,你可以有一个小服务来处理你的计费需求,另一个独立的服务来处理登录。当一个模块需要从另一个模块获取信息时,它可以直接调用相应的微服务的API。
通过这种解耦,开发人员可以专注于自己的特定微服务,并在需要时部署它,而不是等待来自不同模块的更改完成。团队可以完全拥有自己的整个代码库,而且小型代码库更易于维护。如果某个特定微服务出现问题,它只会导致该微服务崩溃;其他独立的微服务仍然会运行。
另一个优点是能够单独扩展微服务。并非所有终端点都被同样使用。例如,登录服务可能比计费服务使用更多。如果我们采用单体架构方法,我们必须扩展整个服务,这样会浪费资源。采用基于微服务的方法,我们只需扩展所需的微服务。在上面的示例中,我们可以有比计费微服务更多的登录微服务实例。
当我们决定在Clover上采用微服务架构时,我们讨论了不同的设计方案。我们尝试过的一种方法是使用Spring Boot和Spring Cloud。本文将讨论使用Spring Boot和Spring Cloud创建微服务的基础知识。Spring Boot可以帮助你轻松创建一个Spring应用程序,而Spring Cloud提供了一组工具,使不同微服务之间的通信更加容易。
Spring Boot
Spring Boot是创建基于Spring应用程序的有效框架。任何具备基本Java编程技能的人都可以快速创建和运行Spring Boot微服务。学习曲线很小,但它可用于创建强大的生产级应用程序。Spring Boot和Spring Cloud提供了许多内置工具和框架,使得开发基于云的微服务非常容易。大多数功能都可以通过使用少量注释来启用,从而使开发变得非常敏捷。
创建简单的Spring Boot应用程序
创建Spring Boot应用程序的最简单方法是使用Spring Initializr。Spring提供了一个易于使用的界面,可生成带有所有必需依赖项的基本Spring Boot项目。
你可以选择Maven或Gradle作为构建工具。你可以选择Java、Kotlin或Groovy作为编程语言,以及你想要的Spring Boot版本。你还可以指定你的组和artifact ID以及你需要的依赖项。
Spring Initializr将生成一个基本的Maven/Gradle项目,你可以将其导入到Eclipse或任何其他IDE中,以用作项目的起点。
生成的项目将具有一个带有@SpringBootApplication
注释的类(通常命名为Application
)。这是Spring Boot应用程序的起点。它看起来像这样:
其余的开发与你开发Spring应用程序的方式完全相同。你定义你的控制器层,并使用注释将请求映射到方法。Spring Boot应用程序将获取注释并将你的请求路由到适当的方法。
示例请求处理程序:
使用Maven/Gradle构建生成JAR/WAR以进行部署。
部署Spring Boot应用程序
- 内嵌服务器: Spring Boot应用程序可以使用内嵌服务器部署。你可以生成一个JAR文件,并像任何其他JAR文件一样运行它。这避免了运行和维护独立服务器实例的需求。进一步简化此过程的是,Spring Boot提供了对内嵌Jetty、Undertow和Tomcat的支持,可以在
pom.xml
(或Gradle)中进行配置,如下所示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
- 独立服务器: 你还可以在独立服务器(例如独立的Tomcat)中部署Spring Boot应用程序。为此,你可以为Spring Boot应用程序生成WAR文件(而不是JAR文件),并像普通WAR文件一样部署它。这将在另一篇文章中介绍。
Spring Cloud
部署微服务的一个关键挑战是处理不同微服务之间的平滑通信。可能需要负载均衡器、某种中央注册表来跟踪哪些微服务正在运行或停止,以及在连接中断的情况下的错误处理等。幸运的是,Spring Cloud提供了工具和框架来轻松完成此任务。我们测试过的一些基本Spring Cloud功能包括使用Eureka的服务发现、使用Ribbon的负载均衡以及使用Hystrix的断路器。
Eureka
部署微服务的一个优点是能够根据需要水平扩展单个服务。当动态地旋转服务的新实例时,使用它的其他服务需要知道其他可用性。显然,硬编码服务实例的地址是不可扩展的。这就是服务发现工具发挥作用的地方。服务发现工具允许单个微服务在部署和运行时将自己注册到注册表中。当客户端需要特定服务时,它可以从发现工具获取服务实例列表,然后查询服务实例。Eureka是一款易于使用的服务发现工具。使用Eureka的第一步是启动一个Eureka服务器。该服务器充当其他服务注册自己的注册表。当一个微服务需要与另一个微服务通信时,它可以查询Eureka以查找该微服务的活动实例。
Eureka服务器可以是另一个Spring Boot应用程序。同样,你可以使用Spring Initializr创建此应用程序。在生成Eureka服务器应用程序时,在Spring Initializr中选择Eureka作为依赖项。
生成应用程序后,编辑应用程序以将注释@EnableEurekaServer
添加到你的Application
类中(如第一个代码片段所示)。
你可以在application.yml
中配置服务器端口。对于本地设置,它看起来像这样:
server:
port: 8086eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
从浏览器中,转到http://localhost:port/,以查看你的Eureka仪表板。
一旦你的Eureka服务器正在运行,下一步是在部署时向你的微服务添加Eureka更改,以便它们向你的Eureka服务器注册。为此,首先将Eureka依赖项添加到pom.xml
中:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
然后,在application.yml
中进行更改以添加Eureka服务器配置。本地设置的示例:
eureka:
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://localhost:8086/eureka
instance:
hostname: localhost
最后,在你的Application
类中添加注释@EnableDiscoveryClient
。
启动服务并检查Eureka仪表板。你的服务应出现在列表中。可选地,你可以启动更多的服务实例以检查它们是否出现在仪表板上。
Ribbon
一旦我们运行了Eureka,当你的服务想要查询另一个服务时,它应从Eureka服务器获取第二个服务的实例列表并调用其中之一。
通过使用另一个名为Ribbon的工具,可以极大地简化这个过程。Ribbon是一个负载均衡器,可以配置为自动从Eureka获取服务的实例列表,并在负载平衡的同时查询服务。
你所有对另一个微服务的查询都将通过Ribbon路由,Ribbon与Eureka交谈以找到你需要查询的微服务实例的实际地址。可以通过application.yml
启用Ribbon:
ribbon:
https:
client:
enabled: true
以下是使用Ribbon和Eureka调用另一个服务的示例代码。在此示例中,我们的函数调用在Eureka上注册为DEMOB名称的第二个服务。(请注意serviceUrl
:它使用此名称而不是某个地址;Ribbon和Eureka负责解析地址。)
还请注意,我们使用@LoadBalanced
和@Bean
注释创建了一个RestTemplate
bean(在第1行中自动连接到restTemplate
受保护的对象)。这对于使RestTemplate使用Ribbon进行负载平衡至关重要。
Hystrix
设置你的微服务之后,它们显然需要通过网络相互通信。即使你尽了最大努力,由于各种原因,对微服务的API调用可能会失败。
在这种情况下,你可以使用Hystrix提供一定程度的容错能力。Hystrix是一个断路器。Hystrix允许你定义一个后备方法,如果你对另一个微服务的网络调用失败,则会调用该方法。一旦服务可用,它将恢复正常行为。
要启用Hystrix,请将以下依赖项添加到pom.xml
中。第一个依赖项允许你添加Hystrix,而第二个依赖项允许你启用Hystrix仪表板,该仪表板允许你监视服务的健康状况。actuator依赖项是收集Hystrix指标所需的。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>\
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
要使用Hystrix仪表板,请将以下内容添加到application.yml
中:
management:
endpoints:
web:
exposure:
include: hystrix.stream
之后,在Application
类中添加注释@EnableHystrixDashboard
和@EnableCircuitBreaker
。
以下代码显示如何在restTemplate
周围编写Hystrix包装器。在callGetService
函数内,如果restTemplate
调用失败,则控制权将移动到@HystrixCommand
注释中提到的后备方法。(这是上面用于说明使用Ribbon的相同代码。)
结论
简而言之,使用Spring Boot创建微服务非常容易。Spring Initializr会处理大部分查找和添加依赖项的工作。如果你熟悉Spring开发,则转换到Spring Boot很简单。你可以仅使用注释而不是复杂的配置来启用大多数功能。学习Spring Boot并使用它构建微服务所需的时间很少。微服务提供了一种轻松的方法,可以从大型单块服务中移动,转向易于维护的小型服务,而Spring Boot提供了一种构建和维护它们的有效方法。
评论(0)