微服务架构中的精妙设计:服务注册/服务发现-Eureka

一.使用注册中心背景 

1.1服务远程调用问题

服务之间远程调⽤时, 我们的URL是写死的 

String url = "http://127.0.0.1:9090/product/"+ orderInfo.getProductId();

缺点:

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

 

解决方法:

这样就类似解决高耦合的思想,引入第三方来保存保存和交互双方信息

我们⽣活中, 避免不了和各个机构(医院, 学校, 政府部⻔等)打交道, 就需要保存各个机构的电话号码. 如果机构换了电话号码, 就需要通知各个使⽤⽅, 但是这些机构的使⽤⽅群体是巨⼤的, 没办法做到⼀⼀通知, 怎么处理呢?
机构电话如果发⽣变化, 通知114. ⽤⼾需要联系机构时, 先打114查询电话, 然后再联系各个机构.

 

114查号台的作⽤主要有两个:
  • 号码注册: 服务方把电话上报给114
  • 号码查询: 使用方通过114可以查到对应的号码

 

同样的, 微服务开发时, 也可以采⽤类似的⽅案.
  • 服务启动/变更时, 向注册中心报道. 注册中心记录应用和IP的关系.
  • 调⽤⽅调⽤时, 先去注册中心获取服务⽅的IP, 再去服务⽅进⾏调⽤

 1.2什么是注册中心

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

 注册中⼼主要有三种⻆⾊:

  • 服务提供者(Server):⼀次业务中, 被其它微服务调用的服务. 也就是提供接⼝给其它微服务.
  • 服务消费者(Client):⼀次业务中, 调用其它微服务的服务. 也就是调⽤其它微服务提供的接⼝.
  • 服务注册中⼼(Registry): ⽤于保存Server 的注册信息, 当Server 节点发⽣变更时, Registry 会同步变更. 服务与注册中⼼使⽤⼀定机制通信, 如果注册中⼼与某服务⻓时间⽆法通信, 就会注销该实例

 

1.3CAP理论

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

  • ⼀致性(Consistency) CAP理论中的⼀致性, 指的是强⼀致性. 所有节点在同⼀时间具有相同的数据
  • 可⽤性(Availability) 保证每个请求都有响应(响应结果可能不对)
  • 分区容错性(Partition Tolerance) 当出现⽹络分区后,系统仍然能够对外提供服务
⼀个部门全国各地都有岗位, 这时候, 总部下发了⼀个通知, 由于通知需要开会周知全员, 当有客户咨询时:
所有成员对客户的回应结果都是⼀致的(⼀致性)
客户咨询时, ⼀定有回应(可用性)
当其中⼀个成员休假时, 这个部门的其他成员也可以对客户提供咨询服务(分区容错性)
CAP 理论告诉我们: ⼀个分布式系统不可能同时满⾜数据⼀致性, 服务可⽤性和分区容错性这三个基本需求, 最多只能同时满⾜其中的两个
为什么?
  • 如果要保证一致性,总部有了新通知,就必须等所有地区的成员都收到通知后,才能统一回应客户。但这样在网络故障期间,那些没收到通知的地区成员就无法回应客户,也就牺牲了可用性。
     
  • 如果要保证可用性,不管网络有没有问题,只要客户来咨询,成员们就得马上回应。但这样一来,在网络分区的情况下,那些没收到新通知的成员可能就会给出和收到通知的成员不一样的回应,也就牺牲了一致性。
在分布式系统中, 系统间的⽹络不能100%保证健康, 服务⼜必须对外保证服务. 因此Partition
Tolerance不可避免. 那就只能在C和A中选择⼀个. 也就是CP或者AP架构
CP架构: 为了保证分布式系统对外的数据⼀致性, 于是选择不返回任何数据
AP架构: 为了保证分布式系统的可⽤性, 即使数据不一致,也要保证响应

1.4常见的注册中心

  1. Zookeeper
    Zookeeper的官⽅并没有说它是⼀个注册中⼼, 但是国内Java体系, ⼤部分的集群环境都是依赖 Zookeeper来完成注册中⼼的功能.
  2. Eureka:
    Eureka是Netflix开发的基于REST的服务发现框架, 主要⽤于服务注册, 管理,负载均衡和服务故障转移. 官⽅声明在Eureka2.0版本停⽌维护, 不建议使⽤. 但是Eureka是SpringCloud服务注册/发现的默认实现, 所以⽬前还是有很多公司在使⽤.
  3. Nacos:
    Nacos是Spring Cloud Alibaba架构中重要的组件, 除了服务注册, 服务发现功能之外, Nacos还⽀持配置管理, 流量管理, DNS, 动态DNS等多种特性

 CAP理论对比 

 

