如何理解Spring Cloud和Docker的微服务架构

77次阅读
没有评论

共计 6489 个字符,预计需要花费 17 分钟才能阅读完成。

如何理解 Spring Cloud 和 Docker 的微服务架构,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Spring Cloud 和 Docker 的微服务架构

功能服务

整体应用被分解成三个核心的微服务。这些微服务是围绕某些业务功能进行组织,可独立部署的应用程序。

如何理解 Spring Cloud 和 Docker 的微服务架构

服务间关系

Account Service(账户服务)

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

如何理解 Spring Cloud 和 Docker 的微服务架构

Statistics Service(统计服务)

对主要统计参数执行计算,并获取每个帐户的时间线。数据点包含标准化为基本货币和时间段的值。这些数据可用于追踪账户一生中的现金流动态

如何理解 Spring Cloud 和 Docker 的微服务架构

Notification Service(通知服务)

保存用户联系信息和消息设置(比如提醒和备份频率),定时器从其他服务器上收集所需的信息并通过 emial 发送给订阅者。

如何理解 Spring Cloud 和 Docker 的微服务架构

注意

·每个微服务都有自己的数据库,不能绕过微服务提供的 API 直接访问微服务的持久化数据。

·这个例子中我采用 mongoDB 作为每个微服务的数据库,用户可以根据微服务的类型选择合适的数据库。

·微服务和微服务间的采用同步的 REST API 进行通信,通常的做法是采用交互风格进行通信,比如:通过同步的 GET 请求来检索数据,通过 Message Broker 使用异步方法来创建 / 更新操作,以便分离服务和缓冲区消息,目标是实现最终一致性。

Infrastructure Services(基础设施服务)

分布式系统中有许多共同的模式,可以帮助我们描述核心服务。spring cloud 提供了强大的工具以帮助 spring boot 应用实现这些模式,下面会做一些简单的介绍:

如何理解 Spring Cloud 和 Docker 的微服务架构

系统架构

Config Service(配置服务)

spring cloud config  是分布式系统中的集中式配置服务。

在这个项目中,我使用 native profile 从本地的 classpath 上加载配置文件,你可以在 shared 目录下面查看 config service resources。比如:当 Notification-service 请求它的配置信息,配置服务会返回如下来两个文件:shared/notification-service.yml 和 shared/application.yml(这个文件会被所有的应用共享).

Client-side Usage(客户端使用)

只要用 spring-cloud-starter-config 依赖构建 Spring Boot 应用程序,其余部分将自动配置

应用中不需要其他任何内置的 properties,只需要提供一个 bootstrap.yml 文件,这个文件中需要包含当前应用的名字和 Config service 的 url

spring:

 application:

   name: notification-service

 cloud:

   config:

     uri: http://config:8888

     fail-fast: true

spring cloud config 支持动态修改 App 的配置信息,比如:在 EmailService bean 上添加 @RefreshScope 注解,这就意味着你可以修改 email 的正文和标题而不用重新编译或者重启 Notification service。具体操作如下:

1、修改 config server 上相关的属性

2、对 Notification service 执行刷新请求:

curl -H Authorization: Bearer #token# -XPOST http://127.0.0.1:8000/notifications/refresh

也可以采用 webhooks 自动执行这个流程

注意

1、动态刷新有如下限制:@RefreshScope 注解无法在 @Configuration 类和 @Scheduled 方法上生效。

2、fail-fast 属性意味着如果服务无法连接上 config service,则服务会在启动期间立即失败。这在一起启动所有服务的时候十分有用。

Auth Service(鉴权服务)

授权职责完全提取到单独的服务器,后者为后端资源服务授予 OAuth3 令牌。身份验证服务器用于用户授权以及在外围进行安全的机器对机器通信。

在这个项目中,我使用密码凭证作为用户授权的授权类型(因为它只被本机应用程序 UI 使用),而客户端凭证作为微服务授权的授权类型。

Spring Cloud Security 提供了便利的注释和自动配置,使得从服务器和客户端都可以轻松实现。您可以在文档中了解更多信息,并查看 Auth Server 代码中的配置详细信息。

