基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

对着背影说爱祢 提交于 2020-08-19 17:11:38

项目名称

piggymetrics

转发+关注,然后私信回复关键字 “项目”即可获得《piggymetrics》的源码地址

项目简介

这是一个教程项目,演示了使用Spring Boot,Spring Cloud和Docker的微服务架构模式。顺便说一下,拥有漂亮的用户界面。

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

功能服务

PiggyMetrics被分解为三个核心微服务。它们都是围绕某些业务领域组织的可独立部署的应用程序。

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

开户服务

包含一般用户输入逻辑和验证:收入/支出项目,储蓄和账户设置。

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

统计服务

对主要统计参数执行计算,并捕获每个账户的时间序列。数据点包含以标准化为基础货币和时间段的值。此数据用于跟踪账户生命周期中的现金流动态。

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

通知服务

存储用户的联系信息和通知设置(如提醒和备份频率)。计划工从其他服务收集所需的信息,并将电子邮件发送给订阅的客户。

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

笔记

  • 每个微服务都有自己的数据库,因此无法绕过API并直接访问持久性数据。
  • 在这个项目中,作者将MongoDB用作每个服务的主数据库。具有多语言持久性体系结构(选择最适合服务需求的db类型)也可能是有意义的。
  • 服务到服务的通信已大大简化:微服务仅使用同步REST API进行通话。实际系统中的常见做法是使用交互样式的组合。例如,执行同步GET请求以检索数据,并通过消息代理使用异步方法进行创建/更新操作,以使服务和消息分离。但是,这将我们带到了最终的一致性世界。

基础设施服务

分布式系统中有一堆常见的模式,可以帮助我们使描述的核心服务正常工作。Spring Cloud提供了功能强大的工具,这些工具可以增强Spring Boot应用程序的行为以实现这些模式。我会简单介绍一下。

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

配置服务

Spring Cloud Config是用于分布式系统的水平可扩展的集中式配置服务。它使用当前可支持本地存储,Git和Subversion的可插入存储库层。

在此项目中,我使用native profile,它只是从本地类路径加载配置文件。您可以shared在Config服务资源中看到目录。现在,当Notification-service请求其配置时,Config服务将使用
shared/notification-service.yml和进行响应shared/application.yml(在所有客户端应用程序之间共享)。

客户端使用

只要构建
spring-cloud-starter-config依赖项的Spring Boot应用程序,其余的工作就由自动配置完成。

现在,您在应用程序中不需要任何嵌入式属性。只需提供bootstrap.yml应用程序名称和配置服务网址即可:

春季:
   应用程序:
     名称:通知服务
  云:
     配置:
       uri:http:// config:8888 
      fail-fast:true

借助Spring Cloud Config,您可以动态更改应用程序配置。

例如,EmailService bean用注释@RefreshScope。这意味着,您可以更改电子邮件文本和主题,而无需重建和重新启动Notification Service应用程序。

首先,更改配置服务器中的必需属性。然后,执行对通知服务的刷新请求: curl -H "Authorization: Bearer #token#" -XPOST 
http://127.0.0.1:8000/notifications/refresh

另外,您可以使用Repository webhooks自动执行此过程

笔记

  • 但是,对于动态刷新有一些限制。@RefreshScope不适用于@Configuration类,也不影响@Scheduled方法
  • fail-fast 属性意味着如果Spring Boot应用程序无法连接到Config Service,它将立即启动失败。
  • 有显著的安全注意事项如下

验证服务

授权职责已完全提取到单独的服务器,该服务器为后端资源服务授予OAuth2令牌。Auth Server用于用户授权以及外围内部安全的机器对机器通信。

在此项目中,我将Password credentials授予类型用于用户授权(因为仅用于本机PiggyMetrics UI),而将Client Credentials授予类型用于微服务授权。

Spring Cloud Security提供了方便的批注和自动配置,以使其在服务器和客户端均易于实现。您可以在文档中了解更多信息,并在Auth Server代码中查看配置详细信息。

从客户端来看,一切工作都与传统的基于会话的授权完全相同。您可以Principal从请求中检索对象,并使用基于表达式的访问控制和@PreAuthorize注释检查用户的角色以及其他内容。

PiggyMetrics中的每个客户端(账户服务,统计服务,通知服务和浏览器)都有一个范围:server后端服务,以及ui-浏览器。因此,我们还可以保护控制器免受外部访问,例如:

