SpringCloud封裝了Netflix公司開發的Eureka模塊來實現服務治理。java
在傳統的RPC遠程調用框架中,管理每一個服務與服務之間依賴關係比較複雜,管理比較複雜,因此須要服務治理,管理服務與服務間的依賴關係,能夠實現服務調用,負載均衡,容錯等,實現服務註冊與發現。git
Eureka採用了CS的設計架構:Eureka Server做爲服務註冊功能的服務器,它是服務註冊中心。而系統中的其餘微服務,使用Eureka Client鏈接到Eureka Server並維持心跳鏈接。這樣系統的維護人員就能夠經過Eureka Server來監控系統中各個服務是否正常運行。spring
在服務註冊與發現中,有一個註冊中心。當服務器啓動的時候,會把當前本身服務器信息【好比:服務地址、通信地址等】以別名的方式註冊到註冊中心上。另外一方【消費者服務提供者】,以該別名的方式去註冊中心上獲取到實際的服務通信地址,而後再實現本地RPC調用。api
遠程調用框架核心思想:在與註冊中心,由於使用註冊中心管理每一個與服務之間的一個依賴關係【服務治理概念】。在任何RPC遠程框架中,都會有一個註冊中心【存放服務地址相關的信息:接口地址】。緩存
Eureka Server提供服務的註冊服務服務器
各個微服務節點經過配置啓動後,會在EurekaServer中進行註冊,這樣EurekaServer中的服務註冊表中將會存儲所服務節點的信息,服務節點的信息能夠在接口中直觀的看到。架構
Eureka Client經過註冊中心進行訪問app
是一個Java客戶端,用與簡化Eureka Server的交互,客戶端同時也具有一個內置的,使用輪詢(round-robin)的負載均衡器。在應用啓動後,將會向Eureka Server發送心跳(默認週期爲30s)。若是Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,Eureka Server將會從服務註冊表中把這個服務節點移除掉(默認90s,也就是3個心跳週期).負載均衡
瞭解了Eureka的系統架構圖以後,咱們應該很是清楚,最簡單的實現也須要三個角色:服務消費者,服務提供者,註冊中心EurekaServer。已知咱們已經擁有了兩個角色:框架
咱們還需建立一個服務中心模塊:cloud-eureka-server7001。
<!--eureka server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
server: port: 7001 eureka: instance: hostname: localhost #eureka服務端的實例名稱 client: register-with-eureka: false #false表示不向註冊中心註冊本身。 fetch-registry: false #false表示本身端就是註冊中心,個人職責就是維護服務實例,並不須要去檢索服務 service-url: # 設置與Eureka Server交互的地址查詢服務和註冊服務都須要依賴這個地址 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
@SpringBootApplication @EnableEurekaServer public class EurekaServer7001Application { public static void main(String[] args) { SpringApplication.run(EurekaServer7001Application.class,args); } }
訪問localhost:7001/
,出現以下界面,表示Eureka已經配置完成。但此時你會發現,第二欄出現了No instances available,由於此時尚未將兩個客戶端加入。
服務端已經配置,接下來就是配置註冊客戶端的操做。在操做以前,咱們應該可以聯想,既然代表服務註冊中心用的是:@EnableEurekaServer,那麼是否是代表客戶端也有相似的註解呢?是否是也要引入相似的依賴呢?確實,是這樣的。咱們以cloud-provider-payment8001
服務爲例,先試着將該服務註冊進註冊中心。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
在yml中增長一下內容:
eureka: client: #表示是否將本身註冊進EurekaServer默認爲true。 register-with-eureka: true #是否從EurekaServer抓取已有的註冊信息,默認爲true。單節點無所謂,集羣必須設置爲true才能配合ribbon使用負載均衡 fetchRegistry: true service-url: #單機版 defaultZone: http://localhost:7001/eureka
@EnableEurekaClient @SpringBootApplication public class Payment8001Application { public static void main(String[] args) { SpringApplication.run(Payment8001Application.class,args); } }
咱們先啓動EurekaServer7001Application,再啓動Payment8001Application,接着訪問:localhost:7001/
,咱們能夠看到Application爲CLOUD-PAYMENT-SERVICE
的服務已經註冊進來。
而這裏的Application的名稱就是咱們在yml中配置的spring.application.name=cloud-payment-service
。
ok,咱們能夠照着上述步驟,將另一個客戶端也註冊進來,這裏就不贅述了。
啓動服務並註冊完成後,若是停掉服務,30s後,Eureka會開啓保護機制:
服務註冊實際上就是將服務信息註冊到註冊中心中,服務發現實際上就是從註冊中心中獲取到服務的信息,本質上就是key-value形式信息的存入與讀取。
key就是服務的名字,value就是服務調用的地址。
搭建Eureka註冊中心集羣,實現負載均衡和故障容錯,也就是Eureka server和provider都是多個的,這防止一個註冊中心故障,全部都GG。
而集羣的搭建原理在於:每一個Eureka註冊中心之間相互註冊,相互同步心跳。
此時從父pom中查看一下module的結構:
<modules> <module>cloud-provider-payment8001</module> <module>cloud-consumer-order80</module> <module>cloud-api-commons</module> <module>cloud-eureka-server7001</module> <module>cloud-eureka-server7002</module> </modules>
在C:\Windows\System32\drivers\etc
目錄下的hosts文件添加如下映射:
127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com
server: port: 7001 eureka: instance: hostname: eureka7001.com #eureka服務端的實例名稱 client: register-with-eureka: false #false表示不向註冊中心註冊本身。 fetch-registry: false #false表示本身端就是註冊中心,個人職責就是維護服務實例,並不須要去檢索服務 service-url: #集羣指向其它eureka defaultZone: http://eureka7002.com:7002/eureka/ ######################### 7001 < - > 7002 ############################# server: port: 7002 eureka: instance: hostname: eureka7002.com #eureka服務端的實例名稱 client: register-with-eureka: false #false表示不向註冊中心註冊本身。 fetch-registry: false #false表示本身端就是註冊中心,個人職責就是維護服務實例,並不須要去檢索服務 service-url: #集羣指向其它eureka defaultZone: http://eureka7001.com:7001/eureka/
訪問localhost:7001/
和localhost:7002/
,發現兩個中心都成功啓動。固然,咱們已經配置了路徑映射,訪問eureka7001.com:7001/
和eureka7002.com:7002/
的效果是同樣的。
單機版的時候穩定指向http://localhost:7001/eureka
,集羣狀態下須要改變eureka.client.service-url.defaultZone
的值:
eureka: client: #表示是否將本身註冊進EurekaServer默認爲true。 register-with-eureka: true #是否從EurekaServer抓取已有的註冊信息,默認爲true。單節點無所謂,集羣必須設置爲true才能配合ribbon使用負載均衡 fetchRegistry: true service-url: # #單機版 # defaultZone: http://localhost:7001/eureka # 集羣版 defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
此時兩個註冊中心都註冊了兩個客戶端服務,表明已經配置完成。
咱們訪問註冊中心,能夠發現CLOUD-PAYMENT-SERVICE對應兩臺提供服務者:
private static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced //賦予RestTemplate負載均衡的能力 public RestTemplate restTemplate(){ return new RestTemplate(); } }
接着屢次訪問:http://localhost/consumer/payment/1
,會輪換者調用不一樣服務者的接口。
本系列文章爲《尚硅谷SpringCloud教程》的學習筆記【版本稍微有些不一樣,後續遇到bug再作相關說明】,主要作一個長期的記錄,爲之後學習的同窗提供示例,代碼同步更新到Gitee:https://gitee.com/tqbx/spring-cloud-learning,而且以標籤的形式詳細區分每一個步驟,這個系列文章也會同步更新。