客户端与传统的基于 session 的权限验证类似,你可以从 request 中获取 Principal 对象信息,校验用户的角色,使用 @PreAuthorize 注解进行基于正则的访问控制。

每个 client (account-service, statistics-service, notification-service 和 browser)都有一个 scope 属性: server:后台服务, ui: 浏览器,通过 scope 能防止 controller 被外部访问:

@PreAuthorize(#oauth3.hasScope( server) )

@RequestMapping(value = accounts/{name} , method = RequestMethod.GET)

public List getStatisticsByAccountName(@PathVariable String name) {

   return statisticsService.findByAccountName(name);

}

API Gateway

在这个例子中,存在三个核心服务,将外部 API 暴露给客户端,但是在现实世界中,随着系统复杂度的增加,核心服务数也会急剧增长。可能存在一个复杂页面,渲染这个页面需要调用上百个服务。

理论上,客户端应该直接请求每一个微服务,但是这种方式存在很多挑战和局限性,比如:客户端需要了解所有微服务的地址,为每一个信息独立地执行 http 调用,然后在客户端 merger 这些信息。Another problem is non-web-friendly protocols, which might be used on the backend.

通常一个更好的实现方式是使用 API Gateway,它是一个进入系统的单入口,目的是将请求路由到合适的后台服务或者调用多个后台服务并将结果聚合返回给客户端。API Gateway 也会被用来做权限验证,监控,压力测试,服务迁移,静态响应处理和主动流量管理

在 Spring cloud 项目中可以通过 @EnableZuulProxyannotation 注解使用 Netflix 开源的项目 edge service,

在这个例子中我们使用 Zuul 存储静态内容(UI application),路由请求到合适的微服务上,下面是 Notification service 的路由配置:

zuul:

   routes:

       notification-service:

           path: /notifications/**

           serviceId: notification-service

           stripPrefix: false

这个配置意味着所有以 /notifications 开头的请求都会被路由到 Notification service,Notification service 地址并没有硬编码,Zuul 使用服务发现机制定位 Notification service 实例并实现访问的负载均衡。

Service Discovery(服务发现)

通过服务发现能够自动地确定服务实例的网络位置(由于实例数扩展,实例失败 / 更新,会导致服务实例的网络地址发生变化)

服务发现的关键部分是服务注册,在这个例子中我们使用 Netflix Eureka 实现这个功能,Eureka 是基于客户端服务发现模式的一个好的例子,客户端负责确定可用服务实例 (使用注册服务器) 的位置和负载均衡请求。

在 Spring Boot 中,您可以使用 spring-cloud-starter-eureka-server 依赖项,通过 @EnableEurekaServer 注释和简单的配置属性来构建 Eureka Registry。

客户端支持需要使用 @EnableDiscoveryClient 注解和添加包含应用名称的 bootstrap.yml 文件

spring:

   application:

       name: notification-service

在应用启动的时候,它会在 Eureka Serve 中注册,并提供相关的 meta-data 信息 (比如:host,port,健康检查页,主页等)。Eureka 从微服务的每个实例接收心跳信息,如果在约定的时间内(可配置) 没有接受到心跳信息,这个实例就会被注册中心移除。

Eureka 提供了一个简单的页面,在这个页面上你可以查看运行的微服务以及这些服务对应的实例

如何理解 Spring Cloud 和 Docker 的微服务架构

Eureka

Load Balancer, Circuit Breaker, and Http Client(负载均衡,断路器以及 http Client)

Netflix OSS 提供了另外一套优秀的工具集

Ribbon

Ribbon 是一个客户端的负载均衡器,可以通过它控制 HTTP 和 TCP client 请求,与传统的负载均衡器相比,每个线上调用不需要额外的跳跃,你可以直接联系所需的服务。

Eureka 本身与 Spring Cloud 和 Service Discovery 集成在一起,开箱即用,Eureka Client 提供了一个可用服务的动态列表,Ribbon 可以通过这个列表来实现负载均衡。

Hystrix

Hystrix 是熔断器模式的实现,通过网络访问依赖关系来控制延迟和失败。核心思想是在大量微服务的分布式环境中停止级联失败,这有助于系统尽快恢复。

除了提供熔断器,Hystrix 还可以添加一个 fallback 方法,在主命令失败的情况下返回默认值。

而且,Hystrix 为每个命令生成执行结果和延迟的度量标准,我们可以用它来监视系统行为。

Feign

Feign 是一个声明式 HTTP 客户端,与 Ribbon 和 Hystrix 无缝集成。实际上,通过一个 Spring-Cloud-Starter-Feign 依赖和 @EnableFeignClients 批注,您可以拥有一整套负载均衡器,断路器和 HTTP 客户端,并具有合理的随时可用的默认配置。

下面是 Account Service 的一个列子:

@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);

}

上面的例子指定了所需的服务 id – statistics-service,依靠 Eureka 的自动发现

Monitor Dashboard

在这个项目配置中,搭载 Hystrix 的每个微服务都通过 Spring Cloud Bus(使用 AMQP 代理)向 Turbine 推送指标。Monitoring project 只是一个小型的包含 Turbine 和 Hystrix 仪表板的 Spring boot 应用程序。

让我们看看不同负载下的系统行为:Account service 调用 Statistics service,Statistics service 响应模拟不同的延迟。响应超时阈值设置为 1 秒。

如何理解 Spring Cloud 和 Docker 的微服务架构

Monitor Dashboard

Log Analysis

集中式日志在分析分布式系统中存在的问题时十分有效。Elasticsearch, Logstash, 和 Kibana 的技术栈让你轻松搜索和分析你的日志,系统利用率和网络活动数据。在这篇文章中可以找到相关的描述。

Security

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

Infrastructure Automation(基础设置自动化)

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

·随时发布软件的能力。

·任何构建可能最终成为一个 release。

·一次构建工件,根据需要进行部署

这是在这个项目中实现一个简单的持续交付工作流程:

如何理解 Spring Cloud 和 Docker 的微服务架构

持续交付流程

在这个配置中,Travis CI 为每个成功的 Git 推送建立标记的图像。因此,Docker Hub 上的每个微服务总是有最新的镜像,而旧镜像使用 Git commit hash 进行标记。如果需要的话,部署它们很容易并且快速回滚。

How to Run All the Things?

你将启动 8 个 Spring Boot 应用程序,4 个 MongoDB 实例和 RabbitMq。确保您的机器上有 4 Gb RAM。通过 Gateway,Registry,Config,Auth Service 和 Account Service,您始终可以运行重要的服务。

开始之前

·安装 Docker 和 Docker Compose。

·导出环境变量: CONFIG_SERVICE_PASSWORD, NOTIFICATION_SERVICE_PASSWORD, STATISTICS_SERVICE_PASSWORD, ACCOUNT_SERVICE_PASSWORD, MONGODB_PASSWORD

Production Mode

在这种模式下,会从 docker hub 下抓取最新的 images,只需复制 docker-compose.yml 并点击 docker-compose up -d

Development Mode

如果您想自己构建镜像(例如,在代码中进行了一些更改),则必须克隆所有 repository 并使用 Maven 构建。然后运行

docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

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

·Important Endpoints

·Ilocalhost:80 – Gateway

·Ilocalhost:8761 – Eureka Dashboard

·Ilocalhost:9000 – Hystrix Dashboard

·Ilocalhost:8989 – Turbine stream (source for Hystrix Dashboard)

·Ilocalhost:15672 – RabbitMq management

注意

所有 Spring Boot 应用程序都需要依赖运行中的 Config Server 才能启动。但是,我们可以同时启动所有的容器,因为 docker-compose 选项始终存在 Spring Boot 的 fail-fast 和 restart 属性。这意味着所有从属容器将尝试重新启动,直到配置服务器启动并运行。

此外,在所有应用程序启动之后,服务发现机制还需要一些时间,服务都不会立马被客户端的发现,直到实例,Eureka 服务器和客户端在其本地缓存中都具有相同的元数据,因此可能需要 3 个心跳。默认心跳周期是 30 秒。

关于如何理解 Spring Cloud 和 Docker 的微服务架构问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-25发表,共计6489字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)