当前位置: 首页 > news >正文

服务注册与服务发现

服务注册与服务发现

Eureka的架构

Eureka客户端:使用了@EnableEurekaClient注解的应用服务,如订单服务等,甚至Eureka本身也是一个客户端
Eureka服务端:使用了@EnableEurekaServer注解的应用服务,该服务提供了注册表以及对服务节点的操作
服务提供者:服务启动后,可以向注册中心发起register请求,将服务信息注册进去
服务消费者:服务启动后,可以从注册中心拉取服务信息,并根据所得的服务信息调用服务
他们之间的关系为:
Eureka-server你可以当作他是一个单独的服务,而跟它对接的都是Eureka-client,而Eureka-client中则包含了服务消费者和服务提供者等角色。例如订单服务中包含一个消费者A,商品服务中包含一个提供者B,现在消费者A想查询该订单对应的商品信息,那就是查询提供者B的服务,那么首先A和B都必须先把自己作为一个eureka客户端,然后B将自己的服务信息发送到eureka的服务端中,A再从eureka服务端中拉取B的服务信息(地址),然后发起请求。

服务端

所需依赖

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

启动服务时需要添加两个注解

@EnableEurekaServer
@SpringBootApplication

客户端

所需依赖

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

启动服务需要配置

@EnableEurekaClient
@SpringBootApplication

关系

1、服务提供者、服务消费者、服务发现组件三者之间的关系大致如下:
1)各个微服务在启动时时,将自己的网络地址等信息注册到服务发现组件上(eureka,zookeeper,Consul,spring cloud alibaba的nacos),服务发现组件会存储这些信息。
2)服务消费者会从服务发现组件查询服务提供者的网络地址,然后将服务地址列表缓存到本地,然后根据服务名负载均衡调用服务提供者的接口。
3)各个微服务与服务发现组件使用一定的机制来维持心跳,服务发现组件若发现有服务没有提供心跳,那么服务发现组件会将该服务剔除。
4)微服务网络地址发生变更(例如实例增减或者IP端口发生变化等),会重新注册到服务发现组件上,使用这种方式,可以避免因网络变化导致服务之间的通讯停止,服务消费者也无须人工的修改网络地址。

Eureka简介

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
1.Eureka包含两个组件:Eureka Server和Eureka Client。
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询负载算法的负载均衡器。
2.在应用启动后,Eureka Client会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
3.Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

三、Eureka一些特性及配置过程时需要注意的问题
1.Eureka能够保证AP,即当Eureka中的某个节点挂掉后,剩余的节点继续仍然可以提供服务的发现与注册服务。而Eureka的客户端在向某个Eureka或者发现了当前的Eureka不可用时,会自动切换到其他的节点,也就是说Eureka的节点是平等的,只要有一台Eureka服务器在,就能保证服务的可以继续被使用。
2.Eureka的自我保护机制,我们在注册服务时,如发生断网的情况,Eureka不能接收到当前服务的任何心跳请求,Eureka会在默认的90s后,将该服务进行强制剔除,这样就能保证到网络故障时,虽然失去了部分节点,但不会像zookeeper那样会使整个注册服务瘫痪。当网络稳定时,新的实例会同步到其他节点中。
3.相关配置问题
服务端的配置如下,不注册自身

security:basic:enabled: trueuser:name: userpassword: password123
eureka:client:register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http://user:password123@localhost:8761/eureka

引入依赖

<!-- eureka-server-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.2.3.RELEASE</version>
</dependency><!--eureka-client-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.2.3.RELEASE</version>
</dependency>

Eureka客户端应用服务注册流程

1、应用集成eureka客户端依赖,配置eureka相关信息;
2、当应用启动完成后,应用会自动向eureka-server服务发请求,将自身的示例信息注册到eureka-server;
3、会启动心跳进程和服务状态检测时间;心跳每隔30s一次;应用服务状态发生变更,也会想eureka-server服务进行服务重新注册;
4、当应用服务进行关闭时,会调用shutdown方法,进行服务下线的操作;当服务因断电/网络问题/意外停机,无法正确的下线服务时,这时心跳就会起到相对应的作用,如果eureka-server服务发现应用超过三次(90s)没有心跳,那么就会将服务进行保护/下线;

