在演示spring cloud之前得要知道我們為什么需要微服務框架。
先講講我的經歷,以前我們做項目時所有功能都寫在一起,只是做了分層(模型,數據,業務),所有業務邏輯都寫在業務層,剛開始還好,等時間長了,代碼量大,各業務代碼之間有交集維護起來超級麻煩,每次改動都擔心會不會對其他模塊造成影響,只改動一個模塊也要停系統發一次包,我們以前包含了訂單,支付,會員,預定,庫存,物流等模塊,時間越長心里越慌,出問題的頻次也越高,就這樣惡性循環。后來我們嘗試着把會員剝離了出去,發現效果還不錯,后來慢慢的都一個個剝離了出去,一個模塊一個服務,各自維護,每次發包只要發對應的模塊,不影響其他模塊,大大的降低了出問題的頻次,維護起來也比較輕松。其實我們老早就摸到了微服務的門檻,只是那時候沒有理論和概念作為支撐,只知道這樣可行。
我相信大家或多或少有和我類似的經歷,上面已經說到了一個模塊一個服務,模塊服務化其實就是微服務所提倡的,微服務的主旨是將原本獨立的系統拆分成多個小型服務,這些小型服務都在各自獨立的進程中運行。我之前只有不超過10個服務,而且是單服務應用,沒有分布式,沒有負載均衡,只是點對點通信。想想看如果是成千上百個服務,我們該怎么辦,該如何管理這些服務?這個時候就該我們 spring cloud微服務框架出馬了。spring cloud微服務框架的目的就是方便我們協調服務,管理服務,能更快更好的擴展服務。它里面有服務統一的注冊中心,有客戶端負載均衡,有服務容錯保護,有網關,有服務追蹤等等。講了這么多,大家應該對微服務和微服務框架有了一個大體的認識,如果還不清楚的話,看一下我微服務欄里面的那個系列文章。
我們正式開始演示Spring Cloud Eureka,它包含了服務注冊中心,服務注冊,服務發現。我們把服務注冊中心歸類為Eureka的服務端,服務注冊,服務發現歸類為Eureka的客戶端。
服務注冊中心就是存放服務實例的地方(會保存服務實例的名稱,IP地址,端口號,等信息),服務注冊就是把服務提交到服務注冊中心,服務發現就是從服務注冊中心找到對應的服務。
大體的流程是這樣的:第一步你得現有一個服務注冊中心,第二部把你的服務注冊到服務注冊中心上去,第三步你的客戶端通過服務發現機制找到服務。
下面我們就來創建一個服務注冊中心
我們現在創建一個服務注冊中心,創建一個 名為 eureka-server 的 spring boot 項目
POM如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>org.springframework.boot</groupId> 7 <artifactId>spring-boot-starter-parent</artifactId> 8 <version>2.0.4.RELEASE</version> 9 <relativePath/> 10 </parent> 11 <groupId>com.jp</groupId> 12 <artifactId>eureka-server</artifactId> 13 <version>0.0.1-SNAPSHOT</version> 14 <name>eureka-server</name> 15 <description>Demo project for eureka-server</description> 16 17 18 <properties> 19 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 20 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 21 <java.version>1.8</java.version> 22 <spring-cloud.version>Finchley.SR1</spring-cloud.version> 23 </properties> 24 25 <dependencies> 26 <dependency> 27 <groupId>org.springframework.cloud</groupId> 28 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> 29 </dependency> 30 31 <dependency> 32 <groupId>org.springframework.boot</groupId> 33 <artifactId>spring-boot-starter-test</artifactId> 34 <scope>test</scope> 35 </dependency> 36 </dependencies> 37 38 <dependencyManagement> 39 <dependencies> 40 <dependency> 41 <groupId>org.springframework.cloud</groupId> 42 <artifactId>spring-cloud-dependencies</artifactId> 43 <version>${spring-cloud.version}</version> 44 <type>pom</type> 45 <scope>import</scope> 46 </dependency> 47 </dependencies> 48 </dependencyManagement> 49 50 <build> 51 <plugins> 52 <plugin> 53 <groupId>org.springframework.boot</groupId> 54 <artifactId>spring-boot-maven-plugin</artifactId> 55 </plugin> 56 </plugins> 57 </build> 58 </project>
啟動類:
1 @SpringBootApplication 2 @EnableEurekaServer 3 public class EurekaServerApplication { 4 public static void main(String[] args){ 5 SpringApplication.run(EurekaServerApplication.class , args); 6 } 7 }
啟動類中比平時我們創建的spring boot項目多了一個 @EnableEurekaServer,這個注解的功能就是幫我啟動一個服務注冊中心。
application.properties 配置內容如下:
1 spring.application.name=eureka-service 2 server.port=9001 3 eureka.instance.hostname=peer1 4 #是否向注冊中心注冊自己,客戶端需要開啟,默認為開啟 5 eureka.client.register-with-eureka=false 6 #是否檢索服務,客戶端需要開啟,默認為開啟 7 eureka.client.fetch-registry=false
eureka.instance.hostname 這個配置是主機名,客戶端訪問注冊中心用到(我這里配的 peer1 需要在本地 host中加入 127.0.0.1 peer1)
eureka.client.register-with-eureka 這個配置的意思是向注冊中心注冊自己,因為我們這個服務時注冊中心,所以不需要注冊自己,設置成 fasle
eureka.client.fetch-registry 這個配置的意思是是否檢索服務,服務發現的地方才需要檢索服務,我們服務注冊中心的職責是維護服務實例,所以也不需要,設置成false
項目建好了,配置也好了,我們來啟動項目,啟動好了之后,在地址欄里面輸入:http://localhost:9001/
打開地址之后會看到這樣的界面,說明我們注冊中心啟動成功了,我們發現 Instances currently registered with Eureka 這一欄是空的,說明還沒有服務注冊進來。
雖然我們服務注冊中心起來了,但是我們想一個問題,我們的服務注冊和服務發現都是依賴我們注冊中心的,我們我們服務中心掛了,那我們整個微服務體系就掛了(雖然客戶端可以存儲服務實例列表,可以繼續工作,但是也要隔端時間去服務注冊中心同步的,當無法同步繼續拿本地的服務實例操作時可能會引發一連貫的事故),所以我們需要保證服務注冊中心的高可用,我們只要改變下配置文件,就可以達到我們的目的
我們創建一個 application-s9001.properties 文件:
spring.application.name=eureka-service server.port=9001 eureka.instance.hostname=peer1 eureka.client.serviceUrl.defaultZone=http://peer2:9002/eureka/
#服務實例元數據,設置實例名,區分同一服務中不同實例的唯一標識
eureka.instance.instance-id= ${spring.cloud.client.ip-address}:${server.port}
#啟用IP地址經進行服務注冊
eureka.instance.prefer-ip-address=true
再創建一個 application-s9002.properties 文件:
spring.application.name=eureka-service server.port=9002 eureka.instance.hostname=peer2 eureka.client.serviceUrl.defaultZone=http://peer1:9001/eureka/
#服務實例元數據,設置實例名,區分同一服務中不同實例的唯一標識
eureka.instance.instance-id= ${spring.cloud.client.ip-address}:${server.port}
#啟用IP地址經進行服務注冊
eureka.instance.prefer-ip-address=true
eureka.client.serviceUrl.defaultZone : 指定了一個服務注冊中心地址,我們會把當前服務注冊到這個服務注冊中心上
可以看到我們這兩個配置文件取消了之前針對客戶端設置的兩個false配置,所以我們這兩個服務也是客戶端,為什么了,因為我們要把這兩個服務注冊注冊中心相互注冊,我們即使eureka的服務端,又是客戶端,其實eureka-service中自帶了一個客戶端,我們在做單服務實例時離心的會發現每隔一段時間會有一個報錯,這個就是eureka-service中自帶的客戶端造成的,其實eureka鼓勵我們使用多實例服務注冊中心
我們可以看到在 s9001中 指定了服務注冊中心的地址為 s9002,而 s9002 中指定了服務注冊中心的地址為s9001。
我們啟動兩個服務指定不同的配置文件,參數如下:
-Dspring.profiles.active=s9001
-Dspring.profiles.active=s9002
如果是通過idea啟動配置如下:
我們先啟動 端口是9001,啟動的時候會報錯,我們先忽略,我們接着啟動 端口是9002的服務,我們發現之前 端口9001的服務不報錯了,通過 http://localhost:9001/ 連接我們發現這個時候有服務有兩個地址,
這個時候我們就有兩個相互依賴的服務注冊中心了,那這兩個服務注冊怎么用了,我們下一篇介紹。