Eureka集群
集群概述
簡單陳述下,什么是集群!說直白一點,同一件事多個處理者一起來做,人多力量大,眾人拾柴火焰高!比如說車站窗口的售票員!同一件事(都是賣票),交給一個人去完成就得了嘛,何必弄那么多個呢?同樣的邏輯,我們部署在電腦(服務(wù)器)上的應(yīng)用系統(tǒng)也可能出現(xiàn)“火車站只有一個售票員”的問題!
集群靈魂
集群靈魂!集群還有靈魂這一說么?剛剛提到,眾人拾柴火焰高!人多了,柴就能拾取得更多么?電腦都買回來了并且都放入機房了,這就成集群了嗎?當(dāng)然不是,我們需要一個組織,將這些人、電腦通過一個邏輯組織起來,這才是集群!那么這個組織邏輯就是集群靈魂!
Eureka集群搭建
00 在上一章節(jié),我們實現(xiàn)了這幅圖的邏輯:

解決了跨App間邏輯調(diào)用、通信的問題,中心的Eureka是各個App間的通信“基站”,試想一下,假如這個基站因為要解決通信的邏輯太多、任務(wù)太重或因為其他原因宕機而不能正常提供服務(wù)會產(chǎn)生怎樣的后果?各應(yīng)用的邏輯間不能互相調(diào)用,造成整個應(yīng)用架構(gòu)體系的癱瘓!

那么首先,實現(xiàn)以下結(jié)構(gòu):

01 新配置兩個本地域名:編輯C:\Windows\System32\drivers\etc\hosts 文件,添加 127.0.0.1 的本地域名:
# 將該行添加到末尾
127.0.0.1 slave1 slave2
測試,slave1,slave2 是否配置成功!ping:
C:\Users\wu-chao>ping slave1
正在 Ping slave1 [127.0.0.1] 具有 32 字節(jié)的數(shù)據(jù):
來自 127.0.0.1 的回復(fù): 字節(jié)=32 時間<1ms TTL=64
來自 127.0.0.1 的回復(fù): 字節(jié)=32 時間<1ms TTL=64
來自 127.0.0.1 的回復(fù): 字節(jié)=32 時間<1ms TTL=64
來自 127.0.0.1 的回復(fù): 字節(jié)=32 時間<1ms TTL=64
127.0.0.1 的 Ping 統(tǒng)計信息:
數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒為單位):
最短 = 0ms,最長 = 0ms,平均 = 0ms
C:\Users\wu-chao>ping slave2
正在 Ping slave1 [127.0.0.1] 具有 32 字節(jié)的數(shù)據(jù):
來自 127.0.0.1 的回復(fù): 字節(jié)=32 時間<1ms TTL=64
來自 127.0.0.1 的回復(fù): 字節(jié)=32 時間<1ms TTL=64
來自 127.0.0.1 的回復(fù): 字節(jié)=32 時間<1ms TTL=64
來自 127.0.0.1 的回復(fù): 字節(jié)=32 時間<1ms TTL=64
127.0.0.1 的 Ping 統(tǒng)計信息:
數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒為單位):
最短 = 0ms,最長 = 0ms,平均 = 0ms
slave1、slave2 成功訪問本機IP地址 127.0.0.1,成功!
02 將上一章節(jié)創(chuàng)建的三個工程放入同一個文件夾,如./Eureka,idea open ./Eureka,如此一來,idea 就將三個工程同時打開在一個視圖窗口中:

idea ivew=>Too Windows=> Maven Projects ,打開maven視圖,將三個工程的pom.xml 文件添加到maven project:

03 idea 同時打開三個工程目錄,相關(guān)的運行,故使用maven運行,打開EurekaService pom.xml,添加build配置:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>person.jack.eureka.EurekaService</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
04 刪除EurekaService 工程刪除application.properties 配置文件,添加application-slave1.properties、application-slave2.properties:
resources
application-slave1.properties
application-slave2.properties
# 內(nèi)容分別如下
# application-slave1.propertie
profile=slave1
server.port=8761
spring.application.name=EurekaService1
eureka.client.service-url.defaultZone=http://localhost:8762/eureka/
# application-slave2.properties
profile=slave2
server.port=8762
spring.application.name=EurekaService2
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
# 如此一來,該工程就有了兩個配置文件,通過配置啟動參數(shù)(spring.profiles.active)以指定使用哪個配置文件啟動
05 idea 添加maven命令,啟動項目,編輯啟動配置:【Edit Configurations】,添加maven啟動命令:

