不一样的服务发现Eureka

  在《有了云服务器能干什么》一文中曾讲到从小小云有限的资源中扒拉了一小块来折腾微服务,在连肝数日之后,终于有了基本的微服务雏形(有SSO、有权限控制、有跨服务器资源访问)。

demo

  接下来会用一个系列来记录微服务折腾的过程。本文主要记录服务发现Eureka的折腾之路。

不一样的Eureka

  关于Eureka 的用法网上早已有海量的文章可查阅,所以这里不再赘叙。但是作为资源有限的小云使用,本就不可能运行太多的服务(硬件天花板限制),所以需要调整Eureka Server的配置方案,使其更符合个人小云使用。

we_are_different

更改配置让刷新更快

  我们都知道Eureka默认开启了自保护模式,这个模式很好很强大,就像王者荣耀一样,确实很好玩,可要是没日没夜撸太多,就变成亡者农药了,所以适度适合才是最重要的。

适度游戏

关闭自我保护模式

  作为一个单纯的私人小云,个人觉得没有必要使用Eureka自我保护模式。为什么这么说呢?从其所适合的场景就可以看出。

当Eureka Server节点在短时间内丢失客户端心跳超过门限后,会进入自我保护模式。在该模式下Eureka Server会保持当前客户端的注册信息,即便在未收到客户端续订心跳的时候也不会移出该客户端,以防止因网络故障而非客户端故障引起的误删除事件发生。

  将上述内容通过简单的例子转换一下,某天小R发现通过微信联系不上女神的时候,那么大概率是对方将小R移出了好友或已读不回(收不到续订心跳),如果此时小R够理智的话接下来要做的事应该是默默的从微信中删除女神的账号(删除无效客户端),并通过朋友圈向所有好友宣布已与女神再无关系(刷新缓存,更新客户端列表),然后等待新的女神向小R发送好友申请(新的客户端注册)。但要是某天小R发现大部分人都不能通过微信联系的时候(失联的客户端超过门限),就得考虑是不是自己的微信出问题了(网络问题或其他非客户端问题),而不是把联系不上的好友都删除(自我保护,等待故障恢复)。

  而我们小小云上运行的微服务数量基数小,一两个微服务出现异常就很容易超过Eureka自我保护的门限值,而此时更合理的处理方式是快速移出无效客户端信息,防止将流量引向已故障的服务上(快速反馈502错误,减轻网关压力),没必要进入自我保护模式等待故障恢复。

  关闭自保护模式:eureka.server.enable-self-preservation=false

快速更新

  快速更新是指Eureka Server所维持的客户端信息快速更新,即当有客户端下线时,Eureka Server能立即更新客户端信息表。

  那么首先得及时判断客户端是否下线,Eureka Server通过eureka.server.renewal-threshold-update-interval-ms来控制以什么样的频率去检测所有已注册客户端的心跳。该选项默认为15分钟,不过考虑到本人学艺不精,技不如人做出来的客户端质量拉胯,所以越早发现,才能越早治疗(手动重启),这里我修改为2分钟检测一次。

  发现有异常客户端之后,就得抓紧将异常的客户端移出。而Eureka Server是通过eureka.server.eviction-interval-timer-in-ms控制以什么样的频率去移出已失效的客户端。该选项默认为60秒。当然和上面一样,我希望能更快完成无效客户端的移出动作,所以我修改为5秒。

  Eureka Server内部有自己的数据缓存策略,这里不展开细讲。为了更快完成客户端列表的刷新,我们通过禁用ReadOnlyCache缓存来实现。eureka.server.use-read-only-response-cache: false

  服务端这样配置差不多就可以做到快速更新了,可是光服务端快是不行的,客户端也得跟上才行。而客户端最需要做的是“常联系,快退出”。

  “常联系”是要客户端加快与服务端发送心跳的间隔,两次心跳间隔时间越长,服务端的反应就越慢,理论上从客户端出现问题到客户端信息被移出,最长时间就是心跳间隔时间。如果心跳间隔为10分钟,那么该客户端最长需要10分钟(此处实际还需加上服务端的检测间隔时间)后才会被移出。

  “快退出”则是指客户端出现“失联”后,要让服务端快速、果断的移出该客户端,而不是磨磨蹭蹭拖半天。控制这一切的是由两个选项完成的。

eureka.instance.lease-renewal-interval-in-seconds

eureka.instance.lease-expiration-duration-in-seconds

以下是完整配置yml

eureka: 
  server: 
    enable-self-preservation: false
    renewal-threshold-update-interval-ms: 120000 
    eviction-interval-timer-in-ms: 5000 
    use-read-only-response-cache: false
  instance: 
    lease-expiration-duration-in-seconds: 10 
    lease-renewal-interval-in-seconds: 5 
  client: 
    fetch-registry: true
    register-with-eureka: true
    service-url: defaultZone: ${discovery.server}/eureka
复制代码

自定义页面直达关键信息

  Eureka Server自带了一个web查看页面,可通过该页面查看当前服务端的状态以及注册客户端的状态。原生页面的功能很好用,只是不太适合我的小云而已(毕竟有些功能我都不会用到,自然也就不关注了)。

  对于小云上运行的微服务,我更关注的是各个注册的客户端状态是否正常、Eureka状态是否正常(小云资源有限,稍不留神就OOM Kill了)。所以需要自定义Eureka的页面,做到打开链接,直达关键信息

  关于Eureka自定义页面网上相关教程也挺多的,这里就不重复了。简单来讲,首先将spring-cloud-netflix-eureka-server包中templates.erueka目录拷贝至工程resources下,然后按需修改对应的4个ftlh文件即可。

ui

关于Docker环境下需注意事项

  当客户端向Eureka Server注册的时候,Eureka会在30秒内连续3次检测客户端的状态(健康检测),之后才会将该客户端信息刷新至客户端列表当中。而在Docker执行环境下,通常使用编排工具(如Docker-compose)将所有服务一起启动,虽然服务均已运行,但是仍有可能收到404错误(需等待30秒后再访问)。

  客户端向Eureka Server注册时默认使用主机名进行注册,但是当该客户端在Docker中运行时,使用的主机名其实为Docker Container ID。如果是跨服务器访问则无法通过其查找到真正的客户端(DNS不知道注册使用的Docker Container ID所对应的IP地址),而如果仅使用preferIpAddress选项,虽然可用IP地址替换主机名完成注册,但不幸的是,所使用的IP为Docker Container IP,而非跨服务器所能访问的地址(一般需公网IP地址),所以依然不可被别的服务器使用。因此还需加上eureka.instance.ip-address,通过手动指定IP地址的方式,让客户端可达,这在后续记录中也会提到。

本文涉及源码地址Gitee

复制代码

Guess you like

Origin juejin.im/post/7053819297113571342