@PreAuthorize(“#oauth2.hasScope( '服务器') ”)
 @RequestMapping(值 =  “账户/ {名称} ”,方法 =  RequestMethod 。 GET)
 公共 列表< 数据点 > getStatisticsByAccountName(@PathVariable  字符串名称){
	 返回 statisticsService 。findByAccountName(name);
}

API网关

如您所见,有三个核心服务,它们向客户端公开外部API。在现实世界的系统中,此数字以及整个系统的复杂性都可以非常迅速地增长。实际上,渲染一个复杂的网页可能涉及数百种服务。

从理论上讲,客户端可以直接向每个微服务发出请求。但是很明显,此选项存在挑战和局限性,例如必须知道所有端点地址,分别对每条信息执行http请求,将结果合并到客户端。另一个问题是可能在后端使用的非Web友好协议。

通常,更好的方法是使用API​​网关。它是系统的单个入口点,用于通过将请求路由到适当的后端服务或调用多个后端服务并汇总结果来处理请求。此外,它还可用于身份验证,洞察力,压力和金丝雀测试,服务迁移,静态响应处理,主动流量管理。

Netflix开源了这种边缘服务,现在有了Spring Cloud,我们可以使用一个@EnableZuulProxy注释启用它。在这个项目中,我使用Zuul存储静态内容(ui应用程序)并将请求路由到适当的微服务。这是通知服务的基于前缀的简单路由配置:

zuul:
   路由:
     通知服务:
         路径:/ notifications / ** 
        serviceId:通知服务
        stripPrefix:false

这意味着所有以开头的请求/notifications都将路由到Notification Service。如您所见,没有硬编码的地址。Zuul使用服务发现机制来定位Notification服务实例以及如下所述的Circuit Breaker和Load Balancer。

服务发现

另一个众所周知的体系结构模式是服务发现。它允许自动检测服务实例的网络位置,由于自动缩放,故障和升级,该服务实例可以动态分配地址。

服务发现的关键部分是注册表。我在这个项目中使用Netflix Eureka。当客户端负责确定可用服务实例的位置(使用注册表服务器)并在它们之间负载均衡请求时,Eureka是客户端发现模式的一个很好的例子。

使用Spring Boot,您可以轻松构建具有
spring-cloud-starter-eureka-server依赖项,@EnableEurekaServer注释和简单配置属性的Eureka Registry 。

客户端支持已启用,并@EnableDiscoveryClient带有bootstrap.yml带有应用程序名称的注释:

春天:
   应用程序:
     名称:通知服务

现在,在应用程序启动时,它将向Eureka Server注册并提供元数据,例如主机和端口,运行状况指示器URL,主页等。Eureka从属于服务的每个实例接收心跳消息。如果心跳在可配置的时间表上进行故障转移,则该实例将从注册表中删除。

此外,Eureka还提供了一个简单的界面,您可以在其中跟踪正在运行的服务和许多可用实例: http://localhost:8761

负载均衡器,断路器和Http客户端

Netflix OSS提供了另一套很棒的工具。

色带

Ribbon是客户端负载平衡器,可让您对HTTP和TCP客户端的行为进行大量控制。与传统的负载平衡器相比,无需每次通过线路调用都需要额外的约点-您可以直接联系所需的服务。

开箱即用,它与Spring Cloud和Service Discovery本地集成。Eureka Client提供了可用服务器的动态列表,因此Ribbon可以在它们之间进行平衡。

Hystrix

Hystrix是Circuit Breaker模式的实现,它可以控制通过网络访问的依赖项引起的延迟和故障。主要思想是在具有大量微服务的分布式环境中停止级联故障。这有助于快速故障并尽快恢复-自我修复的容错系统的重要方面。

除了断路器控制之外,使用Hystrix,您还可以添加一个后备方法,如果主命令失败,该方法将被调用以获取默认值。

此外,Hystrix会针对每个命令生成有关执行结果和延迟的度量,我们可以使用这些度量来监视系统行为。

假装

Feign是一个声明性的Http客户端,它与Ribbon和Hystrix无缝集成。实际上,有了一个
spring-cloud-starter-feign依赖项和@EnableFeignClients注释,您便拥有了一整套负载均衡器,断路器和Http客户端,并具有明智的随时可用的默认配置。

这是来自账户服务的示例:

@FeignClient(名称 =  “ statistics-service ”)
 公共 接口 StatisticsServiceClient {

	@RequestMapping(方法 =  RequestMethod 。 PUT,值 =  “ /统计/ {帐户名} ”,消耗 =  的MediaType 。 APPLICATION_JSON_UTF8_VALUE)
	 空隙 updateStatistics(@PathVariable(“帐户名”)的字符串 帐户名,帐户 的帐户);

}
  • 您所需的一切只是一个界面
  • 您可以@RequestMapping在Spring MVC控制器和Feign方法之间共享一部分
  • 上面的示例仅指定了所需的服务id- statistics-service,这要归功于通过Eureka的自动发现(但显然您可以使用特定的URL访问任何资源)

监控仪表板

在此项目配置中,每个带有Hystrix的微服务都通过Spring Cloud Bus(带有AMQP代理)将指标推送到Turbine。Monitoring项目只是一个带有Turbine和Hystrix Dashboard的小型Spring引导应用程序。

参见下面的如何启动和运行它。

让我们看看负载下的系统行为:帐户服务调用了统计信息服务,并且其响应具有不同的模拟延迟。响应超时阈值设置为1秒。

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

日志分析

在尝试确定分布式环境中的问题时,集中日志记录可能非常有用。Elasticsearch,Logstash和Kibana堆栈使您可以轻松搜索和分析日志,利用率和网络活动数据。作者的另一个项目中介绍了现成的Docker配置。

分布式跟踪

分析分布式系统中的问题可能很困难,例如,跟踪从一个微服务传播到另一个微服务的请求。试图找出请求如何在系统中传输可能是一个很大的挑战,特别是如果您对微服务的实现没有任何了解的时候。即使有日志记录,也很难说出哪个动作与单个请求相关。

Spring Cloud Sleuth通过提供对分布式跟踪的支持来解决此问题。它将两种类型的ID添加到日志记录中:traceId和spanId。spanId代表基本的工作单位,例如发送HTTP请求。traceId包含一组形成树状结构的跨度。例如,对于分布式大数据存储,跟踪可能由PUT请求形成。通过对每个操作使用traceId和spanId,我们可以知道应用程序在处理请求时的时间和位置,从而使读取日志变得更加容易。

日志如下,注意[appname,traceId,spanId,exportable]Slf4J MDC中的条目:

2018-07-26 23:13:49.381  WARN [gateway,3216d0de1384bb4f,3216d0de1384bb4f,false] 2999 --- [nio-4000-exec-1] o.s.c.n.z.f.r.s.AbstractRibbonCommand    : The Hystrix timeout of 20000ms for the command account-service is set lower than the combination of the Ribbon read and connect timeout, 80000ms.
2018-07-26 23:13:49.562  INFO [account-service,3216d0de1384bb4f,404ff09c5cf91d2e,false] 3079 --- [nio-6000-exec-1] c.p.account.service.AccountServiceImpl   : new account has been created: test
  • appname:从属性记录跨度的应用程序的名称 spring.application.name
  • traceId:这是分配给单个请求,作业或操作的ID
  • spanId:发生的特定操作的ID
  • exportable:是否应将日志导出到Zipkin

安全

高级安全配置超出了此概念验证项目的范围。为了更真实地模拟真实系统,请考虑使用https,JCE密钥库来加密微服务密码和Config服务器属性内容

基础设施自动化

相互依赖地部署微服务比部署整体应用程序要复杂得多。拥有完全自动化的基础架构非常重要。我们可以通过持续交付方法获得以下好处:

  • 随时发布软件的能力
  • 任何构建都可能最终成为发行版
  • 一次构建工件-根据需要进行部署

这是在此项目中实现的简单连续交付工作流程:

基于Spring Boot 和Spring Cloud和Docker的微服务架构项目实战

 

在此配置中,Travis CI为每次成功的git push构建标记的图像。因此,latest在Docker Hub上总是有每个微服务的映像和较旧的映像,并用git commit hash标记。如果需要,可以轻松部署其中任何一个并快速回滚。

如何运行所有东西?

请记住,您将启动8个Spring Boot应用程序,4个MongoDB实例和RabbitMq。确保4 Gb计算机上有可用的RAM。但是,您始终可以只运行重要的服务:网关,注册表,配置,身份验证服务和帐户服务。

在你开始前

  • 安装Docker和Docker Compose。
  • 更改.env文件中的环境变量值以提高安全性或保持原样。
  • 确保构建项目: mvn package [-DskipTests]

生产方式

在这种模式下,所有最新映像都将从Docker Hub中提取。只需复制docker-compose.yml并点击docker-compose up

开发模式

如果您想自己构建映像(例如,对代码进行一些更改),则必须克隆所有存储库并使用maven构建工件。然后跑docker-compose -f docker-compose.yml -f docker-compose.dev.yml up

docker-compose.dev.yml继承docker-compose.yml有可能在本地构建映像并公开所有容器端口以方便开发。

如果你想开始IntelliJ IDEA的应用程序,您需要可以使用EnvFile插件或手动上市,出口环境变量.env文件(确保它们分别出口:printenv)

重要终点

  • http:// localhost:80-网关
  • http:// localhost:8761-尤里卡仪表板
  • HTTP://本地主机:9000 /锥 -猬控制板(汽轮机流链接:http://turbine-stream-service:8080/turbine/turbine.stream)
  • http:// localhost:15672 -RabbitMq管理(默认登录名/密码:guest / guest)

笔记

所有Spring Boot应用程序都需要已运行的Config Server才能启动。但是由于depends_ondocker-compose选项,我们可以同时启动所有容器。

另外,所有应用程序启动后,服务发现机制都需要一些时间。在实例,Eureka服务器和客户端在其本地缓存中都具有相同的元数据之前,客户端无法发现任何服务,因此可能需要3个心跳。默认心跳周期为30秒。

转发+关注,然后私信回复关键字 “项目”即可获得《piggymetrics》的源码地址

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!