在分布式环境中, 即使拿到⼀个错误的数据, 也胜过⽆法提供实例信
11.11, 京东618都是谨遵AP原则)

 

二.Eureka介绍

Eureka是Netflix OSS套件中关于服务注册和发现的解决⽅案. Spring Cloud对Eureka进⾏了集成, 并作为优先推荐⽅案进⾏宣传, 虽然⽬前Eureka 2.0已经停⽌维护, 新的微服务架构设计中, 也不再建议使⽤, 但是⽬前依然有⼤量公司的微服务系统使⽤Eureka作为注册中⼼
官⽅⽂档: https://github.com/Netflix/eureka/wiki
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的服务列表, 然后进⾏交互

2.1搭建Eureka Server

 Eureka-server 是⼀个独立的微服务,我也通过子项目形式编写

1.搭建注册中心

2.pom文件添加Eureka依赖

 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

3. 创建配置文件,增加Eureka相关的配置

 

server:port: 10010
spring:application:name: eureka-server
eureka:instance:hostname: localhostclient:fetch-registry: false # 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为falseregister-with-eureka: false # 表示是否将自己注册到Eureka Server,默认为true.由于当前应用就是Eureka Server,故而设置为false.service-url:# 设置Eureka Server的地址,查询服务和注册服务都需要依赖这个地址defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4.启动类,开启Eureka的功能

 

package eureka;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {public static void main(String[] args) {SpringApplication.run(EurekaServiceApplication.class,args);}
}

 5.启动项目成功嘿嘿

 


2.2服务注册 

服务注册:针对提供给order订单服务的product产品服务 

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

1. product的pom文件加入Eureka的依赖 

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

 
2. application.yml修改配置信息

1.添加该服务的信息

2.添加相关eureka配置信息 


3. 启动,测试

 

 


2.3服务发现

服务发现:针对消费produc产品服务的order订单服务

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

1. 加入Eureka依赖

 

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>


2.application.yml修改配置信息

1.添加该服务的信息

2.添加相关eureka配置信息 

