SpringCloud服務(wù)注冊中心雙節(jié)點集群(Eureka集群)

作者:xcbeyond
瘋狂源自夢想,技術(shù)成就輝煌!微信公眾號:《程序猿技術(shù)大咖》號主,專注后端開發(fā)多年,擁有豐富的研發(fā)經(jīng)驗,樂于技術(shù)輸出、分享,現(xiàn)階段從事微服務(wù)架構(gòu)項目的研發(fā)工作,涉及架構(gòu)設(shè)計、技術(shù)選型、業(yè)務(wù)研發(fā)等工作。對于Java、微服務(wù)、數(shù)據(jù)庫、Docker有深入了解,并有大量的調(diào)優(yōu)經(jīng)驗。

0、前言
        最近在進行重構(gòu)一個新項目,為了后續(xù)更好的落地,適應(yīng)于日新月異的技術(shù)更新,進行了各方的技術(shù)選型及技術(shù)預(yù)研,最終選型基于微服務(wù)架構(gòu)體系進行開發(fā)重構(gòu)。項目構(gòu)建前最重要的一步就是要想清楚,整體的部署架構(gòu)、高可用性(HA)等等,做好前期的部署架構(gòu)技術(shù)調(diào)研,確定最終方案。

        在微服務(wù)架構(gòu)體系中,核心技術(shù)便是Spring Cloud,通過登錄官網(wǎng)查看SpringCloud已經(jīng)集成了好多優(yōu)質(zhì)的項目,供我們使用借鑒。而SpringCloud Eureka是云端服務(wù)發(fā)現(xiàn),一個基于 REST 的服務(wù),用于定位服務(wù),以實現(xiàn)云端中間層服務(wù)發(fā)現(xiàn)和故障轉(zhuǎn)移,并且支持集群部署。因此,本次部署架構(gòu)技術(shù)方案選型打算采用Eureka集群。

(關(guān)于Eureka服務(wù)注冊與發(fā)現(xiàn)請查看上一章節(jié)內(nèi)容【SpringCloud系列】一、SpringCloud服務(wù)注冊與發(fā)現(xiàn)(Eureka))

         本文將闡述SpringCloud服務(wù)注冊中心雙節(jié)點集群(Eureka集群)方案及集群demo。

1、Eureka集群概述
1.1 基本原理


如上圖,是Eureka集群配置圖。

- 不同節(jié)點的Eureka Server通過Replicate(復(fù)制)進行數(shù)據(jù)同步
- Application Service為服務(wù)提供者
- Application Client為服務(wù)消費者
- Make Remote Call完成一次服務(wù)調(diào)用

        服務(wù)啟動后向Eureka注冊,Eureka Server會將注冊信息向其他Eureka Server進行同步,當服務(wù)消費者要調(diào)用服務(wù)提供者,則向服務(wù)注冊中心獲取服務(wù)提供者地址(即:服務(wù)應(yīng)用名,spring.application.name參數(shù)配置),然后會將服務(wù)提供者地址緩存在本地,下次再調(diào)用時,則直接從本地緩存中取,完成一次調(diào)用。

        當服務(wù)注冊中心Eureka Server檢測到服務(wù)提供者因為宕機、網(wǎng)絡(luò)原因不可用時,則在服務(wù)注冊中心將服務(wù)置為DOWN狀態(tài),并把當前服務(wù)提供者狀態(tài)向訂閱者發(fā)布,訂閱過的服務(wù)消費者更新本地緩存。

        服務(wù)提供者在啟動后,周期性(默認30秒)向Eureka Server發(fā)送心跳,以證明當前服務(wù)是可用狀態(tài)。Eureka Server在一定的時間(默認90秒)未收到客戶端的心跳,則認為服務(wù)宕機,注銷該實例。

1.2 Eureka自我保護機制
        在默認配置中,Eureka Server在默認90s沒有得到客戶端的心跳,則注銷該實例,但是往往因為微服務(wù)跨進程調(diào)用,網(wǎng)絡(luò)通信往往會面臨著各種問題,比如微服務(wù)狀態(tài)正常,但是因為網(wǎng)絡(luò)分區(qū)故障時,Eureka Server注銷服務(wù)實例則會讓大部分微服務(wù)不可用,這很危險,因為服務(wù)明明沒有問題。

         為了解決這個問題,Eureka 有自我保護機制,通過在Eureka Server配置如下參數(shù),可啟動保護機制。

eureka.server.enable-self-preservation=true
         它的原理是,當Eureka Server節(jié)點在短時間內(nèi)丟失過多的客戶端時(可能發(fā)送了網(wǎng)絡(luò)故障),那么這個節(jié)點將進入自我保護模式,不再注銷任何微服務(wù),當網(wǎng)絡(luò)故障回復(fù)后,該節(jié)點會自動退出自我保護模式。

