微服务设计(五)---分布式配置中心与spring cloud stream

一、Spring Cloud Stream

  在实际的企业开发中,消息中间件是至关重要的组件之一。消息中间件主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。不同的中间件其实现方式,内部结构是不一样的。如常见的RabbitMQ和Kafka,由于这两个消息中间件的架构上的不同,像 RabbitMQ有exchange,kafka有Topic,partitions分区,这些中间件的差异性导致实际项目开发造成了一定的困扰,如果用了两个消息队列的其中一种,后面的业务需求,想往另外一种消息队列进行迁移,这时候无疑就是一个灾难性的,一大堆东西都要重新推倒重新做,因为它跟我们的系统耦合了,这时候 springCloud Stream提供了一种解耦合的方式。

1、概述

  Spring Cloud Stream由一个中间件中立的核组成。应用通过Spring Cloud Stream插入的input(相当于消费者consumer,它是从队列中接收消息的)和output(相当于生产者producer,它是从队列中发送消 息的)通道与外界交流。通道通过指定中间件的Binder实现与外部代理连接。业务开发者不再关注具体消息中间件,只需关注Binder对应用程序提供的抽象概念来使用消息中间件实现业务即可。

说明:最底层是消息服务,中间层是绑定层,绑定层和底层的消息服务进行绑定,顶层是消息生产者和消息消费者,顶层可以向绑定层生产消息和和获取消息消费

2、核心概念

  绑定器Binder 

  绑定器是Spring Cloud Stream中一个非常重要的概念。在没有绑定器这个概念的情况下,Spring Boot应用要直接与消息中间件进行信息交互的时候,由于各消息中间件构建的初衷不同,实现细节上会有较大的差异性,这使得实现的消息交互逻辑就会非常笨重,因为对具体的中间件实现细节有太重的依赖,当中间件有较大的变动升级、或是更换中间件的时候,就需要付出非常 大的代价来实施。 通过定义绑定器作为中间层,实现了应用程序与消息中间件(Middleware)细节之间的隔离。通过向应用程序暴露统一的Channel通过,使得应用程序不需要再考虑各种不同的消息中间件的实现。当需要升级消息中间件,或者是更换其他消息中间件产品时,需要做的就是更换对应的Binder绑定器而不需要修改任何应用逻辑 。甚至可以任意的改变中间件的类型而不需要修改一行代码。 Spring Cloud Stream支持各种binder实现。

  通过配置把应用和spring cloud stream 的 binder 绑定在一起,之后只需要修改 binder 的配置来达到动态修改topic、exchange、type等一系列信息而不需要修改一行代码。

发布/订阅模型

  在Spring Cloud Stream中的消息通信方式遵循了发布-订阅模式,当一条消息被投递到消息中间件之后,它会通过共享的 Topic 主题进行广播,消息消费者在订阅的主题中收到它并触发自身的业务逻辑处理。这里所提到的 Topic 主题是Spring Cloud Stream中的一个抽象概念,用来代表发布共享消息给消费者的地方。在不同的消息中间件中, Topic 可能对应着不同的概念,比如:在RabbitMQ中的它对应了Exchange、而在Kakfa中则对应了Kafka中的Topic。

二、SpringCloud Config

1、配置中心概述

  对于单体应用而言,常使用配置文件来管理所有配置,比如SpringBoot的application.yml文件, 但是在微服务架构中全部手动修改的话很麻烦而且不易维护。微服务的配置管理一般有以下需求:

  集中配置管理,一个微服务架构中可能有成百上千个微服务,所以集中配置管理是很重要的。 不同环境不同配置,比如数据源配置在不同环境(开发,生产,测试)中是不同的。

  运行期间可动态调整。例如,可根据各个微服务的负载情况,动态调整数据源连接池大小等配置修改后可自动更新。如配置内容发生变化,微服务可以自动更新配置。

综上所述对于微服务架构而言,一套统一的、通用的管理配置机制是不可缺少的总要组成部分。常见的做法就是通过配置服务器进行管理。

2、常见配置中心

  Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。 

3、Spring Cloud Config简介

   Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分, server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。

  Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,可以为所有环境中的应用程序管理其外部属性。非常适合spring应用,也可以使用在其他语言的应用上。随着应用程序通过从开发到测试和生产的部署流程,可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。

4、Spring Cloud Config

