spring could之——接入注册中心
近来接了点私活,看到一起干活的小伙伴,给私活的项目整了微服务的一套东西,所以今天心血来潮,就来说说:接入注册中心
目标:将自己写的服务实例接入注册中心,做统一的地址管理。
第一步:修改配置文件[pom.xml] 在properties节点下添加spring-cloud.version属性
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR4</spring-cloud.version> </properties>
第二步:修改配置文件[pom.xml] 添加dependencyManagement节点(跟dependencies同级)
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
第三步:修改配置文件[pom.xml] 添加依赖库
1 2 3 4 | <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> |
第四步:修改配置文件[src/main/resources/application.properties],添加注册中心相关配置
spring: application: #应用名称,服务名称 name: sys-zipkin eureka: client: healthcheck: enabled: true #注册中心的地址 serviceUrl: defaultZone: http://DiscoveryUser:youli@127.0.0.1:8045/eureka/,http://DiscoveryUser:youli5458@127.0.0.1:8761/eureka/ #eureka client刷新本地缓存时间 #默认30s registry-fetch-interval-seconds: 5 instance: #服务过期时间配置,超过这个时间没有接收到心跳EurekaServer就会将这个实例剔除 #注意,EurekaServer一定要设置eureka.server.eviction-interval-timer-in-ms否则这个配置无效,这个配置一般为服务刷新时间配置的三倍 #默认90s lease-expiration-duration-in-seconds: 15 #服务刷新时间配置,每隔这个时间会主动心跳一次 #默认30s lease-renewal-interval-in-seconds: 5 prefer-ip-address: true ribbon: #eureka客户端ribbon刷新时间 #默认30s ServerListRefreshInterval: 5000
第五步:修改DemoApplication启动类文件,加入@EnableEurekaClient注解
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
第六步:做完以上步骤后,接口访问地址就变成了http://<网关ip>:<网关端口>/注册应用名称/原接口地址
关于Eureka的一些问题解答
一. 为什么利用Eureka注册一个instance需要很长的时间
基本参照spring-cloud-netflix#373
1.1 Eureka client注册
首次心跳在Eureka client启动后的30s(通过eureka.instance.leaseRenewalIntervalInSeconds配置),所以在这个期间中,instance不会出现在Eureka注册中心中。
eureka: instance: #服务过期时间配置,超过这个时间没有接收到心跳EurekaServer就会将这个实例剔除 #注意,EurekaServer一定要设置eureka.server.eviction-interval-timer-in-ms否则这个配置无效,这个配置一般为服务刷新时间配置的三倍 #默认90s lease-expiration-duration-in-seconds: 15 #服务刷新时间配置,每隔这个时间会主动心跳一次 #默认30s lease-renewal-interval-in-seconds: 5
1.2 Eureka server响应缓存
Eureka server响应缓存每隔30s更新一次(即其他Eureka client从Eureka serve 请求的注册信息每隔30s才会更新,通过eureka.server.responseCacheUpdateIntervalMs配置),所以即便instance注册过了,也不会立即出现在调用 /eureka/apps的返回结果中(因为Eureka面板 http://eurekaserver:8761 对应的页面绕过了响应缓存,所以刚注册过的instance会出现在Eureka面板中),另一个API/eureka/apps//也绕过了响应缓存,所以如果你知道instanceId,你也可以通过此URI来获取instance的具体信息。所以,为了使Eureka client能发现新注册instance,还需要等额外的30s
eureka: server: #启用主动失效,并且每次主动失效检测间隔为3s eviction-interval-timer-in-ms: 3000 #eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap, #这个时间决定了多久会把readWriteCacheMap的缓存更新到readCacheMap上 #默认30s response-cache-update-interval-ms: 3000
1.3 Eureka client缓存
Eureka client本地也缓存着从Eureka server获取的注册信息。这个缓存也是每隔30s刷新一次(通过eureka.client.registryFetchIntervalSeconds配置),这个在前面已经介绍过。所以这个地方又有可能需要30s来使Eureka client刷新本地缓存并把新注册的instance获取下来
eureka:
client:
#eureka client刷新本地缓存时间
#默认30s
registry-fetch-interval-seconds: 5
1.4 负载均衡器缓存
Ribbon是从本地的Eureka client中获取信息来执行负载均衡,ribbon自己也维护了一个缓存来避免每次请求都要调用Eureka client。ribbon缓存默认也是30s刷新一次(通过ribbon.ServerListRefreshInterval配置),所以在ribbon能利用新注册的instance之前可能还需要30s。
ribbon:
#eureka客户端ribbon刷新时间
#默认30s
ServerListRefreshInterval: 5000
二. Eureka Instance 和Eureka client主要配置
2.1.
在Eureka中,一个instance通过一个eureka.instance.instanceId 来唯一标识,如果这个值没有设置,就采用eureka.instance.metadataMap.instanceId来代替。instance之间通过eureka.instance.appName 来彼此访问,在spring cloud中默认值是spring.application.name,如果没有设置则为UNKNOWN。在实际使用中spring.application.name不可或缺,因为相同名字的应用会被Eureka合并成一个群集。eureka.instance.instanceId也可以不设置,直接使用缺省值(client.hostname:application.name:port) ,同一个appName下InstanceId不能相同。属性eureka.instance.virtualHostName目前在spring cloud中目前没有用,默认值是appName或者UNKNOWN。
2.2.
如果 eureka.client.registerWithEureka设置成true(默认值true),应用启动时,会利用指定的eureka.client.serviceUrl.defaultZone注册到对应的Eureka server中。之后每隔30s(通过eureka.instance.leaseRenewalIntervalInSeconds来配置)向Eureka server发送一次心跳,如果Eureka server在90s(通过eureka.instance.leaseExpirationDurationInSeconds配置)内没有收到某个instance发来的心跳就会把这个instance从注册中心中移走。发送心跳的操作是一个异步任务,如果发送失败,则以2的指数形式延长重试的时间,直到达到eureka.instance.leaseRenewalIntervalInSeconds * eureka.client.heartbeatExecutorExponentialBackOffBound这个上限,之后一直以这个上限值作为重试间隔,直至重新连接到Eureka server,并且重新尝试连接到Eureka server的次数是不受限制的。
2.3.
在Eureka server中每一个instance都由一个包含大量这个instance信息的com.netflix.appinfo.InstanceInfo标识,client向Eureka server发送心跳和更新注册信息是不相同的,InstanceInfo也以固定的频率发送到Eureka server,这些信息在Eureka client启动后的40s(通过eureka.client.initialInstanceInfoReplicationIntervalSeconds配置)首次发送,之后每隔30s(通过eureka.client.instanceInfoReplicationIntervalSeconds配置)发送一次。
2.4.
如果eureka.client.fetchRegistry设置成true(默认值true),Eureka client在启动时会从Eureka server获取注册信息并缓存到本地,之后只会增量获取信息(可以把eureka.client.shouldDisableDelta设置成false来强制每次都全量获取)。获取注册信息的操作也是一个异步任务,每隔30秒执行一次(通过eureka.client.registryFetchIntervalSeconds配置),如果操作失败,也是以2的指数形式延长重试时间,直到达到eureka.client.registryFetchIntervalSeconds * eureka.client.cacheRefreshExecutorExponentialBackOffBound 这个上限,之后一直以这个上限值作为重试间隔,直至重新获取到注册信息,并且重新尝试获取注册信息的次数是不受限制的。
这些任务都是在com.netflix.discovery.DiscoveryClient中启动,spring cloud用org.springframework.cloud.netflix.eureka.CloudEurekaClient对这个类进行了扩展。
三. 为什么服务注册上去之后出现主机名是"localhost"
这个并不影响别人调用你的服务,因为注册中心登记的不仅仅是服务提供着的主机名,更重要的是IP地址和端口号。但是为了显示更直观,建议增加以下配置(有时候会比较二,不生效)
eureka: instance: #尽量使用IP地址作为主机名,内网环境更直观 prefer-ip-address: true
分类:
springboot
, spring could
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库