源码分析

源码分析:
应用在服务启动时自动注册的实现:配置类:EurekaClientAutoConfiguration里面向IOC容器内注册了EurekaAutoServiceRegistration.class对象

@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry registry,EurekaRegistration registration) {return new EurekaAutoServiceRegistration(context, registry, registration);
}

EurekaAutoServiceRegistration.class实现了SmartLifecycle.class
SmartLifecycle.class这个类是在应用启动后,自动调用start()

@Override
public void start() {// 端口配置if (this.port.get() != 0) {if (this.registration.getNonSecurePort() == 0) {this.registration.setNonSecurePort(this.port.get());}if (this.registration.getSecurePort() == 0 && this.registration.isSecure()) {this.registration.setSecurePort(this.port.get());}}// only initialize if nonSecurePort is greater than 0 and it isn't already running// because of containerPortInitializer belowif (!this.running.get() && this.registration.getNonSecurePort() > 0) {// 进行主动注册this.serviceRegistry.register(this.registration);// 发布注册事件this.context.publishEvent(new InstanceRegisteredEvent<>(this, this.registration.getInstanceConfig()));this.running.set(true);}}

EurekaServiceRegistry#register() 注册代码如下:

@Override
public void register(EurekaRegistration reg) {maybeInitializeClient(reg);if (log.isInfoEnabled()) {log.info("Registering application " + reg.getApplicationInfoManager().getInfo().getAppName()+ " with eureka with status "+ reg.getInstanceConfig().getInitialStatus());}reg.getApplicationInfoManager().setInstanceStatus(reg.getInstanceConfig().getInitialStatus());// 进行注册健康检查reg.getHealthCheckHandler().ifAvailable(healthCheckHandler ->reg.getEurekaClient().registerHealthCheck(healthCheckHandler));
}

进行安全健康检查同时注册信息 DiscoveryClient#registerHealthCheck()

@Overridepublic void registerHealthCheck(HealthCheckHandler healthCheckHandler) {if (instanceInfo == null) {logger.error("Cannot register a healthcheck handler when instance info is null!");}if (healthCheckHandler != null) {this.healthCheckHandlerRef.set(healthCheckHandler);// schedule an onDemand update of the instanceInfo when a new healthcheck handler is registeredif (instanceInfoReplicator != null) {// 进行注册instanceInfoReplicator.onDemandUpdate();}}}

在上述的onDemandUpdate()方法中有个register方法,代码如下
DiscoveryClient#register()

boolean register() throws Throwable {logger.info(PREFIX + "{}: registering service...", appPathIdentifier);EurekaHttpResponse<Void> httpResponse;try {            // 发请求给配置url进行注册 httpResponse = eurekaTransport.registrationClient.register(instanceInfo);} catch (Exception e) {logger.warn(PREFIX + "{} - registration failed {}", appPathIdentifier, e.getMessage(), e);throw e;}if (logger.isInfoEnabled()) {logger.info(PREFIX + "{} - registration status: {}", appPathIdentifier, httpResponse.getStatusCode());}// 返回204码代表注册成功return httpResponse.getStatusCode() == 204;}

AbstractJerseyEurekaHttpClient#register()

@Override
public EurekaHttpResponse<Void> register(InstanceInfo info) {String urlPath = "apps/" + info.getAppName();ClientResponse response = null;try {Builder resourceBuilder = jerseyClient.resource(serviceUrl).path(urlPath).getRequestBuilder();addExtraHeaders(resourceBuilder);response = resourceBuilder.header("Accept-Encoding", "gzip").type(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, info);return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build();} finally {if (logger.isDebugEnabled()) {logger.debug("Jersey HTTP POST {}/{} with instance {}; statusCode={}", serviceUrl, urlPath, info.getId(), response == null ? "N/A" : response.getStatus());}if (response != null) {response.close();}}
}

相关文章:

服务注册与服务发现

服务注册与服务发现 Eureka的架构 Eureka客户端&#xff1a;使用了EnableEurekaClient注解的应用服务&#xff0c;如订单服务等&#xff0c;甚至Eureka本身也是一个客户端 Eureka服务端&#xff1a;使用了EnableEurekaServer注解的应用服务&#xff0c;该服务提供了注册表以及…...

RabbitMQ从入门到精通之安装、通讯方式详解

文章目录 RabbitMQ一、RabbitMQ介绍1.1 现存问题 一、RabbitMQ介绍二、RabbitMQ安装三、RabbitMQ架构四、RabbitMQ通信方式4.1 RabbitMQ提供的通讯方式4.2 Helloworld 方式4.2Work queues4.3 Publish/Subscribe4.4 Routing4.5 Topics4.6 RPC (了解) 五、Springboot 操作RabbitM…...

植物大战僵尸植物表(二)

前言 此文章为“植物大战僵尸”专栏中的第007刊&#xff08;2023年9月第六刊&#xff09;。 提示&#xff1a; 1.用于无名版&#xff1b; 2.用于1代&#xff1b; 3.pvz指植物大战僵尸&#xff08;Plants VS Zonbies)。 植物大战僵尸植物表 土豆雷窝瓜火炬树桩火爆辣椒杨…...

UML基础

统一建模语言&#xff08;UML是 Unified Modeling Language的缩写, 是用来对软件系统进行可视化建模的一种语言。UML为面向对象开发系统的产品 进行说明、可视化、和编制文档的一种标准语言。 共有9种图 UML中的图其实不止九种 (相同的图还可能会有不同的名称), 这里的九种图是…...

C# void 关键字学习

C#中void关键字是System.Void的别名&#xff1b; 可以将 void 用作方法&#xff08;或本地函数&#xff09;的返回类型来指定该方法不返回值&#xff1b; 如果C&#xff03;方法中没有参数&#xff0c;则不能将void用作参数&#xff1b;这是与C语言不同的&#xff0c;C语言有…...

OA与CRM与ORACLE

办公自动化&#xff08;Office Automation&#xff0c;简称OA&#xff09;&#xff0c;是将计算机、通信等现代化技术运用到传统办公方式&#xff0c;进而形成的一种新型办公方式。办公自动化利用现代化设备和信息化技术&#xff0c;代替办公人员传统的部分手动或重复性业务活动…...

【C++杂货铺】探索list的底层实现

文章目录 一、list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity&#xff08;容量相关&#xff09;1.2.4 list element access&#xff08;元素访问&#xff09;1.2.5 list modifiers&#xff08;链表修改&#xff0…...

NX/UG二次开发—Parasolid—PK_BODY_pick_topols

最近在写一个判断圆孔深度和通盲状态的功能&#xff0c;发现PK_BODY_pick_topols射线函数可以设置到射线垂直距离&#xff0c;相当于一个圆柱空间&#xff0c;但在测试发现&#xff0c;R7的孔&#xff0c;设置&#xff1a; max_edge_dist 0.007; max_vertices 0.007; 结果测…...

【校招VIP】前端算法考点之大数据相关

考点介绍&#xff1a; 大数据的关键技术分为分析技术和处理技术&#xff0c;可用于大数据分析的关键技术主要包括A/B测试&#xff0c;关联规则挖掘&#xff0c;数据挖掘&#xff0c;集成学习&#xff0c;遗传算法&#xff0c;机器学习&#xff0c;自然语言处理&#xff0c;模式…...

Goland2023版新UI的debug模式调试框按钮功能说明

一、背景 Jetbrains家的IDE的UI基本都是一样的&#xff0c;debug模式的调试框按钮排列也是一致的&#xff0c;但是在我使用Goland2023版的新UI时&#xff0c;发现调试框的按钮变化还是很大的&#xff0c;有一些按钮被收起来了&#xff0c;如果看之前的博客会发现有一些文中的旧…...

【AIGC专题】Stable Diffusion 从入门到企业级应用0414

一、前言 本文是《Stable Diffusion 从入门到企业级应用实战》系列的第四部分能力进阶篇《Stable Diffusion ControlNet v1.1 图像精准控制》的第0414篇 利用Stable Diffusion ControlNet 法线贴图模型精准控制图像生成。本部分内容&#xff0c;位于整个Stable Diffusion生态体…...

汇编原理学习记录:物理地址=段地址*16+偏移地址

文章目录 知识点个人思考解释存储器大小为1MB段的最大占用存储为64KB物理地址段地址*16偏移地址 知识点 8086计算机拥有20根地址总线和16根数据总线&#xff0c;地址总线中的16根和数据总线存在复用 数据总线的数量决定了数据总线的宽度&#xff0c;决定了处理器的位数&#…...

mysql-2:安装mysql

MySQL安装 操作系统&#xff1a;CentOS 7MySQL&#xff1a;5.6 MySQL的卸载 查看MySQL软件 rpm -qa | grep mysqlyum repolist all | grep mysql 卸载MySQL 卸载mysql yum remove -y mysql mysql-libs mysql-common删除mysql下的数据文件 rm -rf /var/lib/mysql删除mys…...

gin框架

【狂神说】Gin框架一小时上手 | 快速转型GoWeb开发 | Go语言零基础教程_哔哩哔哩_bilibili 1.介绍 2.简单程序 1&#xff09;gin.GET/POST/PUT/DELETE函数 Go Gin 简明教程 | 快速入门 | 极客兔兔 (geektutu.com) 我的理解是&#xff1a;这类函数就像是在监听接口一样&…...

Laravel 完整开源项目大全

原型项目 Laravel 5 Boilerplate —— 基于当前Laravel最新版本&#xff08;Laravel 6.0&#xff09;并集成Boilerplate的项目Laravel 5 Angular Material Starter —— 这是一个 Laravel 和 AngularJS 的原型项目&#xff08;最高支持版本&#xff1a;5.3&#xff0c;长期未更…...

Spring MVC @Controller和@RequestMapping注解

Controller 注解 Controller 注解可以将一个普通的 Java 类标识成控制器&#xff08;Controller&#xff09;类&#xff0c;示例代码如下。 package net.biancheng.controller; import org.springframework.stereotype.Controller; Controller public class IndexController …...

软件架构之前后端分离架构服务器端高并发演进之路

软件架构之前后端分离架构&服务器端高并发演进之路 前后端分离架构从业务角度从质量属性从性能角度 服务器端关于不同并发量的演进之路1. 单体架构2. 第一次演进&#xff1a;应用服务器和数据库服务器分开部署3. 第二次演进&#xff1a;引入本地缓存和分部署缓存4. 第三次演…...

第4节-PhotoShop基础课程-Ps格式

文章目录 前言1.像素认识2. 图层认识1.图层有上下前后遮挡关系2.橡皮檫可以擦掉选择图层的像素3.新建图层4.新建删除图层 3. 分辨率的理解4. 图片格式A 前言 本章主要介绍PS常用格式 1.像素认识 下面每个格子就是像素 2. 图层认识 1.图层有上下前后遮挡关系 2.橡皮檫可以擦…...

C语言malloc函数学习

malloc的全称是memory allocation&#xff0c;中文叫动态内存分配&#xff0c;用于申请一块连续的指定大小的内存块区域&#xff0c;以void*类型返回分配的内存区域地址&#xff1b; 函数原型为void *malloc(unsigned int size)&#xff0c;在内存的动态存储区中分配一个长度为…...

从零开始学习deepsort目标追踪算法----原理和代码详解

目录 1.目标追踪的主要步骤 2、传统sort算法的流程 3.Deepsort算法流程 4、目标追踪整体代码 4.1 Configs文件目录下&#xff1a; 4.2 deep_sort/deep_sort/deep目录下&#xff1a; 4.3 deep_sort/deep_sort/sort目录下&#xff1a; 运行demo&#xff1a; DeepSORT&…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...