同樣的方法,再添加一個EurekaSlave2,其Command line如下:
exec:java -Dexec.mainClass=person.jack.eureka.EurekaService -Dspring.profiles.active=slave2
06 運行EurekaService1,EurekaService2 那么1、2就會自動抓取互為客戶端;先啟動EurekaService1,自動抓取EurekaService2(eureka.client.service-url.defaultZone=http://localhost:8762/eureka/),其實EurekaService2還未啟動,所以此啟動過程是會報異常的,不理它,下一步同樣的方法啟動EurekaService2,就不會報錯了!


http://localhost:8761 頁面打印信息
Instances currently registered with Eureka
| Application | AMIs | Availability Zones | Status |
|---|---|---|---|
| EUREKASERVICE1 | n/a (1) | (1) | UP (1) - LAPTOP-TJDLNJHK:EurekaService1:8761 |
| EUREKASERVICE2 | n/a (1) | (1) | UP (1) - LAPTOP-TJDLNJHK:EurekaService2:8762 |
http://localhost:8762 頁面打印信息
Instances currently registered with Eureka
| Application | AMIs | Availability Zones | Status |
|---|---|---|---|
| EUREKASERVICE1 | n/a (1) | (1) | UP (1) - LAPTOP-TJDLNJHK:EurekaService1:8761 |
| EUREKASERVICE2 | n/a (1) | (1) | UP (1) - LAPTOP-TJDLNJHK:EurekaService2:8762 |
Eureka集群搭建成功
搭建應(yīng)用集群
現(xiàn)在基站已經(jīng)是集群了,那么我們的應(yīng)用呢?舉例,假如我們購買火車票只能去一個火車站(不考慮網(wǎng)絡(luò)訂票),那么該火車站勢必人脈為患,排隊的長龍勢必超長,車站勢必“宕機”!所以就得考慮以下結(jié)構(gòu):

如此,應(yīng)用也成集群了!
01 改造AppOne,刪除application.properties 文件,添加 application-8081.properties 、application-8082.properties,內(nèi)容分別如下:
###### application-8081.properties ######
server.port=8081
# 應(yīng)用名稱
spring.application.name=AppOne
# eureka服務(wù)端地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/,http://localhost:8762/eureka/
###### application-8082.properties ######
server.port=8082
# 應(yīng)用名稱
spring.application.name=AppOne
# eureka服務(wù)端地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/,http://localhost:8762/eureka/
02 同樣,改造AppTwo:
###### application-8083.properties ######
server.port=8083
# 應(yīng)用名稱
spring.application.name=AppTwo
# eureka服務(wù)端地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/,http://localhost:8762/eureka/
###### application-8084.properties ######
server.port=8084
# 應(yīng)用名稱
spring.application.name=AppTwo
# eureka服務(wù)端地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/,http://localhost:8762/eureka/
03 現(xiàn)在一個app有兩個配置文件了,同樣配置maven 命令啟動對應(yīng)的App:

04 依次啟動EurekaSlave1、EurekaSlave2、AppOne_8081、AppOne_8082、AppTwo_8083、AppTwo_8084,注意 各Controller代碼邏輯:
# AppTwo/AppTwoHello 代碼:
package person.jack.controller
@RestController
public class AppTwoHello {
@Autowired
private RestTemplate restTemplate;
@ResponseBody
@RequestMapping("/getAppOneMesg/{mesg}")
public String getAppOneMesg(@PathVariable String mesg){
String strMesg=restTemplate.getForObject("http://APPONE/sayMesg/" + mesg, String.class);
return "訪問App2,從App1 收到信息:“"+strMesg+"“";
}
}
# AppOne/HelloController 代碼:
package person.jack.controller;
@RestController
public class HelloController {
@Value("${spring.application.name}")
private String springAppName;
@Value("${spring.profiles.active}")
private String active;
@ResponseBody
@RequestMapping(value = "/sayMesg/{word}")
public String sayMesg(@PathVariable String word){
System.out.println(springAppName);
System.out.println(active);
return springAppName+":"+active + word ;
}
}
05 測試:訪問AppTwo 8083,http://localhost:8083/getAppOneMesg/abc 并多次刷新:
# 頁面交替打印
訪問App2,從App1 收到信息:“AppOne:8081abc“
訪問App2,從App1 收到信息:“AppOne:8082abc“
06 測試:訪問AppTwo 8084,http://localhost:8084/getAppOneMesg/abc 并多次刷新:
# 頁面交替打印
訪問App2,從App1 收到信息:“AppOne:8081abc“
訪問App2,從App1 收到信息:“AppOne:8082abc“
07 如此,AppTwo 調(diào)用AppOne,那么調(diào)用的就不是一個AppOne 實例,而是調(diào)用AppOne 的集群,其實例會被輪次調(diào)用!測試通過!
08 應(yīng)用集群搭建成功!
重新認(rèn)識Eureka
停止EurekaSlave1、EurekaSlave2 服務(wù),重新測試 http://localhost:8083/getAppOneMesg/abc、http://localhost:8084/getAppOneMesg/abc:
# 頁面依然交替交替打印
訪問App2,從App1 收到信息:“AppOne:8081abc“
訪問App2,從App1 收到信息:“AppOne:8082abc“
這是為什么?“基站”服務(wù)不存在了,App2 同App1 應(yīng)該是不能通信了才對!可事實上,他們沒有斷開!
Eureka,它實際上起到的是一個注冊服務(wù)!它就像一個云端通訊錄!AppOne、AppTwo 啟動到并注冊到云端,那么AppOne(AppTwo)就同時獲取了其他云端成云的聯(lián)系信息【并緩存到本App】,所以若“基站”服務(wù)突然不存在了,并不妨礙宕機之前以注冊到“基站”App間的通信!但若一個新的App也試著注冊到Eureka,首先,它無法注冊,因為“基站”服務(wù)已經(jīng)不存在了,其二,那么新注冊的App無法與之前的App進行通信,因為它們之間沒有在一個云端里交流!若想更新“通訊方式”,需重啟Eureka服務(wù)以自動捕獲Eureka客戶端刷新“通訊錄”。