(1)概述

  Config Server是一个可横向扩展、集中式的配置服务器,它用于集中管理应用程序各个环境下的配置, 默认使用Git存储配置文件内容,也可以使用SVN存储,或者是本地文件存储。 

(2)配置中心的高可用

  在单机环境中,客户端都是直接调用配置中心的server端来获取配置文件信息。这样就存在了一个问题,客户端和服务端的耦合性太高,如果server端要做集群,客户端只能通过原始的方式来路由, server端改变IP地址的时候,客户端也需要修改配置,不符合springcloud服务治理的理念。 springcloud提供了这样的解决方案,只需要将server端当做一个服务注册到eureka中,client端去 eureka中去获取配置中心server端的服务即可。

(3)消息总线bus

  在微服务架构中,通常会使用轻量级的消息代理来构建一个共用的消息主题来连接各个微服务实例,它广播的消息会被所有在注册中心的微服务实例监听和消费,也称消息总线。 SpringCloud中也有对应的解决方案,SpringCloud Bus将分布式的节点用轻量的消息代理连接起来,可以很容易搭建消息总线,配合SpringCloud config 实现微服务应用配置信息的动态更新。

  根据此图可以看出利用Spring Cloud Bus做配置更新的步骤: 提交代码触发post请求给bus/refresh server端接收到请求并发送给Spring Cloud Bus Spring Cloud bus接到消息并通知给其它客户端其它客户端接收到通知,请求Server端获取最新配置全部客户端均获取到最新的配置。

5、开源配置中心Apollo

(1)Apollo概述

  Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的 配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置 管理场景。服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装 Tomcat等应用容器。 正是基于配置的特殊性,所以Apollo从设计之初就立志于成为一个有治理能力的配置发布平台,目前提供了以下的特性:

  • 统一管理不同环境、不同集群的配置

    • Apollo提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。
    • 同一份代码部署在不同的集群,可以有不同的配置,比如zookeeper的地址等
    • 通过命名空间(namespace)可以很方便地支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖
  • 配置修改实时生效(热发布)

    • 用户在Apollo修改完配置并发布后,客户端能实时(1秒)接收到最新的配置,并通知到应用程序
  • 版本发布管理

    • 所有的配置发布都有版本概念,从而可以方便地支持配置的回滚
  • 灰度发布

    • 支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例
  • 权限管理、发布审核、操作审计

    • 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
    • 所有的操作都有审计日志,可以方便地追踪问题

(2)Apollo的实现方式

上图简要描述了Apollo客户端的实现原理:

  1. 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。

  2. 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。 这是一个fallback机制,为了防止推送机制失效导致配置不更新 客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回 304 - Not Modified 定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval 来覆盖,单位为分钟。

  3. 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中。

  4. 客户端会把从服务端获取到的配置在本地文件系统缓存一份 在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置 5. 应用程序从Apollo客户端获取最新的配置、订阅配置更新通知。

(3)Apollo中的几个核心概念:

  1. application (应用)

    • 实际使用配置的应用,Apollo客户端在运行时需要知道当前使用配置的应用,从而可以去获取对应的配置;
    • 每个应用都需要有唯一的身份标识 -- appId。
  2. environment (环境)

    • 配置对应的环境,Apollo客户端在运行时需要知道当前应用所处环境,从而获取应用的配置
    • 所以环境默认是通过读取机器上的配置(server.properties中的env属性)指定的,也支持运行时通过System Property等指定。
  3. cluster (集群)

    • 一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。

    • 对不同的cluster,同一个配置可以有不一样的值,如zookeeper地址。

    • 集群默认是通过读取机器上的配置(server.properties中的idc属性)指定的,不过也支持运行时通过System Property指定。

  4. namespace (命名空间)

    • 一个应用下不同配置的分组,可以简单地把namespace类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC配置文件,应用自身的配置文件等;

    • 应用可以直接读取到公共组件(公有)的配置namespace,如DAL,RPC等;

    • 应用也可以通过继承(引用)公共组件(公有)的配置namespace来对公共组件的配置做调整,如DAL的初始数据库连接数;

    • 私有namespace只有当前项目可以访问。

   github地址 https://github.com/ctripcorp/apollo

 

 感谢阅读,借鉴了不少大佬资料,如需转载,请注明出处,谢谢!https://www.cnblogs.com/huyangshu-fs/p/13888671.html

 

posted on 2022-10-01 23:54  ys-fullStack  阅读(297)  评论(0编辑  收藏  举报