【Spring Cloud】 服务注册/服务发现

系列文章目录


文章目录


一、背景

1.1、问题描述

上篇文章中我们介绍到远程调用时,我们的URL是写死的,

java 复制代码
String url = "http://127.0.0.1:9090/product/"+ orderInfo.getProductId();

当更换机器, 或者新增机器时, 这个URL就需要跟着变更, 就需要去通知所有的相关服务去修改. 随之而来的就是各个项目的配置文件反复更新, 各个项目的频繁部署. 这种没有具体意义, 但又不得不做的工作, 会让人非常痛苦.

1.2、解决思路

我们生活中, 避免不了和各个机构(医院, 学校, 政府部门等)打交道, 就需要保存各个机构的电话号码. 如果机构换了电话号码, 就需要通知各个使用方, 但是这些机构的使⽤⽅群体是巨大的, 没办法做到一一通知, 怎么处理呢?

机构电话如果发生变化, 通知114. 用户需要联系机构时, 先打114查询电话, 然后再联系各个机构.114查号台的作用主要有两个:

号码注册: 服务方把电话上报给114

号码查询: 使用方通过114可以查到对应的号码

同样的, 微服务开发时, 也可以采用类似的方案.

服务启动/变更时, 向注册中心 报道. 注册中心记录应用和IP的关系.

调用房调用时, 先去注册中心获取服务方的IP, 再去服务方进行调用.

1.3、什么是注册中心?

在最初的架构体系中, 集群的概念还不那么流行, 且机器数量也比较少, 此时直接使用DNS+Nginx就可以满足几乎所有服务的发现. 相关的注册信息直接配置在Nginx. 但是随着微服务的流行与流量的激增,机器规模逐渐变大, 并且机器会有频繁的上下线行为, 这种时候需要运维手动地去维护这个配置信息是⼀个很麻烦的操作. 所以开发者们开始希望有这么⼀个东西, 它能维护⼀个服务列表, 哪个机器上线了,哪个机器宕机了, 这些信息都会自动更新到服务列表上, 客户端拿到这个列表, 直接进行服务调用即可.这个就是注册中心

注册中心主要有三种角色:

•服务提供者(Server):一次业务中, 被其它微服务调用的服务. 也就是提供接口给其它微服务.

•服务消费者(Client):一次业务中, 调用其它微服务的服务. 也就是调用其它微服务提供的接口.

• 服务注册中心(Registry): 用于保存Server 的注册信息, 当Server 节点发生变更时, Registry 会同步变更. 服务与注册中心使用⼀定机制通信, 如果注册中心与某服务长时间无法通信, 就会注销该实例。

他们之间的关系以及工作内容, 可以通过两个概念来描述:

**服务注册:**服务提供者在启动时, 向 Registry 注册自身服务, 并向 Registry 定期发送心跳汇报存活状态.
服务发现: 服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口. 服务发现的⼀个重要作⽤就是提供给服务消费者⼀个可用的服务列表.

1.4、CAP理论

谈到注册中心, 就避不开CAP理论.

CAP 理论是分布式系统设计中最基础, 也是最为关键的理论.

• ⼀致性(Consistency) CAP理论中的⼀致性, 指的是强⼀致性. 所有节点在同⼀时间具有相同的数据

•可用性(Availability) 保证每个请求都有响应(响应结果可能不对)

• 分区容错性(Partition Tolerance)当出现网络分区后,系统仍然能够对外提供服务

举例说明下面:

⼀个部门全国各地都有岗位, 这时候, 总部下发了⼀个通知, 由于通知需要开会周知全员, 当有客户咨询时:

1 . 所有成员对客⼾的回应结果都是⼀致的(⼀致性)

2 . 客户咨询时, ⼀定有回应(可用性)

3 . 当其中一个成员休假时, 这个部⻔的其他成员也可以对客户提供咨询服务(分区容错性)

CAP 理论告诉我们: ⼀个分布式系统不可能同时满足数据⼀致性, 服务可用性和分区容错性这三个基本需求, 最多只能同时满足其中的两个.

