SpringCloud之二:服务注册与配置中心

前言

跟着丁雪丰的课程来到了SpringCloud,如果说SpringBoot是针对单体服务,那这里就是针对多服务了,在这里他主要介绍了以下5个部分:

  • 服务注册与发现
  • 熔断
  • 配置中心
  • 消息
  • 调用链监控

杨波微服务的课程,他少了网关、日志、监控3部分的内容,当然他们的课程是不一样的,一个是SpringCloud,一个是微服务。结合这些课程以及在K8S中的实践,来谈谈一个成熟的系统所应具备的功能。

  • 服务治理

    服务注册、配置中心

  • 请求与流量控制

    网关、熔断限流、调用链监控

  • 监控、日志

    流量监控、中间件监控、系统监控等

    日志与日志分析等几部分

这在以前的2020-03-26微服务框架选择这篇文章里已经有些说明了,这里按这个顺序来细看一下这3部分。

ps: 这篇2019-04-19分布式系统设计模式.md文章也指的复习一下。

服务注册

基本原理

  • 场景

    试想一个系统由多个服务组成,每个服务又运营多个实例这种场景,如何来进行服务控制与管理,既方便服务之间的通信,也方便对外提供服务。

    例如:

    场景

    网上商城系统由User、Order、Goods等服务组成,每个服务又有N台机器示例,服务之间相互关联和调用。

  • 基本角色

    服务注册的3种角色:服务的提供者、服务的消费者、服务注册中心。

  • 基本逻辑

    1. 服务向注册中心进行注册

      服务中心是一个Key-Value的地址列表,维护着服务名-服务地址(ip+port)的映射。

      注册
    2. 服务消费者向注册中心询问提供者的地址

      然后向服务提供者发起访问

      使用
  • 关键点

    1. 对服务提供者的维护

      为保证服务质量,注册中心需要对服务提供者的状态进行检查。最基础的方式就是心跳。几秒钟发一次检查心跳,如果不发或者状态返回不对,则对其进行相应的处理。

    2. 注册中心集群

      注册中心变成成功系统的基础服务,就要保证它不会出现问题。需要搭集群,搭集群就存在一致性问题,需要用Paxos、Raft、Gossip等算法

  • 方案对比

    redis集群方案中,可以看到3种方案:客户端方案、中间件方案、服务端方案。

    客户端方案:客户端知道提供者有哪些,并决定向哪个发起访问。

    中间层方案:中间层代理所有服务提供者,客户端不需要指导具体哪个提供者,直接访问代理商,由代理商决定哪个服务处理请求。中间层可以被认为是网关。

    服务端方案:服务提供者组建成去中心的集群,向任一节点访问等价于向整个集群访问。

    对比一下K8S,K8S的方案应该算是中间件方案。相同的Pod通过Service统一对外提供服务,多个pod共享统一Service的IP,不管是内部的请求还是外部的请求。服务的调用方不需要指导服务者的具体信息,直接进行访问即可,在Service上进行流量的调度,还可以实现负载均衡。见k8s基础

    以前做的SB软总线,也是一种中间层的方案,SB各节点组成集群,各个服务向其进行注册,服务调用通过SB节点进行代理。

    不知道它在处理一致性的时候是用的哪种算法,既然已经有服务中心了,为什么还分主备。

可选组件

注册中心可用的组件比较多:

  • Eureka:Netflix已经不维护了
  • Zookeeper:注册中心更需要AP,Zookeeper是CP。在分区的情况下,可用
  • Consul:正点
  • Nacos:也不错

对比也比较多了,不再多说了,这些选用Consul。

SpringCloud对注册中心进行了抽象,让我们选择任何组件,使用上几乎无差别。

对于服务注册:提供了ServiceRegistry抽象

对于客户发现:提供了DiscoveryClient抽象与LoadBalancerClient抽象

Consul的关键特性:

  1. 服务发现
  2. KV存储
  3. 多数据中心支持
  4. 安全的服务间通信

特色功能:

  1. HTTP API:restful微服务

  2. DNS:提供了服务域名(xxx.service.consul)

    dig命令可查: dig @127.0.0.1 -p 8600 xxx.service.consul

  3. 与Nginx联动

    ngx_http_consul_backend_module

