写点什么

微服务架构下的服务治理:如何在 SpringCloud 框架中实现服务的注册与发现

发布于: 2021 年 05 月 03 日
微服务架构下的服务治理:如何在SpringCloud框架中实现服务的注册与发现

服务治理

  • RPC 远程过程调用协议的核心设计思想: 在于注册中心, 因为注册中心:管理每个服务与服务之间的一个依赖关系

  • 服务治理: 在传统的 RPC 远程过程调用协议中,管理每个服务与服务之间的依赖关系非常复杂.可以使用服务治理技术,管理每个服务与服务之间的一个依赖关系.可以实现本地负载均衡,服务发现与注册,容错等

服务注册与发现

注册中心

  • 在 RPC 远程过程调用协议中,有一个注册中心

  • SpringCloud 支持三种组册中心:

  • Consul(go 语言)

  • Eureka

  • Zookeeper

  • Dubbo 支持两种注册中心:

  • Zookeeper

  • Redis

  • 注册中心概念: 存放服务地址相关信息(接口地址),通过别名注册获取

  • 原理:

  • 首先启动注册中心

  • 服务提供者(Provider)服务在启动时,把当前服务信息以别名的方式注册到注册中心

  • 服务消费者(Consumer)在调用接口的时候,使用服务别名从注册中心获取 RPC 远程调用地址

  • 服务消费者(Consumer)获取 RPC 远程调用地址后,使用本地 HttpClient 技术实现调用

  • 配置文件:


server.port=8761  # 服务端口号eureka.instance.hostname=127.0.0.1  # 注册中心IP地址eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/  # 注册url地址eureka.client.register-with-eureka=false  # 是否将自己注册到注册中心(集群时需要注册)eureka.client.fetch-registry=false  # 是否需要到注册中心检索服务信息
复制代码


  • 注册中心项目:


1.在主类上标注@EnableEurekaServer注解开启EurekaServer服务,开启注册中心
复制代码

服务注册

  • 将服务信息注册到注册中心上

  • 配置文件:


server.port=8001  # 服务提供者(Provider)服务端口号spring.application.name=Ticket-Service  # 服务别名,注册到注册中心的名称:serviceIdeureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/  # 服务提供者(Provider)注册到eureka注册中心的url地址eureka.client.register-with-eureka=true  # 是否将自己注册到注册中心eureka.client.fetch-registry=true  # 是否需要到注册中心检索服务信息
复制代码


  • 服务提供者(Provider)项目:


1.在主类上标注@EnableEurekaClient注解将服务提供者(Provider)服务注册到注册中心
复制代码

服务发现

  • 从注册中心获取服务信息

  • 配置文件:


server.port=8200  # 服务消费者(Consumer)服务端口号spring.application.name=Ticket-User  # 服务别名,注册到注册中心的名称:serviceIdeureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/  # 服务提供者(Provider)调用服务eureka注册中心的url地址eureka.client.register-with-eureka=true  # 是否将自己注册到注册中心eureka.client.fetch-registry=true  # 是否需要到注册中心检索服务信息
复制代码


  • 服务消费者(Consumer)项目:


1.在SpringCloud有两种方式调用服务:Rest  Fegin(SpringCloud)Rest:- 使用RestTemplate,是SpringBoot的web组件,默认整合Ribbon负载均衡器.底层就是采用的HttpClient技术- 创建RestTemplate并标注@Bean添加方法创建Http服务进行通信- RestTemplate调用有两种方式:采用服务别名调用  直接url调用 restTemplate.getForObject("providerName(替代IP地址)/providerUrl",String.class)2.在主类上标注@EnableEurekaClient(@EnableDiscoveryClient)注解开启服务消费者(Consumer)从注册中心发现服务功能3.使用Rest方式以别名方式调用需要依赖Ribbon负载均衡器,在RestTemplate方法上标注  @LoadBalanced,让RestTemplate在请求时拥有客户端的负载均衡的能力
复制代码


  • Ribbon 负载均衡:

  • 在集群操作中:

  • 首先启动注册中心

  • 多个服务提供者(Provider)服务在启动时,把当前服务信息以别名的方式注册到注册中心

  • 多个服务消费者(Consumer)在调用接口的时候,使用服务别名从注册中心获取 RPC 远程调用地址

  • 服务消费者(Consumer)获取 RPC 远程调用地址后,先使用 Ribbon 负载均衡器实现负载均衡再使用本地 HttpClient 技术实现调用

  • 负载均衡基本策略: 轮询机制(默认)

集群

  • 微服务 RPC 远程过程调用协议的核心:服务治理:注册中心

  • 搭建注册中心集群: 可以解决注册中心故障导致整个微服务环境不可用的问题

  • Eureka 高可用原理:

  • 默认情况下,Eureka 是让服务注册的服务注册中心,不注册自己

  • Eureka 高可用就是将自己作为服务向其它注册中心注册自己, 形成一组相互注册的服务注册中心,实现服务清单的互相同步, 达到高可用效果

  • 注册中心集群:

  • 在注册服务过程中,只会保证有一台注册中心有对应的服务信息数据即可,只有注册中心宕机后,才启动同步数据到其它注册中心

  • 配置文件:


server.port=9000  # 服务端口号spring.application.name=euraka  # 注册中心集群上服务器的名称要保持一致eureka.instance.hostname=127.0.0.1  # 注册中心IP地址eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:8761/eureka/  # ,注册到其它注册中心的url地址eureka.client.register-with-eureka=true  # 是否将自己注册到注册中心(集群时需要注册)eureka.client.fetch-registry=true  # 是否需要到注册中心检索服务信息
复制代码

