Spring cloud微服務實戰——高可用註冊中心(二)
上一篇我們介紹服務註冊中心、服務提供者、服務消費者的建立以及呼叫。本次課程介紹的是服務中心高可用設定,以及Eureka的自我保護模式。
高可用的服務註冊中心
在服務註冊中心其實也就是一個服務,它同樣可以向其他服務中心註冊,Eureka Servere的高可用實際上就是將自己作為服務向其他服務中心進行註冊,這樣就形成了相互註冊的服務註冊中心。下面我們就來配置一下。我們還是使用上一節的ack-center工程為示例,建立兩個節點,如下:
- application-node1.properties
spring.application.name=ack-center
server.port =9101
eureka.instance.hostname=ack-center-node1
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://ack-center-node2:9102/eureka/
- application-node1.properties
spring.application.name=ack-center
server.port=9102
eureka.instance.hostname =ack-center-node2
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://ack-center-node1:9101/eureka/
埠分別設定為9101,9102,node1和node2互相註冊,注意:eureka.client.register-with-eureka=true eureka.client.fetch-registry=true 設定為true,還記得之前我們設定為false,是不向自己進行註冊。這裡要設定為true。
記得修改hosts:
127.0.0.1 ack-center-node1
127.0.0.1 ack-center-node2
然後到ack-center目錄下用maven命令打包 mvn package。
打包成功後到target 目錄下通過spring.profiles.active屬性分別啟動node1,node2
java -jar ack-center-0.0.1-SNAPSHOT.jar --spring.profiles.active=node1
java -jar ack-center-0.0.1-SNAPSHOT.jar --spring.profiles.active=node2
開啟localhost:9101,看到node2已經註冊,同理開啟localhost:9102,看到node1已經註冊,registered-replicas,available-replicas,分別已經有了不同節點的資訊。
這樣我們就實現了服務的高可用。
服務提供者&消費者修改
在配置了多節點的服務註冊中心後,服務提供者和消費者需要相應的修改。同樣,我們還是藉助ack-provider和ack-consumer進行修改。
- 提供者修改eureka.client.service-url.defaultZone如下
spring.application.name=ack-provider
server.port=9001
eureka.instance.hostname=ack-provider
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://ack-center-node1:9101/eureka/,http://ack-center-node2:9102/eureka/
- 消費者修改eureka.client.service-url.defaultZone如下
spring.application.name=ack-consumer
server.port=9002
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
#eureka.client.service-url.defaultZone=http://ack-center:9000/eureka/
eureka.client.service-url.defaultZone=http://ack-center-node1:9101/eureka/,http://ack-center-node2:9102/eureka/
然後分別啟動提供者和消費者看到:
2017-09-26 11:25:41.380 INFO 7384 — [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_ACK-PROVIDER/localhost:ack-provider:9001: registering service…
2017-09-26 11:25:41.425 INFO 7384 — [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_ACK-PROVIDER/localhost:ack-provider:9001 - registration status: 204
ack-consumer也是同樣的道理。我們現在呼叫consumer的介面:http://localhost:9002/getHello
看到輸出:hello,I am from provider。
我們既然用了高可用的註冊中心,那麼現在我們把node1給停掉。同樣執行http://localhost:9002/getHello ,也會收到hello,I am from provider的輸出,因為provider同時向node1和node2進行了註冊,當斷開node1的時候,node2上的其他服務依然可以訪問,從而實現了服務註冊中心的高可用。
EMERGENCY!
當我們停掉一個服務的時候,會看到如下警告。
這是Eureka進入了保護模式,不會馬上把不可用的服務剔除掉,預設的心跳時間比較長,開發環境下,我們想快速踢出不可用服務時,如何做?很簡單,把自我保護功能設定為false:
server 端設定
eureka.server.enable-self-preservation=false
#Make sure eureka server can detect whether this app is up or down
eureka.instance.lease-renewal-interval-in-seconds=5
eureka.instance.lease-expiration-duration-in-seconds=5
client端設定
#Make sure eureka server can detect whether this app is up or down
eureka.instance.lease-renewal-interval-in-seconds=5
eureka.instance.lease-expiration-duration-in-seconds=5
這樣會報:
THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
提示你自我保護功能關閉會帶來的問題。加入ack-provider已經註冊了,這時候我們關閉ack-provider,過幾秒,ack-center控制檯會輸出
2017-09-26 15:00:40.772 INFO 7656 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 0ms
2017-09-26 15:00:40.772 INFO 7656 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Evicting 1 items (expired=1, evictionLimit=1)
2017-09-26 15:00:40.772 WARN 7656 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : DS: Registry: expired lease for ACK-PROVIDER/localhost:ack-provider:9001
2017-09-26 15:00:40.773 INFO 7656 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Cancelled instance ACK-PROVIDER/localhost:ack-provider:9001 (replication=false)
重新整理頁面,ack-provider已經被移除了。
不使用主機名來定義註冊中心的地址
修改properties
#####使用IP地址################
eureka.instance.prefer-ip-address=true
eureka.instance.instanceId=${spring.application.name}:${spring.cloud.client.ipAddress}:${server.port}
###########IP END#################
重啟重新整理頁面,則顯示了IP:埠
到這裡就結束了。