实用 具有Spring Cloud和 Docker 的微服务架构

73 篇文章 0 订阅
27 篇文章 0 订阅

如何使用Spring Boot,Spring Cloud,Docker和Netflix的一些开源工具设置微服务架构。

本文以使用Spring Boot,Spring Cloud和Docker构建的概念验证应用程序为例,为了解常见的微服务架构模式提供了一个起点。

该代码在Github上可用,图像在Docker Hub上可用。你只需一个命令即可启动整个系统。

作为该系统的基础,我选择了一个旧项目,该项目的后端曾经是一个整体。该应用程序提供了一种处理个人财务,组织收入和支出,管理储蓄,分析统计数据以及创建简单预测的方法。

功能服务
整体应用程序被分解为三个核心微服务。它们都是围绕某些业务功能组织的可独立部署的应用程序。
在这里插入图片描述
开户服务
包含常规用户输入逻辑和验证:收入/支出项目,储蓄和帐户设置。
在这里插入图片描述

统计服务
对主要统计参数执行计算,并捕获每个帐户的时间序列。 数据点包含标准化为基础货币和时间段的值。此数据可能用于跟踪帐户生命周期中的现金流量动态。
在这里插入图片描述

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

在这里插入图片描述

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

基础设施服务
分布式系统中有一堆常见的模式,可以帮助我们使描述的核心服务正常工作。 Spring Cloud提供了强大的工具,这些工具可以增强Spring Boot应用程序的行为以实现这些模式。我会简单介绍一下。
在这里插入图片描述
配置服务
Spring Cloud Config是用于分布式系统的水平可扩展集中式配置服务。 它使用了当前支持本地存储,Git和Subversion的可插入存储库层。
在此项目中,我使用本机配置文件,该配置文件仅从本地类路径加载配置文件。你可以在配置服务资源中看到共享目录。 现在,当Notification-service请求进行配置时,Config服务将使用shared / notification-service.yml和shared / application.yml(在所有客户端应用程序之间共享)进行响应。

客户端使用
只需使用spring-cloud-starter-config依赖关系构建Spring Boot应用程序,其余的工作就由自动配置完成。

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

spring:
  application:
    name: notification-service
  cloud:
    config:
      uri: http://config:8888
      fail-fast: true

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

例如,EmailService bean用@RefreshScope注释。这意味着您可以更改电子邮件文本和主题行,而无需重建和重新启动Notification Service应用程序。
首先,在Config服务器中更改所需的属性。然后,对通知服务执行刷新请求:curl -H“ Authorization:Bearer#token#” -XPOST http://127.0.0.1:8000/notifications/refresh
你也可以使用webhooks自动执行此过程。

笔记
尽管如此,动态刷新还是有一些限制。@RefreshScope不适用于@Configuration类,并且不会影响@Scheduled方法。
``快速故障’'属性意味着Spring Boot应用程序无法连接到Config Service时将立即启动失败。当你一起启动所有应用程序时,这非常有用。
下面有重要的安全说明。

验证服务
授权职责已完全提取到单独的服务器中,该服务器为后端资源服务授予OAuth2令牌。Auth Server用于用户授权以及外围内部安全的机器对机器通信。
在此项目中,我将密码凭据用作用户授权的授予类型(因为它仅由本机应用程序UI使用),并将客户端凭据用作微服务授权的授予类型。
Spring Cloud Security提供了方便的批注和自动配置,以使从服务器和客户端两者都真正易于实现。你可以在文档中了解更多信息,并在Auth Server代码中查看配置详细信息
从客户端来看,所有工作都与传统的基于会话的授权完全相同。你可以从请求中检索主体对象,使用基于表达式的访问控制和@PreAuthorize注释检查用户角色和其他内容。
PiggyMetrics中的每个客户端(帐户服务,统计服务,通知服务和浏览器)都有一个范围:服务器用于后端服务,服务器ui用于浏览器。 因此,我们还可以保护控制器免受外部访问,例如:

@PreAuthorize("#oauth2.hasScope('server')")
@RequestMapping(value = "accounts/{name}", method = RequestMethod.GET)
public List<DataPoint> getStatisticsByAccountName(@PathVariable String name) {
    return statisticsService.findByAccountName(name);
}

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

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

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

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