在分布式系统中, 系统间的网络不能100%保证健康, 服务又必须对外保证服务. 因此Partition Tolerance不可避免. 那就只能在C和A中选择⼀个. 也就是CP或者AP架构

正常情况:

网络异常:


CP架构: 为了保证分布式系统对外的数据一致性, 于是选择不返回任何数据
AP架构: 为了保证分布式系统的可用性, 节点2返回V0版本的数据(即使这个数据不正确)

1.5、常见的注册中心

1.Zookeeper

Zookeeper的官方并没有说它是一个注册中心, 但是国内Java体系, ⼤部分的集群环境都是依赖Zookeeper来完成注册中心的功能.

  1. Eureka

Eureka是Netflix开发的基于REST的服务发现框架, 主要用于服务注册, 管理,负载均衡和服务故障转移.

官方声明在Eureka2.0版本停止维护, 不建议使用. 但是Eureka是SpringCloud服务注册/发现的默认实现, 所以目前还是有很多公司在使用

3.Nacos

Nacos是Spring Cloud Alibaba架构中重要的组件, 除了服务注册, 服务发现功能之外, Nacos还支持配置管理, 流量管理, DNS, 动态DNS等多种特性.

CAP理论对比:

Zookeeper Eureka Nacos
CAP理论 CP AP CP或AP、默认AP

在分布式环境中, 即使拿到⼀个错误的数据, 也胜过无法提供实例信息而造成请求失败要好(比如淘宝11.11, 京东618都是谨遵AP原则),本系列文章会给大家介绍Eureka和Nacos的使用

二、Eureka介绍

Eureka是Netflix OSS套件中关于服务注册和发现的解决⽅案. Spring Cloud对Eureka进行了集成, 并作为优先推荐方案进行宣传, 虽然目前Eureka 2.0已经停止维护, 新的微服务架构设计中, 也不再建议使用, 但是目前依然有⼤量公司的微服务系统使用Eureka作为注册中心.

Eureka主要分为两个部分:

• Eureka Server: 作为注册中心Server端, 向微服务应用程序提供服务注册, 发现, 健康检查等能力.

• Eureka Client: 服务提供者, 服务启动时, 会向Eureka Server 注册自己的信息(IP,端口,服务信息等),Eureka Server会存储这些信息

关于Eureka的学习, 主要包含以下三个部分:

1 . 搭建Eureka Server

2 . 将order-service, product-service 都注册到Eureka

3 . order-service远程调用时, 从Eureka中获取product-service的服务列表, 然后进行交互

3.搭建Eureka Server

Eureka-server 是⼀个独立的微服务.

3.1 创建Eureka-server 子模块

3.2、引入eureka-server依赖

java 复制代码
<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

3.3 项目构建插件

java 复制代码
 <build>
 	<plugins>
 		<plugin>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-maven-plugin</artifactId>
 	</plugin>
 </plugins>
</build>

3.4、完善启动类

给该项目编写⼀个启动类, 并在启动类上添加 @EnableEurekaServer 注解, 开启eureka注册中心服务

java 复制代码
 	@EnableEurekaServer
    @SpringBootApplication
    public class EurekaServerApplication {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServerApplication.class, args);
        }
    }

3.5、编写配置文件

java 复制代码
server:
 port: 10010
spring:
 application:
 name: eureka-server
eureka:
 instance:
  hostname: localhost
 client:
  fetch-registry: false # 表⽰是否从Eureka Server获取注册信息,默认为true.因为这是⼀个单点的Eureka        Server,不需要同步其他的Eureka Server节点的数据,这⾥设置为false
  register-with-eureka: false # 表⽰是否将⾃⼰注册到Eureka Server,默认为true.由于当前应⽤就是Eureka Server,故⽽设置为false.
  service-url:
 # 设置与Eureka Server的地址,查询服务和注册服务都需要依赖这个地址.
   defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

启动服务后,注册中心就可以实现了。

四、服务注册

接下来我们把product-service 注册到eureka-server中