Eureka 自我保护机制

  • Eureka 自我保护机制: 为了防止 EurekaClient 可以正常运行时,与 EurekaServer 在网络无法通信的情况下,EurekaServer 误将 EurekaClient 服务剔除


1.默认情况下,EurekaClient端定时向EurekaServer端发送心跳包2.如果EurekaServer端在<一定时间>内没有收到EurekaClient端发送的心跳包,便会直接从服务注册列表中剔除该服务3.在<短时间>内如果丢失了大量的服务实例心跳包,EurekaServer端会开启自我保护机制,不会剔除EurekaClient端
复制代码


  • 在本地开发环境中,测试时建议关闭 EurekaServer 端自我保护机制,保证不可用服务及时被剔除:


配置文件:EurekaServer端:eureka.server.enable-self-preservation=false     # 是否开启自我保护机制(默认开启true) eureka.server.eviction-interval-timer-in-ms=2000  # 剔除间隔2秒
EurekaClient端-服务提供者(Provider):# 心跳检测和续约时间,在测试程序时,将值设置小些,保证服务关闭后,注册中心及时剔除服务eureka.instance.lease-renewal-interval-in-seconds=1 # EurekaClient端向EurekaServer端发送心跳的时间间隔秒eureka.instance.lease-expiration-duration-in-seconds=2 # EurekaServer端在收到最后一次心跳之后等待时间上限秒,超过就剔除服务
复制代码

Zookeeper

  • Eureka 闭源,使用 Zookeeper 替代 Eureka 作为注册中心

  • Zookeeper 是分布式协调工具,可以实现注册中心的功能,采用 Zookeeper 的临时节点类型

  • 临时节点和生命周期是相关联的,如果服务断开连接之后,临时节点就会被自动删除


配置文件:ZookeeperClient-服务提供者(Provider):server.port=8090  # 服务端口号spring.application.name=zk-ticket  # 服务别名,注册到注册中心的名称spring.cloud.zookeeper.connect-string=127.0.0.1:2181  #注册到zookeeper注册中心的url地址 
ZookeeperClient-服务消费者(Consumer):server.port=8020 # 服务端口号spring.application.name=zk-user # 服务别名,注册到注册中心的名称spring.cloud.zookeeper.connect-string=127.0.0.1:2181 #调用服务的zookeeper注册中心的url地址

1.ZookeeperClient-服务提供者(Provider)在主类上标注@EnableDiscoveryClient注解向注册中心注册服务2.ZookeeperClient-服务消费者(Consumer)在主类上标注@EnableDiscoveryClient注解从注册中心调用服务3..在调用服务的方法上标注@LoadBalanced开启Ribbon的负载均衡功能进行服务的调用
复制代码

Consul

  • Consul 是开源的分布式服务发现与配置管理系统,由 HashiCorp 公司用 Go 语言开发

  • 特点:

  • 基于 raft 协议,比较简洁

  • 支持健康检查

  • 支持 Http 和 DNS 协议

  • 支持跨数据中心的 WAN 集群

  • 提供图形界面

  • 跨平台

  • Consul 环境搭建:

  • 下载 Consul

  • 设置环境变量:添加 Consul 所在目录

  • cmd 启动:consul agent -dev -ui -node=cy(-dev:开发服务器模式启动 -node:节点名 -ui 界面访问支持,默认开启)

  • 访问 Consul: http://localhost:8500


配置文件:ConsulClient-服务提供者(Provider):server.port=8780  # 服务端口号spring.application.name=consul-ticket  # 服务别名,注册到注册中心的名称spring.cloud.consul.host=127.0.0.1    # Consul服务url地址spring.cloud.consul.port=8500      # Consul服务端口号spring.cloud.consul.discovery.hostname=192.168.66.128  # 服务在注册中心显示的IP地址(默认情况下,服务注册到注册中心,地址随机生成)
ConsulClient-服务消费者(Consumer):server.port=8099 # 服务端口号spring.application.name=consul-user # 服务别名,注册到注册中心的名称spring.cloud.zookeeper.connect-string=127.0.0.1:2181 #服务调用服务Consul注册中心的url地址

1.ZookeeperClient-服务提供者(Provider)在主类上标注@EnableDiscoveryClient注解向注册中心注册服务2.ZookeeperClient-服务消费者(Consumer)在主类上标注@EnableDiscoveryClient注解从注册中心调用服务3..在调用服务的方法上标注@LoadBalanced开启Ribbon的负载均衡功能进行服务的调用
复制代码

DiscoveryClient

  • 获取注册中心的服务信息

  • 用于实现本地负载均衡


@Autowired    // 自动装配private DiscoveryClient discoveryClient;  // Discovery接口,用于获取注册中心的服务信息

@RequestMapping("/discoveryClientMember")public List<ServiceInstance> discoveryClientMember(){ List<ServiceInstance> instances=discoveryClient.getInstance("consul-ticket"); for(ServiceInstance serviceInstance:instances){ System.out.println("URI:"+serviceInstance.getUri()); } return instance;}
复制代码


发布于: 2021 年 05 月 03 日阅读数: 20
用户头像

一位攻城狮的自我修养 2021.04.06 加入

分享技术干货,面试题和攻城狮故事。 你的关注支持是我持续进步的最大动力! https://github.com/ChovaVea

评论

发布
暂无评论
微服务架构下的服务治理:如何在SpringCloud框架中实现服务的注册与发现