1.3 Eureka高可用集群
        理論上來講,因為服務(wù)消費者本地緩存了服務(wù)提供者的地址,即使Eureka Server宕機,也不會影響服務(wù)之間的調(diào)用,但是一旦新服務(wù)上線,已經(jīng)在緩存在本地的服務(wù)提供者不可用了,服務(wù)消費者也無法知道,所以保證Eureka Server的高可用還是很有必要的。

        在分布式系統(tǒng)中,任何的地方存在單點,整個體系就不是高可用的,Eureka 也一樣,在上面的架構(gòu)圖中Eureka Server不是以單點存在的,而是以集群的方式對外提供服務(wù)。

2、Eureka雙中心節(jié)點集群
本節(jié)以具體示例說明Eureka集群及配置。

2.1 創(chuàng)建Eureka Server
(1)新建springCloudEurekaCluster項目作為Eureka Server集群項目:

pom.xml如下:

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.xcbeyond.springcloud</groupId>
    <artifactId>springCloudEurekaCluster</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springCloudEurekaCluster</name>
    <url>http://maven.apache.org</url>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/>
    </parent>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
    </dependencies>
    
    <description>Eureka集群</description>
</project>
(2)配置application.properties。

    在Eureka Server集群時,需要部署多個節(jié)點,則需要同一個項目,使用不同的配置。因此,在本例中使用springCloudEurekaCluster一個項目通過不同的啟動參數(shù)來啟動占用不同端口的兩個Server服務(wù),來模擬Eureka集群。則使用下面三個*.properties配置文件:

application.properties
application-eureka-server1.properties
application-eureka-server2.properties
application.properties

#應(yīng)用名
spring.application.name=eureka-cluster
application-eureka-server1.properties

##eureka-server1節(jié)點配置,配置參數(shù)--spring.profiles.active=eureka-server1來啟動該環(huán)境
spring.profiles=eureka-server1
server.port=8761
eureka.instance.hostname=eureka-server1
eureka.client.serviceUrl.defaultZone=http://eureka-server2:8762/eureka/
application-eureka-server2.properties

##eureka-server2節(jié)點配置,配置參數(shù)--spring.profiles.active=eureka-server2來啟動該環(huán)境
spring.profiles=eureka-server2
server.port=8762
eureka.instance.hostname=eureka-server2
eureka.client.serviceUrl.defaultZone=http://eureka-server1:8761/eureka/
       application-eureka-server1.properties、application-eureka-server2.properties配置文件設(shè)置了不同的端口(server.port),重點是參數(shù)eureka.client.serviceUrl.defaultZone,分別配置對方的地址作為Eureka Client進行相互注冊。由于采用了參數(shù)配置eureka.instance.hostname及http://eureka-server1的寫法,則需要在進行hosts的配置,window在C:\Windows\System32\drivers\etc\hosts,Linux是在/etc/host,此處,以我windows本機說明,在hosts文件中最近如下配置:

127.0.0.1 eureka-server1
127.0.0.1 eureka-server2
(3)新建啟動類。

com.xcbeyond.springcloud.eurekacluster.EurekaClusterApplication.java

package com.xcbeyond.springcloud.eurekacluster;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 
/**
 * Eureka集群啟動類
 * @author xcbeyond
 * 2018年8月7日上午10:34:01
 */
@SpringBootApplication
//開啟對EurekaServer的支持,即:作為Eureka服務(wù)端
@EnableEurekaServer
//開啟作為Eureka Server的客戶端的支持
@EnableDiscoveryClient
public class EurekaClusterApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaClusterApplication.class, args);
    }
}
重點添加@EnableEurekaServer注解,開啟對EurekaServer的支持,即:作為Eureka服務(wù)端。

項目源碼:https://download.csdn.net/download/xcbeyond/10592831

2.2.Eureka集群啟動及驗證
2.2.1 集群啟動
      在創(chuàng)建Eureka server項目時,創(chuàng)建了兩個properties配置文件,作為集群不同的節(jié)點配置文件,在啟動項目時,只需指定啟動參數(shù)--spring.profiles.active=eureka-server1來指定對應(yīng)配置環(huán)境,運行啟動類即可。Eclipse IDE開發(fā)環(huán)境下,配置啟動參數(shù)方式如下:

在啟動第一個節(jié)點eureka-server1過程中,會持續(xù)出現(xiàn)如下錯誤信息:






2018-08-09 10:29:25.225 ERROR 7964 --- [nfoReplicator-0] c.n.d.s.t.d.RedirectingEurekaHttpClient  : Request execution error
 