4.1、引入eureka-client依赖

java 复制代码
<dependency>
 	<groupId>org.springframework.cloud</groupId>
	 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

4.2、完善配置文件

添加服务名称和eureka地址

java 复制代码
spring:
 application:
  name: product-service
eureka:
 client:
   service-url:
    defaultZone: http://127.0.0.1:10010/eureka

启动后服务注册成功

五、服务发现

接下来我们修改order-service, 在远程调用时, 从eureka-server拉取product-service的服务信息, 实现服务发现

5.1、引入依赖

服务注册和服务发现都封装在eureka-client依赖中, 所以服务发现时, 也是引入eureka-client依赖

java 复制代码
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

5.2 完善配置文件

java 复制代码
spring:
 application:
 name: product-service
eureka:
 client:
  service-url:
   defaultZone: http://127.0.0.1:10010/eureka

5.3、远程调用

java 复制代码
    @Slf4j
    @Service
    public class OrderService {
        @Autowired
        private OrderMapper orderMapper;
        @Resource
        private DiscoveryClient discoveryClient;
        @Autowired
        private RestTemplate restTemplate;
        public OrderInfo selectOrderById(Integer orderId) {
            OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
            //String url = "http://127.0.0.1:9090/product/"+ orderInfo.getProductId();
            //根据应⽤名称获取服务列表
            List<ServiceInstance> instances =
                    discoveryClient.getInstances("product-service");
            //服务可能有多个, 获取第⼀个
            EurekaServiceInstance instance = (EurekaServiceInstance)
                    instances.get(0);
            log.info(instance.getInstanceId());
            //拼接url
            String url = instance.getUri()+"/product/"+ orderInfo.getProductId();
            ProductInfo productInfo = restTemplate.getForObject(url,
                    ProductInfo.class);
            orderInfo.setProductInfo(productInfo);
            return orderInfo;
        }
    }

六、Eureka 和Zookeeper区别

Eureka和Zookeeper都是用于服务注册和发现的工具,区别如下:

1 . Eureka是Netflix开源的项目, 而Zookeeper是Apache开源的项目.

2 . Eureka 基于AP原则,保证高可用, Zookeeper基于CP原则, 保证数据⼀致性.

3 . Eureka 每个节点 都是均等的,Zookeeper的节点区分Leader 和Follower 或 Observer, 也正因为这个原因,

如果Zookeeper的Leader发生故障时, 需要重新选举, 选举过程集群会有短暂时间的不可用.

七、总结

以上就是本文全部内容,本文主要为大家介绍了注册中心及CAP理论,以及注册中心的实际相关操作。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持

相关推荐
心疼你的一切5 小时前
昇腾CANN实战落地:从智慧城市到AIGC,解锁五大行业AI应用的算力密码
数据仓库·人工智能·深度学习·aigc·智慧城市·cann
AI绘画哇哒哒5 小时前
【干货收藏】深度解析AI Agent框架:设计原理+主流选型+项目实操,一站式学习指南
人工智能·学习·ai·程序员·大模型·产品经理·转行
数据分析能量站5 小时前
Clawdbot(现名Moltbot)-现状分析
人工智能
那个村的李富贵5 小时前
CANN加速下的AIGC“即时翻译”:AI语音克隆与实时变声实战
人工智能·算法·aigc·cann
二十雨辰5 小时前
[python]-AI大模型
开发语言·人工智能·python
陈天伟教授5 小时前
人工智能应用- 语言理解:04.大语言模型
人工智能·语言模型·自然语言处理
Luhui Dev5 小时前
AI 与数学的融合:技术路径、应用前沿与未来展望(2026 版)
人工智能
power 雀儿5 小时前
Scaled Dot-Product Attention 分数计算 C++
算法
chian-ocean5 小时前
量化加速实战:基于 `ops-transformer` 的 INT8 Transformer 推理
人工智能·深度学习·transformer
那个村的李富贵5 小时前
从CANN到Canvas:AI绘画加速实战与源码解析
人工智能·ai作画·cann