本文介绍如何搭建高可用 Eureka 集群,并解决该过程中遇到的一些坑。本文算是 Eureka 系列文章的第一篇,后面会继续探索基于 Docker 的 Eureka 集群搭建、灰度发布、金丝雀发布、AB测试以及蓝绿部署,从而做到无缝的升级更新服务。
首先,我解释下所谓的灰度发布、金丝雀发布、AB测试、蓝绿部署。
所谓灰度发布,是指先发布新版本,但是流量不直接切到该节点,而是先把测试人员的流量切到该节点,然后进行测试,如果没问题,便可以把所有流量切到新节点,我们就以最简单的系统来举个例子。假设某电商系统要升级,我们先在 另一个(相对目前运行的系统)端口部署新版本,然后在 nginx(或者别的负载均衡)里配置将测试账号的流量切到该节点,如果测试OK 没问题,则把所有流量切到新系统。
金丝雀发布,我个人理解和灰度发布一致,国内外叫法不一样的缘故吧,如有误,欢迎纠正。
AB测试则是线上的系统不同用户看到的功能不一样,比如A用户看到A功能,B用户看到B功能,然后分析数据,最后确定到底A功能好还是B功能好。
蓝绿部署则是有两组服务器,比如A和B,发布前,流量先都切到A,然后发布B,之后流量切到B。
其实,蓝绿发布和灰度发布很想象,但是前者保留了A,意味着可以随时回退,且回退很容易,而灰度发布则不容易回退喽。在实际场景下,建议灰度发布和蓝绿发布相结合。可以用两组 docker 来实现,虽然是双倍资源占用,但是 docker 你可以在发布后停止,这样则仅占用存储空间,也谈不上浪费。好了,正文开始:
创建 Spring boot 项目
首先,我们用 idea 新建一个项目,左侧点击 Spring Initializr 然后 Next 填入相关信息,然后继续 Next,左侧点击 Web 右侧勾选 Spring Web Starter,接着 左侧点击 Spring Cloud Discovery 右侧勾选 Eureka Server 最后继续 Next 完成项目的创建。
接着找到 入口类,比如 EurekaApplication ,添加注解:@EnableEurekaServer 以及 @EnableDiscoveryClient 然后修改 application.properties
修改 application.properties 文件
1、修改 application.properties 文件如下:
spring.profiles.active=node1 spring.profiles.include=default
2、新增 application-default.properties 文件如下:
server.port=6161 spring.application.name=eureka-server eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.instance.prefer-ip-address=false
3、新增 application-node1.properties 文件如下:
server.port=6161 eureka.instance.hostname=eureka-server1 eureka.client.serviceUrl.defaultZone=http://eureka-server3:6163/eureka/,http://eureka-server2:6162/eureka/
4、新增 application-node2.properties 文件如下:
server.port=6162 eureka.instance.hostname=eureka-server2 eureka.client.serviceUrl.defaultZone=http://eureka-server1:6161/eureka/,http://eureka-server3:6163/eureka/
5、新增 application-node3.properties 文件如下:
server.port=6163 eureka.instance.hostname=eureka-server3 eureka.client.serviceUrl.defaultZone=http://eureka-server1:6161/eureka/,http://eureka-server2:6162/eureka/
现在,我们可以打包了,打包后在终端里分别执行:
java -jar ./target/eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=node1 java -jar ./target/eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=node2 java -jar ./target/eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=node3
6、hosts 文件里 新增如下几行
127.0.0.1 eureka-server1 127.0.0.1 eureka-server2 127.0.0.1 eureka-server3
现在 你可以打开浏览器访问:http://localhost:6161/ 或者 http://localhost:6162/ 然后多刷新几下,然后查看 General Info 下面的 registered-replicas 以及 available-replicas 另外还有 unavailable-replicas, 看下 available-replicas 里面是否有另外两个节点。
遇到的问题,available-replicas 为空,unavailable-replicas 里的信息与 registered-replicas 一样:
讲道理,按我给的配置不应该出现这个问题,但是我遇到过这个问题,主要是要确保:
1、各个节点 只能共享同一个 spring.application.name 或 eureka.instance.appname,不能 node1 里是 spring.application.name=eureka-server1 而 node2 里是 spring.application.name=eureka-server2,这样子是不行,你只能在默认的 配置里写入 spring.application.name=eureka-server,或者 eureka.instance.appname=eureka-server 这两个值必须是各个节点共享的。
2、每个节点都必须配置 eureka.instance.hostname 且 eureka.client.serviceUrl.defaultZone 里面需要配置除了自身外的其他节点信息,多个节点间用逗号隔开,另外,hostname 不能用 localhost,比如这里,我分别用了 eureka-server1 、eureka-server2 以及 eureka-server3
3、另外也看到说要配置: eureka.instance.prefer-ip-address=false 但是新版里已经是默认的 false 了,不过,配置为 true 的确有问题。
4、同样的,看到说要配置:eureka.client.fetch-registry=true 以及 eureka.client.register-with-eureka=true 不过,最新版本里也是默认为 true,且我已经试过,如果改为 false 的确会出问题。
5、最后,一定要解析域名,你也可以在 hosts 文件里指定死。