本文主要学习的是SpringCloud 基础组件中的 注册中心-Eureka
所谓服务注册中心就是在整个的微服务架构中单独提出一个服务,这个服务不完成系统的任何的业务功能,仅仅用来完成对整个微服务系统的服务注册和服务发现,以及对服务健康状态的监控和管理功能。
服务注册
当微服务(客户端)在启动的时候会向服务端(注册中心)提交自己的服务信息(服务名,ip,端口等),在服务端会形成一个微服务的通信地址列表。 — 这叫服务注册
服务发现
通常情况下,微服务(客户端)会定时从服务端(注册中心)拉取微服务通信地址列表缓存到本地, 当一个微服务(消费者)在向另一个微服务(提供者)发起调用的时候会根据目标服务的服务名找到其通信地址,然后向目标服务发起网络请求。— 这叫服务发现
服务续约
另外,通常微服务(客户端)会采用“心跳机制”向服务端(注册中心)发请求进行服务续约,其实就是定时向注册中心发请求报告自己的健康状况,告诉注册中心自己还活着,不要把自己从服务地址清单中剔除掉,那么当微服务(客户端)宕机未向注册中心发起续约请求,或者续约请求超时,注册中心机会从服务地址清单中剔除该续约失败的服务。
服务注册与发现通常包括服务端,客户端组成,服务端也加注册中心,是一个独立的应用有自己的进程,而客户端需要集成到具体的微服务项目中。
服务注册与发现是用来实现微服务的集中管理,主要体现于服务实例的注册(通信地址,服务名等)和服务实例的发现,以及服务的续约等功能。
我们首先看一组图:
图解:
服务之间需要进行网络通信,服务器之间发起调用时调用服务需要知道被调用服务的通信地址,试问当微服务数量成百上千之多,程序员该如何管理众多的服务通信地址,难道编写代码里IP 端口写死吗,对于随时新增加的微服务和下线的微服务,或者部署一些服务到了新的机器上,又应该如何去动态添加、修改和删除这些微服务的通信地址呢?所以手工管理服务的通信地址是一件遥不可及的事情,我们需要借助一个强大的工具帮我们实现这一功能。
简言之:
服务注册中心
- 可以对所有的微服务的信息进行存储,如微服务的名称、IP、端口等
- 可以在进行服务调用时通过服务发现查询可用的微服务列表及网络地址进行服务调用
- 可以对所有的微服务进行心跳检测,如发现某实例长时间无法访问,就会从服务注册表移除该实例。
常用的注册中心
springcloud支持的多种注册中心Eureka(netflix)、Consul、Zookeeper、以及阿里巴巴推出Nacos组件
Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务。SpringCloud将它集成在其子项目spring-cloud-netflix中,用以实现SpringCloud的服务注册和发现功能。
戳我:查看官网
Eureka包含两个组件:Eureka Server和Eureka Client 即服务端 和客户端
本次项目采用的是boot2.2.5 ,但是在写blog的时候呢,boot已经升级了几个版本,为了充分还原场景 ,则在yml中更改下 springboot-parent版本即可
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
#指定服务端口号
server:
port: 8761
#指定服务名
spring:
application:
name: eureka-server
client:
service-url:
#注册中心通信地址
defaultZone: http://localhost:8761/eureka
接下来就可以启动啦
高高兴兴启动,发现启动到是成功了,但中途居然有错误日志
# 访问Eureka的服务注册页面
- http://localhost:8761
这个东西呢,就是注册表,所有其余的服务调用等等 都是通过其注册表去找到对应的具体的服务的
那么,为什么,我作为一个服务端,也像是客户端一样的形式注册到了咱们的注册表呢?
— 因为eureka -server 他其实即包含了客户端也包含了服务端,在开启注解 @EnableEurekaServer
后呢,其就像人格分裂一般,把自己既作为服务端启动,又作为客户端启动并尝试向注册中心的注册表去注册。
— 这也是 ,我们前边项目启动报错的一个原因… 大家可以想想,我注册中心服务还没启动好,你又人格分裂般的以客服身份去注册,那能找到吗?能个鬼哟!
那么,怎么解决呢?
– 关闭自我注册功能
--yml配置 修改
eureka:
client:
service-url:
#注册中心通信地址
defaultZone: http://localhost:8761/eureka
#取消自己向注册中心注册
register-with-eureka: false
#取消 从 eureka 服务端获取注册表信息
fetch-registry: false
从起项目,发现没有类似注册到eureka 的日志了,无报错信息了
注册表呢,也是干干净净的了
可能有不熟悉微服务的小伙伴是诧异! 我就这么进入了我的注册中心查看到了我的所有服务?这也太不安全了吧!
– 1.实际中,微服务群体仅仅只会向外部暴露网关地址,所有请求都由网关转发到内部微服务群中,而内部微服务群呢,则是放在局域网内 ,外部无法直接访问的。
– 2. eureka 也是可以开启登录认证的 --也比较简单 引入个依赖 yml配置配置
eureka 的服务端呢,基本就到这里了,后边还有因为问题而产生的新知识----
-- eureka 总共分为两大版块 一个 eureka-server 服务端、 eureka-client 客户端
-- 其实呢,在使用 eureka 作为注册中心的时候呢,所有向其注册表注册的服务都是其客户端,即eureka client,例如开发时,我们有 配置中心、用户服务、广告服务等等,这个服务呢,都需要向eureka server 注册,以便其他服务在调用的时候啊,能直接通过注册表找到对应服务,以及使用 feign 通过服务名 进行负载均衡调用等
创建一个springboot 项目
版本与server 一致,更改为 2.2.5
引入cloud 版本管理,与server一致 Hontox.SR6
springboot.yml配置
– 这里需要注意哈,开始我的eureka -server 写的注册中心地址为localhost:8761 我只是泛指 本机哈,本机内网IP为 192.168.124.17,各位伙伴 可直接指定注册中心地址 Ip 端口
server:
port: 8762
spring:
application:
#服务名 每个不同业务微服务名需唯一
name: zs-app
eureka:
instance:
# 指定此实例的ip
ip-address: 192.168.124.17
#显示Ip 注册
prefer-ip-address: true
# 注册时使用ip而不是主机名
instance-id: ${eureka.instance.ip-address}:${server.port}
client:
service-url:
#指定eureka注册中心地址
defaultZone: http://localhost:8761/eureka
其实呢,eureka-client 基本配置就这些,然后在其中编写自己的业务代码即可
首先,咱们先来分析上边的问题
# 可能有小伙伴要问了,你的 127.0.0.1 不之前说了就是 192.168.124.17 这两个不同一个吗?
-- 是的,确实是同一个,但是 eureka 不知道啊,因为它客户端读取yml配置信息注册到注册表中的啊
instance-id: ${eureka.instance.ip-address}:${server.port}
# 为什么有两个?
-- 因为 我开始是本机127.0.0.1 来着,为了区分以及想要突出后续我说的问题,所以又改成了真实的本机内网IP
因为 eureka 的自我保护策略,吧先前的 配置127.0.0.1 配置关闭后呢,他仍然会有段时间出现在注册表中
# 两个又咋样?两个就牛逼吗?
-- 没错 两个就是牛逼 ,而且他不仅可以两个,还可以n个,,
-- 两个有什么作用呢?
-- 抛砖引玉,简单说下: 负载均衡,都知道 微服务调用可以是从注册表去找服务,从而不用写死Ip 以及端口, 那么,两个同名的服务,有着不同ip以及端口 ,是不是就可以使用负载均衡组件到达负 载的效果了呢?
# 补充一点,每个业务一致的服务名字一定要一致,且不同业务功能服务名名字需要"唯一"
-- 用户服务 你要叫 zs-app,那么,订单就不能取这个名字,但是 我拷贝多份 zs-app 的用户服务部署不同端口 ip 是可行的
Eureka -server 管理页面 出现的红色提示信息
这是:eureka的自我保护机制
官网地址: https://github.com/Netflix/eureka/wiki/Server-Self-Preservation-Mode
- 默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时按道理不应该移除这个微服务,所以引入了自我保护机制。
- Eureka Server在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期。
- 这种设计的哲学原理就是"宁可信其有不可信其无!",愿意相信,服务是正常的。
- 自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。
开始我以配置 127.0.0.1 身份启动一个客户端,但是又关闭了,配置192.168.124.17 ,因为127 正常启动后,会到eureka-server 注册表注册,然后挂掉后,服务端没收到其心跳 就会开启保护,也就是界面的显红,当过段时间后,还是未收到心跳,才会将其从注册表剔除。
那么在开发中呢,我们根据实际情况可修改 eureka server 接受心跳间隔最大时间以及 指定客户端间隔多久向server 发送一次心跳
注意了:此配置,加载eureka -server 端
#用来修改eureka server默认接受心跳的最大时间 默认是90s
eureka.instance.lease-expiration-duration-in-seconds=10
#指定客户端多久向eureka server发送一次心跳 默认是30s
eureka.instance.lease-renewal-interval-in-seconds=5
可能,有小伙伴想问了,我在开发的时候,写错了配置,从起客户端后注册中心又不立即剔除服务,出现调用负载均衡调用到前边停止的错误配置服务情况下,大几率会出现错误啊,这个很烦啊??
这个 eureka 也想到了!
我保护策略,能开,那么自然也能关啊!
关闭eureka自我保护机制
eureka:
server:
#关闭自我保护
enable-self-preservation: false
#超时2s自动清除
eviction-interval-timer-in-ms: 2000
特别特别注意啦!
eureka的自我保护机制 ,生产时一定不要关闭,其本身目的就是为了保护微服务的健壮性与稳定性,您还把他关闭了?
生产时一定不要关闭!
生产时一定不要关闭!
生产时一定不要关闭!
# 1.官方停止更新说明
- https://github.com/Netflix/eureka/wiki
- 在1.x版本项目仍是活跃的,但是在2.x版本中已然四停止了维护,并且官网还说了,如果继续使用,出现问题后果自负!!!
那么,停止维护了就不能用了?当然不是,上方也说过了,1.x项目仍是活跃的,只是说,版本没有了更新迭代,后续如果出现问题,不好解决!
可能有小伙伴又想问了,我们不是 Hontox.SR6吗? boot不是2.2.5吗?那用的eureka 是哪个版本呢?
可以发现,无论呢,外部版本怎么更新怎么更新,但是 eureka 内部所用依赖呢,却止步于1.9.x
其实呢 eureka 近一两年公司开发新项目不是第一考虑的注册中心,eureka呢,也非不可替代,前边也说过了,nacos、zookeper 、nacos 等
人嘛,是向前看的,技术呢,也是不断迭代升级的,互联网时代,没有什么是真正意义上的不可或缺的,springcloud 微服务组件亦然。但是 eureka 作为老牌的注册中心,学习下怎么使用,大致的工作原理还是有必要的,其余注册中心组件,也是在其思想上进行优化以及扩展的嘛!
那么 eureka 的基本使用篇暂时就到这里了…
项目简单源码:spring-cloud-hoxton-sr6-eureka
后续继续更新…