Spring-cloud微服务实战【三】:eureka注册中心(中)

  回忆一下,在上一篇文章中,咱们建立了两个springboot项目,而且在consumer项目中经过restTemplate进行HTTP通讯,成功访问到了producer提供的接口,思考一下这样的实现方式有什么问题?
  1.consumer必须知道producer的IP,才能调用对方的HTTP接口,而且在consumer代码中使用硬编码的方式来访问producer的HTTP接口,代码耦合度高,实现方式不优雅.也许有童鞋会说,咱们能够在application.properties配置文件进行配置,那么请看第二个问题.
  2.通常来讲,生产环境的producer是一个集群,有多个IP,那我consumer该怎么写请求地址?而且假如producer集群的IP变了,consumer应用须要修改配置,从新打包上线.这对于一个高并发访问的生产项目来讲是不可接受的.所以,consumer应用须要一种机制,能够在访问producer的时候不须要关心producer的IP,而且该机制还应该提供相似于观察者模式的通知机制,在producer的IP进行变动的时候,及时通consumer,而且还能提供相似Nginx的负载均衡的功能,这就是eureka注册中心的做用.git

什么是eureka注册中心?

  eureka是netflix公司开发的一款用于服务发现的框架,spring-cloud将其集成到spring-cloud-netflix子项目中,包括咱们后续会使用的负载均衡ribbon,服务熔断与降级Hystrix等等都是netflix公司开发的.能够看出,springcloud其实整合了许多优秀公司的框架.
  咱们经过一张图来讲明一下eureka工做机制:
filegithub

  假如咱们如今有许多的微服务做为服务提供方,每一个微服务是一个集群,他们将本身的集群节点的IP与端口号注册到eureka中心,当有消费者须要消费服务的时候,便可从注册中心拉取全部的服务提供方列表,选择须要消费的服务,此时,eureka会根据负载算法将消费者须要的服务的IP与端口号返回给消费者,此时,消费者就能够根据IP和端口号去消费对应的服务了.此外,eureka还必须接收注册服务的心跳,确保注册的服务可用.而且从图中咱们能够得知:
file算法

代码实战

  接下来,咱们改造上一篇文章中已有的代码,使用eureka进行服务治理,producer注册自身到eureka,consumer从eureka获取producer的信息并调用.
  首先,咱们要新建一个子模块,用于充当eureka-server的角色:
file
file
file
filespring

  将本模块加入父项目中:
file缓存

  而后新增pom.xml中的配置:
filespringboot

  修改配置文件:
file服务器

  而后在启动类加上@EnableEurekaServer:
file网络

  而后启动试一试,此时控制台会有错误信息:
file并发

  咱们暂时先无论这些错误信息,先访问一下,看看是否能访问:
fileapp

  能够看到,eureka是能正常访问的,接下来,咱们修改producer的代码,将producer注册到eureka-server中.
首先修改pom.xml:
file

  而后修改配置文件:
file

  最后在启动类加上@EnableEurekaClient:
file

  此时,咱们再启动producer项目,而后访问eureka-server,看看是否producer已经注册成功:
file

  此时咱们再访问该页面,咱们须要关注的主要是笔者使用红框标识的3条信息,其中第一条咱们暂时先无论(第一次访问页面不会出现,但过一下子刷新就能够看到),待会儿咱们再倒回来讲,第二条,表示咱们的producer应用已经注册到eureka-server,但应用名未设置,因此目 前显示的是UNKNOWN,所以须要咱们设置应用名.第三条状态为UP(1),表示该服务正常启动,且地址是: DongHP:7001,点击访问试一试:
file

  能够看到,访问的域名是donghp(个人电脑名是DongHP):7001,后面跟的是actuator/info,而且页面报错,报错信息提示咱们没有该页面(404),所以咱们须要添加spring-actuator,该模块是spring进行健康检查的模块,咱们先分别解决第二和第三个问题:先修改配置文件,新增应用名:dhp-micro-service-producer
file

  接下来为了让咱们看到真实的IP地址,而不是 donghp:7001 ,咱们再加上显示真实IP的配置:
file

  最后,再添加spring-actuator健康检查的依赖:
file

  再重启producer,并刷新eureka-server页面:
file

  能够看到,修改后的producer已经成功注册到eureka-server中了,可是咱们会发现,以前注册的服务还在,并无消失,这是什么缘由呢?是缓存吗?并非,咱们能够试一试,过一下子再刷新,仍然仍是有,这并非缓存,还记得咱们以前所说的第一条:
file

提示信息吗?这是eureka提示咱们触发了eureka的自我保护机制.

  所谓eureka自我保护机制,就是当服务未按时进行心跳续约时(以前咱们在介绍eureka的时候说了,服务若是注册到eureka后,会定时向eureka发送心跳),Eureka会统计服务实例最近15分钟心跳续约的比例是否低于了85%(eureka.server.renewal-percent-threshold默认状况下=0.85)。当server在15分钟内,比值低于percent,即少了15%的微服务心跳,server会进入自我保护状态,Self-Preservation。在此状态下,server不会删除任何注册信息,这就有可能致使在调用微服务时,实际上服务并不存在。由此咱们能够分析出eureka自我保护机制的缺点:有可能保留确实已经不可用的微服务,可是相比之下,它的优势是能最大化保存全部的微服务,由于在生产环境下,网络问题致使的心跳丢失太常见了,咱们不能简单以是否收到心跳来判断一个微服务是否不可用,所以建议生产环境开启自我保护机制,开发时的测试环境能够关闭.

  所以上图中出现的问题就可以解释了,首先咱们已经关闭了以前的UNKNOWN的微服务,从新修改配置启动了新的DHP-MICRO-SERVICE-PRODUCER,此时eureka服务器并无重启,UNKNOWN的微服务再也不向eureka发送心跳(默认30秒发送一次心跳),所以eureka的心跳比例只有50%,低于85%,页面弹出eureka触发自我保护机制的提示,而且eureka进入自我保护状态,不会删除任何微服务.所以无论咱们如何刷新页面,UNKNOWN的微服务始终都在,若是须要禁用eureka的自我保护状态,可使用配置:eureka.server.enable-self-preservation=false(默认是开启的).
file

  此时先启动eureka-server,再还原producer的配置启动,再修改producer的配置启动:
file

  上图中①提示咱们目前关闭了自我保护模式,②说明目前有两个已注册的微服务,可是UNKNOWN已经下线了,所以咱们过一分钟刷新:
file

  此时就只有一个了,咱们再访问一下:
file

  得出两个信息: 1.咱们的ip是192.168.1.105,去验证一下:
file

2.咱们没有配置健康检查的信息,所以咱们在producer中配置相关信息:
file

file

  到此,咱们的eureka-server已经成功启动,而且producer也注册到eureka了,一切看似很完美了,但你们是否记得以前咱们说eureka-server启动的时候会报错的问题呢?
file

  这是由于eureka-server配置还不完整,咱们还须要添加配置:
file

  而后再启动eureka-server和producer:
file

  能够看到,producer服务已经成功注册到eureka中了,而且eureka-server也没有报错信息了.

  此时咱们再经过consumer项目验证一下.修改consumer项目代码:
  首先consumer也须要添加eureka-client的依赖:
file

  其次配置eureka相关信息:
file

  而后在启动类加上注解:
file

  最后修改代码:
file

  能够发现,这里之前是直接使用ip:port,如今经过eureka发现服务,就对应于咱们以前所说的再也不关心对方服务的ip和端口,而且对方服务地址变化也不会再对咱们的代码形成任何影响了,代码的优雅性和可维护性大大提高!

  因为这种方式走eureka服务发现,所以还须要加上@LoadBalanced注解:
file

  最后测试一下:
file

  访问成功!自此,咱们成功使用了eureka注册中心来解决文章一开始抛出的两个问题,那是否是这样就完美了?是否还有值得继续优化的地方?敬请期待下一篇文章.

  本文的github地址

本文由博客一文多发平台 OpenWrite 发布!

相关文章
相关标签/搜索