servic:port: 8080spring:application:name: order-servicedatasource:url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncoding=utf8&useSSL=falseusername: rootpassword: weigang527driver-class-name: com.mysql.cj.jdbc.Drivermvc:favicon:enable: falseprofiles:  #多平台配置active: dev
# 设置 Mybatis 的 xml 保存路径
mybatis:mapper-locations: classpath:mapper/*Mapper.xmlconfiguration: # 配置打印 MyBatis 执行的 SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true  #自动驼峰转换
eureka:client:service-url:defaultZone: http://127.0.0.1:10010/eureka/

 

3.service层修改远程调用的代码

package order.service;import lombok.extern.slf4j.Slf4j;
import order.mapper.OrderMapper;
import order.model.OrderInfo;
import order.model.ProductInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import java.util.List;
@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;//注入这个接口@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;//注意这个有多个同名,使用.cloud.client后缀的public OrderInfo selectOrderById(Integer orderId){OrderInfo orderInfo = orderMapper.selectOrderById(orderId);//String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();//从Eureka中获取服务列表(因为可能不止一个服务,所有使用列表,然后再选择列表中的product服务)List<ServiceInstance> instances = discoveryClient.getInstances("product-service");String uri = instances.get(0).getUri().toString();String url = uri+"/product/" + orderInfo.getProductId();log.info("远程调用url:{}",url);ProductInfo productInfo = restTemplate.getForObject(url,ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}


4. 启动,测试 

5.查看远程调用是否成功

 

 

2.4Eureka 和Zookeeper区别

Eureka和Zookeeper都是用于服务注册和发现的⼯具,区别如下:
  • Eureka是Netflix开源的项目, 而Zookeeper是Apache开源的项⽬.
  • Eureka 基于AP原则, 保证⾼可用, Zookeeper基于CP原则, 保证数据⼀致性.
  • Eureka 每个节点都是均等的, Zookeeper的节点区分Leader 和Follower 或 Observer, 也正因为这个原因, 如果Zookeeper的Leader发⽣故障时, 需要重新选举, 选举过程集群会有短暂时间的不可⽤

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/75105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

极速版:栈的内存/局部变量表/堆的内存细分

1. 栈的存储 每个线程都有自己的栈&#xff0c;栈中数据以栈帧&#xff08;Stack Frame&#xff09;为基本单位 线程上正在执行的每个方法都各自对应一个栈桢&#xff08;Stack Frame&#xff09; 栈桢是一个内存区块&#xff0c;是一个数据集&#xff0c;维系着方法执行过程…

【操作系统】内存泄漏 vs 内存碎片

【操作系统】内存泄漏 vs 内存碎片 内存泄漏&#xff08;Memory Leak&#xff09; vs 内存碎片&#xff08;Memory Fragmentation&#xff09;1. 内存泄漏&#xff08;Memory Leak&#xff09;2. 内存碎片&#xff08;Memory Fragmentation&#xff09;3. 内存泄漏 vs 内存碎片…

力扣HOT100之矩阵:73. 矩阵置零

这道题我没有想到什么好的办法&#xff0c;直接暴力AC了&#xff0c;直接遍历两次矩阵&#xff0c;第一次遍历用两个向量分别记录出现0的行数和列数&#xff0c;第二次遍历就判断当前的元素的行数或者列数是否出现在之前的两个向量中&#xff0c;若出现了就直接置零&#xff0c…

​Flink/Kafka在python中的用处

一、基础概念 1. ​Apache Kafka 是什么&#xff1f; ​核心功能&#xff1a;Kafka 是一个分布式流处理平台&#xff0c;主要用于构建实时数据管道和流式应用程序。​核心概念&#xff1a; ​生产者&#xff08;Producer&#xff09;​&#xff1a;向 Kafka 发送数据的程序。…

推荐系统(十八):优势特征蒸馏(Privileged Features Distillation)在商品推荐中的应用

在商品推荐系统中&#xff0c;粗排和精排环节的知识蒸馏方法主要通过复杂模型&#xff08;Teacher&#xff09;指导简单模型&#xff08;Student&#xff09;的训练&#xff0c;以提升粗排效果及与精排的一致性。本文将以淘宝的一篇论文《Privileged Features Distillation at …

深度学习四大核心架构:神经网络(NN)、卷积神经网络(CNN)、循环神经网络(RNN)与Transformer全概述

目录 &#x1f4c2; 深度学习四大核心架构 &#x1f330; 知识点概述 &#x1f9e0; 核心区别对比表 ⚡ 生活化案例理解 &#x1f511; 选型指南 &#x1f4c2; 深度学习四大核心架构 第一篇&#xff1a; 神经网络基础&#xff08;NN&#xff09; &#x1f330; 知识点概述…

R语言对偏态换数据进行转换(对数、平方根、立方根)

我们进行研究的时候经常会遇见偏态数据&#xff0c;数据转换是统计分析和数据预处理中的一项基本技术。使用 R 时&#xff0c;了解如何正确转换数据有助于满足统计假设、标准化分布并提高分析的准确性。在 R 中实现和可视化最常见的数据转换&#xff1a;对数、平方根和立方根转…

第十四届蓝桥杯省赛电子类单片机学习记录(客观题)

01.一个8位的DAC转换器&#xff0c;供电电压为3.3V&#xff0c;参考电压2.4V&#xff0c;其ILSB产生的输出电压增量是&#xff08;D&#xff09;V。 A. 0.0129 B. 0.0047 C. 0.0064 D. 0.0094 解析&#xff1a; ILSB&#xff08;最低有效位&#xff09;的电压增量计算公式…

HarmonyOSNext_API16_媒体查询

媒体查询条件详解 媒体查询是响应式设计的核心工具&#xff0c;通过判断设备特征动态调整界面样式。其完整规则由媒体类型、逻辑操作符和媒体特征三部分组成&#xff0c;具体解析如下&#xff1a; 一、媒体查询语法结构 基本格式&#xff1a; [媒体类型] [逻辑操作符] (媒体特…

Python+拉普拉斯变换求解微分方程

引言 在数学和工程学中,微分方程广泛应用于描述动态系统的行为,如电路、电气控制系统、机械振动等。求解微分方程的一个常见方法是使用拉普拉斯变换,尤其是在涉及到初始条件时。今天,我们将通过 Python 演示如何使用拉普拉斯变换来求解微分方程,并帮助大家更好地理解这一…

【算法】手撕快速排序

快速排序的思想 任取一个元素作为枢轴&#xff0c;然后想办法把这个区间划分为两部分&#xff0c;小于等于枢轴的放左边&#xff0c;大于等于枢轴的放右边 然后递归处理左右区间&#xff0c;直到空或只剩一个 具体动画演示详见 数据结构合集 - 快速排序(算法过程, 效率分析…

《八大排序算法》

相关概念 排序&#xff1a;使一串记录&#xff0c;按照其中某个或某些关键字的大小&#xff0c;递增或递减的排列起来。稳定性&#xff1a;它描述了在排序过程中&#xff0c;相等元素的相对顺序是否保持不变。假设在待排序的序列中&#xff0c;有两个元素a和b&#xff0c;它们…

深度学习篇---paddleocr正则化提取

文章目录 前言一、代码总述&介绍1.1导入必要的库1.1.1cv21.1.2re1.1.3paddleocr 1.2初始化PaddleOCR1.3打开摄像头1.4使用 PaddleOCR 进行识别1.5定义正则表达式模式1.6打印提取结果1.7异常处理 二、正则表达式2.1简介2.2常用正则表达式模式及原理2.2.1. 快递单号模式2.2.2…

JavaScript DOM与元素操作

目录 DOM 树、DOM 对象、元素操作 一、DOM 树与 DOM 对象 二、获取 DOM 元素 1. 基础方法 2. 现代方法&#xff08;ES6&#xff09; 三、修改元素内容 四、修改元素常见属性 1. 标准属性 2. 通用方法 五、通过 style 修改样式 六、通过类名修改样式 1. className 属…

单元测试的编写

Python 单元测试示例 在 Python 中&#xff0c;通常使用 unittest 模块来编写单元测试。以下是一个简单的示例&#xff1a; 示例代码&#xff1a;calculator.py # calculator.py def add(a, b):return a bdef subtract(a, b):return a - b 单元测试代码&#xff1a;test_c…

大模型学习:从零到一实现一个BERT微调

目录 一、准备阶段 1.导入模块 2.指定使用的是GPU还是CPU 3.加载数据集 二、对数据添加词元和分词 1.根据BERT的预训练&#xff0c;我们要将一个句子的句头添加[CLS]句尾添加[SEP] 2.激活BERT词元分析器 3.填充句子为固定长度 代码解释&#xff1a; 三、数据处理 1.…

10组时尚复古美学自然冷色调肖像电影照片调色Lightroom预设 De La Mer – Nautical Lightroom Presets

De La Mer 预设系列包含 10 种真实的调色预设&#xff0c;适用于肖像、时尚和美术。为您的肖像摄影带来电影美学和个性&#xff01; De La Mer 预设非常适合专业人士和业余爱好者&#xff0c;可在桌面或移动设备上使用&#xff0c;为您的摄影项目提供轻松的工作流程。这套包括…

SDL多窗口多线程渲染技术解析

SDL多窗口多线程渲染技术解析 技术原理 SDL多线程模型与窗口管理 SDL通过SDL_Thread结构体实现跨平台线程管理。在多窗口场景中,每个窗口需关联独立的渲染器,且建议遵循以下原则: 窗口与渲染器绑定:每个窗口创建时生成专属渲染器(SDL_CreateRenderer),避免跨线程操作…

QT 跨平台发布指南

一、Windows 平台发布 1. 使用 windeployqt 工具 windeployqt --release --no-compiler-runtime your_app.exe 2. 需要包含的文件 应用程序 .exe 文件 Qt5Core.dll, Qt5Gui.dll, Qt5Widgets.dll 等 Qt 库 platforms/qwindows.dll 插件 styles/qwindowsvistastyle.dll (如果使…

L2-037 包装机 (分数25)(详解)

题目链接——L2-037 包装机 问题分析 这个题目就是模拟了物品在传送带和筐之间的传送过程。传送带用队列模拟&#xff0c;筐用栈模拟。 输入 3 4 4 GPLT PATA OMSA 3 2 3 0 1 2 0 2 2 0 -1输出 根据上述操作&#xff0c;输出的物品顺序是&#xff1a; MATA样例分析 初始…