com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
    at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187) ~[jersey-apache-client4-1.19.1.jar:1.19.1]
    at com.sun.jersey.api.client.filter.GZIPContentEncodingFilter.handle(GZIPContentEncodingFilter.java:123) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.netflix.discovery.EurekaIdentityHeaderFilter.handle(EurekaIdentityHeaderFilter.java:27) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.sun.jersey.api.client.Client.handle(Client.java:652) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient.register(AbstractJerseyEurekaHttpClient.java:56) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.MetricsCollectingEurekaHttpClient.execute(MetricsCollectingEurekaHttpClient.java:73) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.executeOnNewServer(RedirectingEurekaHttpClient.java:118) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.execute(RedirectingEurekaHttpClient.java:79) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:120) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.DiscoveryClient.register(DiscoveryClient.java:829) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:121) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.InstanceInfoReplicator$1.run(InstanceInfoReplicator.java:101) [eureka-client-1.9.2.jar:1.9.2]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_121]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_121]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_121]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.8.0_121]
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) ~[na:1.8.0_121]
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_121]
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_121]
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_121]
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_121]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_121]
    at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_121]
    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121) ~[httpclient-4.5.5.jar:4.5.5]
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180) ~[httpclient-4.5.5.jar:4.5.5]
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144) ~[httpclient-4.5.5.jar:4.5.5]
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134) ~[httpclient-4.5.5.jar:4.5.5]
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610) ~[httpclient-4.5.5.jar:4.5.5]
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445) ~[httpclient-4.5.5.jar:4.5.5]
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835) ~[httpclient-4.5.5.jar:4.5.5]
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:118) ~[httpclient-4.5.5.jar:4.5.5]
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) ~[httpclient-4.5.5.jar:4.5.5]
    at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:173) ~[jersey-apache-client4-1.19.1.jar:1.19.1]
    ... 30 common frames omitted
 
2018-08-09 10:29:25.225  WARN 7964 --- [nfoReplicator-0] c.n.d.s.t.d.RetryableEurekaHttpClient    : Request execution failed with message: java.net.ConnectException: Connection refused: connect
2018-08-09 10:29:25.225  WARN 7964 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_EUREKA-CLUSTER/xuchao:eureka-cluster:8761 - registration failed Cannot execute request on any known server
 
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
    at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.DiscoveryClient.register(DiscoveryClient.java:829) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:121) [eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.InstanceInfoReplicator$1.run(InstanceInfoReplicator.java:101) [eureka-client-1.9.2.jar:1.9.2]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_121]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_121]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_121]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
 
2018-08-09 10:29:25.225  WARN 7964 --- [nfoReplicator-0] c.n.discovery.InstanceInfoReplicator     : There was a problem with the instance info replicator
 
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
    at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.DiscoveryClient.register(DiscoveryClient.java:829) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:121) ~[eureka-client-1.9.2.jar:1.9.2]
    at com.netflix.discovery.InstanceInfoReplicator$1.run(InstanceInfoReplicator.java:101) [eureka-client-1.9.2.jar:1.9.2]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_121]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_121]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_121]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
     分析日志可知,是在第一個節(jié)點eureka-server1啟動后,向eureka-server2注冊時連接拒絕(java.net.ConnectException: Connection refused: connect)導(dǎo)致,因為此時eureka-server2節(jié)點還未啟動,所有出現(xiàn)此類錯誤信息是正常的,eureka-server2啟動后,此類錯誤日志將不會出現(xiàn)。關(guān)于各類集群環(huán)境不同節(jié)點在順次啟動時都會出現(xiàn)類似錯誤信息的,大家不必驚慌!

       

        在瀏覽器中分別訪問各自節(jié)點的地址、端口,http://eureka-server1:8761/、http://eureka-server2:8762/

從上面兩張圖可以看出,DS Replicas、registered-replicas、available-replicas分別有了對方的地址,即:相互Replicate、相互注冊,則說明Eureka集群成功。

2.2高可用性驗證
如果出現(xiàn)其中一個節(jié)點宕機,結(jié)果將會如何呢?

停掉eureka-server1服務(wù)作為模擬宕機,訪問http://eureka-server1:8761/顯示無法訪問,http://eureka-server2:8762/正常訪問,eureka-server2節(jié)點信息如下:

發(fā)生變化之處,如上圖標注,eureka-server1宕機后,eureka-server2依舊可以發(fā)現(xiàn)eureka-server1,而eureka-server1只是變?yōu)閡navailable-replicas而已,最終不會影響其他客戶端的注冊。當eureka-server1啟動后,一切自動恢復(fù)。

(其他高可用性的驗證,感興趣的可一一驗證)