使用

  1. 启动consul

    docker pull consul

    docker run --name consul -d -p 8500:8500 -p 8600:8600/udp consul

  2. pom

    <dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    
  3. 配置文件

    bootstrap.properties,配置本服务的服务名

    spring.application.name=xxx
    

    application.properties,配置consul的地址

    由于服务可以直接注册到consul中,所以不用再配置port

    server.port=0
    spring.cloud.consul.host=localhost
    spring.cloud.consul.port=8500
    spring.cloud.consul.discovery.prefer-ip-address=true
    
  4. application中@EnableDiscoveryClient

    @SpringBootApplication
    @EnableJpaRepositories
    @EnableCaching
    @EnableDiscoveryClient
    public class WaiterServiceApplication implements WebMvcConfigurer {
    }
    
  5. 服务消费者

    一般也需要@EnableDiscoveryClient,正常的去配置HttpClient即可。

    在调用时,注意http的地址,中间为服务名即可。

    ParameterizedTypeReference<List<Coffee>> ptr =
                    new ParameterizedTypeReference<List<Coffee>>() {};
            ResponseEntity<List<Coffee>> list = restTemplate
                    .exchange("http://waiter-service/coffee/", HttpMethod.GET, null, ptr);
    

配置中心

基本原理

配置中心是将在yml中的配置放到配置中心去,这个不仅可以动态的修改配置,也更容易管理所有服务、所有示例的配置。

核心原理上主要是配置文件的加载上,属于SpringBoot的延续。

Spring Cloud Config提供了与Spring中Environment与PropertySource相兼容的一套抽象,相当于在ApplicationContext中增加了一类新的PropertySource。

Spring Cloud Config提供的PropertySource优先级高于本地配置文件所对应的propertySource,应用程序在查属性时,有限查找这些PropertySource。

PropertySource:对于各种基于"名称/值"对(key/value pair)的属性源,Spring将其抽象成了抽象泛型类PropertySource<T>。可以是配置文件、命令行、环境变量等等

Environment:环境相当于PropertySource的一个集合

AppliacationContext:Environment是其一个功能

参考

SpringCloudConfig在生成PropertySource过程中有一个辅助类PropertySourceLocator,在它的唯一的接口locate中通过getRemoteEnvironment来加载远程服务上的Eniroment,然后将其中的PropertySource加载到自己的上下文中。

可选组件

与注册服务类似,Spring Cloud Config提供了统一的抽象。这个可选组件跟服务注册的可选组件基本重合:

  • Zookeeper
  • Consul
  • Nacos

上一节使用的Consul,这里依然选择Consul即可。

知识点

consul包中提供的基本类

Consul提供配置的包是spring-cloud-consul-config,其提供的PropertySource有ConsulPropertySource与ConsulFilesPropertySource。通过ConsulPropertySourceLocator加载

consul中配置变更之后的处理

Consul的变更不是pub/sub的方式,而是一种轮询方式,启动一个ThreadPoolTaskScheduler来处理。

spring.cloud.consul.config.watch.delay=1000

配置加载顺序

以yml为例:

  1. 应用名-profile.yml
  2. 应用名.yml
  3. application-profile.yml
  4. application.yml

使用

  1. 启动consul

  2. pom依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-config</artifactId>
    </dependency>
    
  3. 配置文件

    在bootstrap.properties中配置:

    spring.applcation.name=xxx应用名
    spring.cloud.consul.host=localhost
    spring.cloud.consul.port=8500
    spring.cloud.consul.discovery.prefer-ip-address=true
    
    spring.cloud.consul.config.enabled=true
    spring.cloud.consul.config.format=yaml
    
  4. consul中存数据

    配置存储格式:

    spring.cloud.consul.config.format = KEY_VALUE | YAML | PROPERTIES | FILES
    

    存储位置:/config/xxx应用名/data下

    通过consul提供的图形页面(localhost:8500),在Key/Value中添加,yaml配置即可。

    修改配置后,相应的服务通过轮询可以自动重新加载配置。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×