服务注册与服务发现
服务注册与服务发现
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客户端:使用了EnableEurekaClient注解的应用服务,如订单服务等,甚至Eureka本身也是一个客户端 Eureka服务端:使用了EnableEurekaServer注解的应用服务,该服务提供了注册表以及…...

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刊(2023年9月第六刊)。 提示: 1.用于无名版; 2.用于1代; 3.pvz指植物大战僵尸(Plants VS Zonbies)。 植物大战僵尸植物表 土豆雷窝瓜火炬树桩火爆辣椒杨…...

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

C# void 关键字学习
C#中void关键字是System.Void的别名; 可以将 void 用作方法(或本地函数)的返回类型来指定该方法不返回值; 如果C#方法中没有参数,则不能将void用作参数;这是与C语言不同的,C语言有…...
OA与CRM与ORACLE
办公自动化(Office Automation,简称OA),是将计算机、通信等现代化技术运用到传统办公方式,进而形成的一种新型办公方式。办公自动化利用现代化设备和信息化技术,代替办公人员传统的部分手动或重复性业务活动…...

【C++杂货铺】探索list的底层实现
文章目录 一、list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity(容量相关)1.2.4 list element access(元素访问)1.2.5 list modifiers(链表修改࿰…...
NX/UG二次开发—Parasolid—PK_BODY_pick_topols
最近在写一个判断圆孔深度和通盲状态的功能,发现PK_BODY_pick_topols射线函数可以设置到射线垂直距离,相当于一个圆柱空间,但在测试发现,R7的孔,设置: max_edge_dist 0.007; max_vertices 0.007; 结果测…...

【校招VIP】前端算法考点之大数据相关
考点介绍: 大数据的关键技术分为分析技术和处理技术,可用于大数据分析的关键技术主要包括A/B测试,关联规则挖掘,数据挖掘,集成学习,遗传算法,机器学习,自然语言处理,模式…...

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

【AIGC专题】Stable Diffusion 从入门到企业级应用0414
一、前言 本文是《Stable Diffusion 从入门到企业级应用实战》系列的第四部分能力进阶篇《Stable Diffusion ControlNet v1.1 图像精准控制》的第0414篇 利用Stable Diffusion ControlNet 法线贴图模型精准控制图像生成。本部分内容,位于整个Stable Diffusion生态体…...
汇编原理学习记录:物理地址=段地址*16+偏移地址
文章目录 知识点个人思考解释存储器大小为1MB段的最大占用存储为64KB物理地址段地址*16偏移地址 知识点 8086计算机拥有20根地址总线和16根数据总线,地址总线中的16根和数据总线存在复用 数据总线的数量决定了数据总线的宽度,决定了处理器的位数&#…...
mysql-2:安装mysql
MySQL安装 操作系统:CentOS 7MySQL: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)gin.GET/POST/PUT/DELETE函数 Go Gin 简明教程 | 快速入门 | 极客兔兔 (geektutu.com) 我的理解是:这类函数就像是在监听接口一样&…...
Laravel 完整开源项目大全
原型项目 Laravel 5 Boilerplate —— 基于当前Laravel最新版本(Laravel 6.0)并集成Boilerplate的项目Laravel 5 Angular Material Starter —— 这是一个 Laravel 和 AngularJS 的原型项目(最高支持版本:5.3,长期未更…...
Spring MVC @Controller和@RequestMapping注解
Controller 注解 Controller 注解可以将一个普通的 Java 类标识成控制器(Controller)类,示例代码如下。 package net.biancheng.controller; import org.springframework.stereotype.Controller; Controller public class IndexController …...

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

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

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

从零开始学习deepsort目标追踪算法----原理和代码详解
目录 1.目标追踪的主要步骤 2、传统sort算法的流程 3.Deepsort算法流程 4、目标追踪整体代码 4.1 Configs文件目录下: 4.2 deep_sort/deep_sort/deep目录下: 4.3 deep_sort/deep_sort/sort目录下: 运行demo: DeepSORT&…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
第22节 Node.js JXcore 打包
Node.js是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境。 JXcore是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。 本文主要介绍JXcore的打包功能。 JXcore 安装 下载JXcore安装包&a…...