目錄
1.開發環境
環境 | 版本 |
---|---|
Springboot | 2.1.5.RELEASE |
Springcloud | Greenwich.SR1 |
jdk | 1.8 |
Maven私服 | 第二篇搭建的私服 |
騰訊雲系統 | centos7 |
騰訊雲ip | 192.168.1.100(非真實ip) |
2.Springcloud環境搭建
相信許多朋友或多或少都使用或接觸過Springcloud。Springcloud基於Springboot開發,提供了一套完整的微服務解決方案,其豐富的組件,配置中心,全鏈路監控,API網關,熔斷器等選型中立的開源組件,可以按需擴展和替換。今天做爲Springcloud系列第一篇,就從環境搭建開始,後續章節也都會在此環境下進行書寫。
- 版本命名
1.大版本命名:Springcloud版本命名以倫敦地鐵站名稱英文字母升序排列。
2.小版本命名:同一大版本中會有許多不同的小版本,小版本以".SRX"的命名格式,其中"X"爲數字,如Greenwich.SR1
- 版本選擇
Springcloud的版本需與Springboot版本選擇相匹配,否則啓動時會報錯且無法啓動成功,版本對應如下表,大家也可以登錄Springcloud官網進行查閱springcloud與springboot版本對比
Springcloud版本 | Springboot版本 |
---|---|
Greenwich | 2.1.x |
Finchley | 2.0.x |
Edgware | 1.5.x |
Dalston | 1.5.x |
- 環境搭建
本系列文章選擇的Springcloud版本爲目前最新版本Greenwich.SR1
,Springboot版本爲2.1.5.RELEASE
,下邊開始我們Springcloud項目的搭建,搭建maven工程比較簡單,在此就不做演示,下邊只展示項目pom.xml。
1.引入Springboot父級依賴
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
2.設置變量
<properties>
<!--jdk版本-->
<jdk.version>1.8</jdk.version>
<!--Springcloud版本-->
<spring.cloud.version>Greenwich.SR1</spring.cloud.version>
</properties>
3.引入Springcloud依賴
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
4.完整pom.xml依賴
<properties>
<jdk.version>1.8</jdk.version>
<spring.cloud.version>Greenwich.SR1</spring.cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--設置構建插件及環境-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<!--構建設置-->
<configuration>
<encoding>utf-8</encoding>
<!--java編譯版本-->
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>
上述依賴配置完畢後,等待下載依賴jar包,本系列文章的依賴都是從上一篇文章搭建的Maven私服下載的,大家也可以配置阿里雲鏡像或直接從中央倉庫下載,依賴下載時間看自己網速,靜待依賴下載完成,咱們的Springcloud項目環境準備已經完成,那就開始註冊中心的學習吧。
3.註冊中心之Eureka
1.Eureka閉源,相信大家都知道Eureka2.0版本已經閉源了,1.x版本可正常使用,2.x已經開源部份可以正常使用,但風險自擔,大家可以看看官方說明Eureka閉源wiki
2.在此還想講講Eureak,主要是想保證文章的完整性,下邊我們會整合Springcloud+consul做爲後續文章的註冊中心
註冊中心見名知意,就是專門用來註冊服務之用。在微服務中,服務提供者將服務註冊至註冊中心,服務消費者要調用某個服務,則從註冊中心查找需要調用的服務ip:port,然後本地通過http調用服務,從而完成服務調用。
3.1 入門案例
-
項目結構
-
編寫Eureka Server
(1) 引入依賴
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
(2) 書寫application.yml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
參數名 | 說明 |
---|---|
eureka.instance.hostname | eureka服務端ip |
eureka.client.fetch-registry | 是否獲取註冊表信息,由於是服務Eureka server,則設置爲false |
eureka.client.register-with-erueka | 是否將服務註冊至註冊中心 |
eureka.client.service-url: | 註冊中心地址 |
(3) 書寫啓動類,註冊中心添加@EnableEurekaServer
註解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
(4) 啓動服務,訪問http://localhost:8761/
,出現如下圖所示,即表示註冊中心配置成功
- 編寫Eureka Client
(1) 引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
(2) 書寫application.yml
server:
port: 8762
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: eureka-client
(3) 書寫啓動類,添加@EnableEurekaClient
註解
@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
(4) 查看服務是否註冊至註冊中心,輸入http://localhost:8761
,出現下圖表示服務已經註冊至註冊中心
注意:Eureka使用LeaseInfo來標識服務租約信息,其包含如下說明,通過其默認值可看出,雖然有時候服務已經停止了,但是在註冊中心中還是能看到該服務在線
字段 | 說明 | 默認值 |
---|---|---|
renewalIntervalInSecs | Client端續約的間隔週期 | 30s |
durationInSecs | Client端需要設定的租約效時長 | 90s |
registrationTimestamp | Server端設置的該租約第一次註冊時間 | |
lastRenewalTimestamp | Server端設置的該租約最後一次續約時間 | |
evictionTimestamp | Server端設置的該租約被剔除時間 | |
serviceUpTimestamp | Server端設置的該服務實例標記爲up的時間 |
3.2相關概念
-
Register-服務註冊
當Eureka Client向Eureka Server註冊時,Eureka Client提供自身元數據,比如ip地址、端口、運行狀況指標等
-
Renew-服務續約
(1) Eureka Client默認情況下每隔30秒發送一次心跳來進行服務續約
(2) Eureka Server在90秒內沒收到Eureka Client心跳,則視爲客戶端服務不可用,Eureka Server會將Eureka Client實例從註冊列表中刪除 -
Fetch Registries-獲取服務註冊列表信息
(1) Eureka Client從Eureka Server獲取服務註冊信息,並將其緩存在本地.Eureka Client會使用服務註冊列表信息查找其它服務信息,從而進行遠程調用
(2) 緩存在本地的服務註冊列表定時(每30秒)更新一次,每次返回註冊列表信息可能與Eureka Client緩存信息不同,Eureka Client會自己處理這些信息 -
Cancel-服務下線
(1) Eureka Client在程序關閉時可以向Eureka Server發送下線請求,該客戶端的實例信息將從Eureka Server服務註冊列表中刪除
(2)該下線請求不會自動完成,需在程序中關閉時調用以下代碼DiscoveryManager.getInstance().shutdownComponet
-
Eviction-服務剔除
默認情況下,當Eureka Client連續90秒沒有向Eureka Server發送服務續約時,Eureka Server會將該實例從服務註冊列表剔除
3.3.常見問題
- 爲何Eureka Client獲取服務實例慢
(1) Eureka Client延遲註冊:Eureka Client啓動後,不是立即向Eureka Server註冊的,而是延遲註冊,默認延遲時間爲40秒
(2)Eureka Server響應緩存:Eureka Server維護每30秒更新一次響應緩存
(3) Eureka Client緩存:Eureka Client保留註冊表信息緩存,該緩存每30秒更新一次
(4) LoadBalancer緩存:Ribbon負載均衡器從本地Eureka Client獲取服務註冊列表信息,本身維護緩存,以避免每個請求都從Eureka Client獲取服務註冊列表 - Eureka 的自我保護
(1) 當新Eureka Server出現時,它嘗試從想鄰節點獲取所有服務實例註冊表信息。
(2)當從相鄰節點獲取信息失敗後,Eureka Server會嘗試其它節點
(3) 如果Eureka Server獲取成功所有服務實例信息,則根據配置信息設置服務續約閾值
(4)如果Eureka Server接收到的服務續約低於該閾值(默認15分鐘85%),則服務器開啓自我保護模式,不再剔除註冊表信息
4.註冊中心之Consul
由於Eureka2.0已經閉源,官方只支持開源部份Eureka2.x,且使用效果不做保證,故在此介紹Springcloud整合consul作爲註冊中心,大家不瞭解Consul的,可以先上Consul官網瞭解。在Springcloud官網中將Springcloud consul與其它Springcloud組件並列,可見consul已經得到Spring認可並推薦,剛好在平時工作中使用的是Consul作爲註冊中心,因此在此給大家講介紹下Springcloud整合consul
注意:由於Consul動西必較多,且本次整合不涉及深入瞭解,所以許多理論動西在此省略,大家有興趣的可以自行去官網查看,在此只講解Springcloud如何整合Consul,Consul配置說明
4.1 Consul簡單介紹
1.下圖爲Consul官方文檔圖,該圖展示了Consul結構,有多個數據中心(DataCenter),每個DataCenter中又包括許多節點信息,分別爲Client和Server,其中所有Server中有一個Leader。
2.Clent端負責接受連接請求,但不做持久化數據操作
3.Server端會持久化數據,其它功能與Client端作用類似
4.Server Leader負責數據同步
4.2 docker安裝Consul及啓動
Docker安裝consul可以參考Docker hub介紹Consul安裝,但感覺寫得很模糊,有興趣的童鞋可以看看
- Docker拉取Consul鏡像
# 拉取鏡像
$ docker pull consul
- 啓動server節點
1.consul端口說明
端口 | 說明 |
---|---|
8500 | 用戶客戶端請求端口 |
8600 | 解析DNS查詢 |
8300 | server間通信端口 |
8301 | Serf LAN端口 |
8302 | Serf WAN端口 |
2.consul參數說明
參數 | 說明 |
---|---|
-server | 表示該節點爲server節點,如果不加則默認爲client節點 |
-bootstrap-expect | 表示期望有幾個節點,設置爲3,該集羣未達到3個則該註冊中心無法工作 |
-node | 表示給啓動節點設置別名 |
-datacenter | 表示給數據中心命名,後續節點要加入該集羣,都需設置爲相同數據中心名,否則會啓動失敗 |
-ui | 表示啓動ui界面,可通過瀏覽器訪問 |
-bind | 設置爲0.0.0.0表示對任意主機開放 |
-client | 與bind功能類似,其默認值爲127.0.0.1 |
$ docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 dfe3bf9e6fe6 agent -server -bootstrap-expect 3 -node=n1 -datacenter=st1 -ui -bind=0.0.0.0 -client=0.0.0.0
- 查看server節點ip
$ docker inspect --format ‘{{ .NetworkSettings.IPAddress }}‘ consul1
- 加入server節點
-join:後邊跟要加入的服務節點ip
$ docker run --name consul2 -d -p 8600:8500 dfe3bf9e6fe6 agent -client -node=n2 -datacenter=st1 -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.3
$ docker run --name consul3 -d -p 8700:8500 dfe3bf9e6fe6 agent -client -node=n3 -datacenter=st1 -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.3
4.3 Consul啓動及訪問
1.上述啓動成功後,瀏覽器鍵入
http://192.168.1.100:8500
(ip填寫自己電腦ip)出現如下界面表示Consul安裝並啓動成功
2.st1:表示上述設置的數據中心名
3.n1、n2、n3:表示節點名,也是上邊啓動時設置參數
5. Springcloud整合Consul
經過上邊步驟,我們的docker環境已經安裝上Consul並且啓動成功,下邊我們繼續將consul整合至上邊我們搭建的環境中
5.1 依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-all</artifactId>
</dependency>
上邊依賴爲組合依賴,其實上邊依賴等同於下邊三個依賴,大家使用工具可以看到,大家選擇上邊依賴或下邊依賴均可
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
5.2 配置及說明
- 配置文件設置
在項目的resource目錄新建一配置文件,取名爲
bootstrap.yml
,這兒涉及至springboot啓動時配置文件加載順序問題,這兒就不作過多說明,配置文件如下
spring:
application:
# 服務註冊名
name: order-service
cloud:
consul:
config:
# 設置配置文件夾
prefix: config
# 設置配置文件夾位置
default-context: application
# 設置配置文件名稱
data-key: data
# 設置配置文件顯示樣式,有properties和yaml兩種格式
format: yaml
# 開啓監聽,動態刷新配置,默認每秒觸發一次
watch:
enabled: true
# 修改動態刷新配置時間
# delay: 2000
# 應用和profile之間的分割符,與spring.profiles.active配合使用
# profile-separator: ,
enabled: true
# consul服務器地址
host: 192.168.1.100
# 默認端口號
port: 8500
# 是否註冊,默認爲true
discovery:
register: true
# 健康檢查時間
health-check-timeout: 2m
enabled: true
heartbeat:
enabled: true
# 優先ip註冊
prefer-ip-address: true
instance-id: ${spring.application.name}:${spring.cloud.client.hostname}:${spring.application.instance_id:${server.port}}
參數說明:
參數名 | 說明 | 說明或默認值 |
---|---|---|
spring.loud.config.prefix | 配置文件夾前綴名 | config |
spring.loud.config.default-context | 配置文件夾位置 | application |
spring.loud.config.data-key | 配置文件名稱 | data |
spring.loud.config.format | 配置文件以何種方式展 | 默認key_valu,還有properties、yaml、files |
spring.loud.config.watch.enable | 開啓監聽動態刷新配置 | true |
spring.loud.config.watch.delay | 動態刷新配置時間 | 1000 |
spring.loud.config.enabld | 允許配置 | true |
spring.loud.config.host | 註冊中心ip | localhost |
spring.loud.config.port | 註冊中心i端口 | 8500 |
spring.loud.config.discovery.register | 是否將服務註冊至註冊中心 | true |
spring.loud.config.discovery.health-check-timeout | 心跳檢測超時時間 | |
spring.loud.config.discovery.enabled | 允許服務被發現 | |
spring.loud.config.discovery.heartbeat.enabled | 允許服務心跳檢測 | |
spring.loud.config.discovery.prefer-ip-address | 優先ip註冊 | false |
spring.loud.config.discovery.instance-id | 唯一的實例id,即服務註冊id |
注意:spring.loud.config.discovery.heartbeat.enabled在配置時一定要配置,在實驗中,未配置時服務能註冊進註冊中心但心跳檢測始終失敗,導致服務不可用,如下圖所示爲服務不可用狀態
- 啓動類添加註解
@EnableDiscoveryClient表示允許服務被發現,啓動時必須添加該註解
@SpringBootApplication
@EnableDiscoveryClient
@RefreshScope
public class OrderServerApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServerApplication.class, args);
}
}
5.3 啓動及訪問
1.配置成功後,瀏覽器鍵入
http://192.168.1.100:8500
出現下圖,表示配置成功
2.能看到已經註冊上的兩個服務分別時order-service
和user-service
3.在health checks處無錯誤,表示服務註冊及心跳檢測正常
- 剔除服務
1.在團隊中經常會遇到註冊至註冊中心,從頁遭成消費消息等情況發生,可通過postman或其它方式剔出服務
2.服務instanceId即爲bootstrap.yml文件配置的spring.cloud.consul.discovery.instanceId
參數
$ put http://192.168.1.100:8500/v1/agent/service/deregister/服務instanceId
5.4 Consul頁面統一配置
- 點擊key/value,選擇
config
,config
爲項目配置文件中spring.loud.config.prefix
配置參數
- 分別爲不同服務設置配置文件,文件夾以
/
結尾,配置文件名爲服務名
- data即爲配置文件中
data-key
配置的名稱
注意:該處配置會覆蓋項目中的application.yml文件,因此如果公有屬性可設置在此處
6. 參考資料
- https://spring.io/projects/spring-cloud
- https://www.consul.io/docs/agent/basics.html
- 《深入理解Spring Cloud與微服務構建》
- 《重新定義Springcloud實戰》