zuul:
  routes:
    notification-service:
        path: /notifications/**
        serviceId: notification-service
        stripPrefix: false

这意味着所有以/通知开头的请求都将被路由到通知服务。如您所见,没有硬编码的地址。Zuul使用服务发现机制来定位Notification服务实例以及电路断路器和负载均衡器,如下所述。

服务发现
另一个众所周知的体系结构模式是服务发现。它允许自动检测服务实例的网络位置,由于自动缩放,故障和升级,该服务实例可以动态分配地址。
服务发现的关键部分是注册表。 我将Netflix Eureka用于该项目。 当客户端负责确定可用服务实例的位置(使用注册表服务器)并在它们之间进行负载平衡请求时,Eureka是客户端发现模式的一个很好的例子。
使用Spring Boot,你可以通过spring-cloud-starter-eureka-server依赖性,@ EnableEurekaServer批注和简单的配置属性轻松构建Eureka Registry。
使用@EnableDiscoveryClient注释和bootstrap.yml启用客户端支持,应用程序名称为:

spring:
  application:
    name: notification-service

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

此外,Eureka还提供了一个简单的界面,你可以在其中跟踪正在运行的服务以及可用实例的数量:http:// localhost:878761
在这里插入图片描述
负载平衡器,断路器和Http客户端
Netflix OSS提供了另一套很棒的工具。

Ribbon
Ribbon是客户端负载平衡器,它使您可以对HTTP和TCP客户端的行为进行大量控制。与传统的负载均衡器相比,每次通过线路调用都不需要额外的跃点-您可以直接联系所需的服务。
开箱即用,它与Spring Cloud和Service Discovery本地集成。 Eureka Client提供了可用服务器的动态列表,因此Ribbon可以在它们之间进行平衡。
Hystrix
Hystrix是Circuit Breaker模式的实现,该模式可以控制通过网络访问的依赖项带来的延迟和故障。主要思想是在具有大量微服务的分布式环境中停止级联故障。这有助于快速故障并尽快恢复-自我修复的容错系统的重要方面。
除了断路器控制之外,使用Hystrix,您还可以添加一个后备方法,如果主命令失败,该方法将被调用以获取默认值。
此外,Hystrix会针对每个命令生成有关执行结果和延迟的指标,我们可以使用这些指标来监控系统行为。
Feign
Feign是一个声明性HTTP客户端,它与Ribbon和Hystrix无缝集成。 实际上,凭借一个spring-cloud-starter-feign依赖性和@EnableFeignClients批注,您具有一整套完整的负载均衡器,断路器和HTTP客户端以及明智的现成默认配置。
这是来自帐户服务的示例:

@FeignClient(name = "statistics-service")
public interface StatisticsServiceClient {
    @RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    void updateStatistics(@PathVariable("accountName") String accountName, Account account);
}

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

监控仪表板
在此项目配置中,每个带有Hystrix的微服务都通过Spring Cloud Bus(带有AMQP代理)将指标推送到Turbine。 Monitoring项目只是一个带有Turbine和Hystrix仪表板的小型Spring引导应用程序。
让我们看一下负载下的系统行为:帐户服务调用统计信息服务,它以不同的模拟延迟响应。 响应超时阈值设置为1秒。

在这里插入图片描述

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

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

基础设施自动化
部署微服务及其相互依赖关系,比部署整体应用程序要复杂得多。 拥有完全自动化的基础架构非常重要。我们可以通过持续交付方法获得以下好处:
随时发布软件的能力。
任何构建都可能最终成为发行版。
一次构建工件,根据需要进行部署。
这是在此项目中实现的简单连续交付工作流程:
在这种配置下,Travis CI为每次成功的Git推送构建标记的图像。因此,Docker Hub上的每个微服务总会有一个最新映像,而旧映像则使用Git commit哈希标记。如果需要,可以轻松部署它们中的任何一个并快速回滚。

如何运行所有东西?

这真的很容易,我建议你尝试一下。请记住,你将启动8个Spring Boot应用程序,4个MongoDB实例和RabbitMq。 确保你的机器上有4 Gb RAM。通过网关,注册表,配置,身份验证服务和帐户服务,你始终可以只运行至关重要的服务。

在你开始前
安装Docker和Docker Compose。
导出环境变量:配置_服务_密码,通知_服务_密码,统计_服务_密码,帐户_服务_密码,MONGODB _密码

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

开发模式
如果你想自己构建映像(例如,对代码进行一些更改),则必须克隆所有存储库并使用Maven构建工件。 然后,运行docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
docker-compose.dev.yml继承了docker-compose.yml,还具有在本地构建映像并公开所有容器端口的更多可能性,以方便开发。

重要端点
本地主机:80-网关
localhost:8761-尤里卡仪表板
localhost:9000-Hystrix仪表板
localhost:8989-涡轮流(Hystrix仪表板的源代码)
localhost:15672-RabbitMq管理

笔记
所有Spring Boot应用程序都需要已运行的Config Server才能启动。 但是由于Spring Boot的快速故障属性和restart:alwaysdocker-compose选项,我们可以同时启动所有容器。 这意味着所有依赖容器将尝试重新启动,直到Config Server启动并运行。
此外,所有应用程序启动后,服务发现机制都需要一些时间。 在实例,Eureka服务器和客户端在其本地缓存中都具有相同的元数据之前,客户端无法发现任何服务,因此可能需要3个听音。 默认听音周期为30秒。

喜欢这篇文章的可以点个赞,欢迎大家留言评论,记得关注我,每天持续更新技术干货、职场趣事、海量面试资料等等
如果你对java技术很感兴趣也可以交流学习,来加入防脱发群 907135806 共同学习进步。
不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代

文章写道这里,欢迎完善交流。最后奉上近期整理出来的一套完整的java架构思维导图,分享给大家对照知识点参考学习。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java干货,以及项目可以拿去练手。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值