1.為什麼要引入服務註冊中心
1.1 原因
public static final String PAYMENT_SRV_URL = "http://localhost:8001";//硬編碼
微服務所在的IP地址和埠號硬編碼到訂單微服務中,會存在非常多的問題
(1)如果訂單微服務和支付微服務的IP地址或者埠號發生了變化,則支付微服務將變得不可用,需要同步修改訂單微服務中呼叫支付微服務的IP地址和埠號。
(2)如果系統中提供了多個訂單微服務和支付微服務,則無法實現微服務的負載均衡功能。
(3)如果系統需要支援更高的併發,需要部署更多的訂單微服務和支付微服務,硬編碼訂單微服務則後續的維護會變得異常複雜。
所以,在微服務開發的過程中,需要引入服務治理功能,實現微服務之間的動態註冊與發現,從此刻開始我們正式進入SpringCloud實戰。
1.2 註冊中心在SpringCloud體系的位置
2.為什麼不再使用Eureka
2.1 Enreka停更維護
https://github.com/Netflix/eureka/wiki
2.2 註冊中心獨立且和微服務功能解耦
目前主流服務中心,希望單獨隔離出來而不是作為一個獨立微服務嵌入到系統中。
按照Netflix
之前的思路,註冊中心Eureka也是作為一個微服務且需要程式設計師自己開發部署(cloud2020
的教程,eureka需要單獨引入依賴,做為一個服務啟動)。
實際情況,希望微服務和註冊中心分離解耦,註冊中心和業務無關的,不要混為一談。提供類似tomcat一樣獨立的元件,微服務註冊上去使用,是個成品。
.3 阿里巴巴Nacos的崛起
一個整合了Service discovery and configuration management的獨立元件。在配置檔案的持久化上,使用起來比Consul要簡單。後面教程會講解到。
3.Consul簡介
3.1 是什麼
3.1.1 consul官網地址
https://www.consul.io/
3.1.2 What is Consul?
Consul 是一套開源的分散式服務發現和配置管理系統,由HashiCorp
公司用Go語言開發。
提供了微服務系統中的服務治理、配置中心、控制匯流排等功能。這些功能中的每一個都可以根據需要單獨使用,也可以一起使用以構建全方位的服務網格,總之Consul提供了一種完整的服務網格解決方案。它具有很多優點。包括: 基於raft協議,比較簡潔; 支援健康檢查, 同時支援HTTP
和DNS
協議支援跨資料中心的 WAN叢集,提供圖形介面 跨平臺,支援 Linux、Mac、Windows。
https://developer.hashicorp.com/consul/docs/intro
3.1.3 禁止使用問題
HashiCorp是一家非常知名的基礎軟體提供商,很多人可能沒聽過它的名字,但是其旗下的6款主流軟體,Terraform、Consul、Vagrant、Nomad、Vault,Packer 相信不少程式設計師都聽說或使用過,尤其是Consul使用者不盡其數。截止目前為止,從HashiCorp官網上的宣告來看,開源專案其實還是“安全”的,被禁用的只是Vault企業版(並且原因是Vault產品目前使用的加密演算法在中國不符合法規,另一方面是美國出口管制法在涉及加密相關軟體上也有相應規定。因此這兩項原因使得HashiCorp不得不在宣告中說明風險)而非其他所有開源產品(Terraform、Consul等)。因此,大家可以暫時放下心來,放心使用!
3.1.4 Spring Cloud Consul
https://docs.spring.io/spring-cloud-consul/reference/index.html
3.2 能幹嘛
3.2.1 服務發現
提供HTTP和DNS兩種發現方式。
3.2.2 健康檢測
支援多種方式,HTTP,TCP,Docker,Shell指令碼定製化監控。
3.2.3 KV儲存
Key,Value的儲存方式。
3.2.4 多資料中心
Consul多資料中心
3.2.5 視覺化WEB介面
3.3 下載地址
https://developer.hashicorp.com/consul/install
3.4 快速開始
https://docs.spring.io/spring-cloud-consul/reference/quickstart.html
4.下載並執行Consul
下載,注意選擇版本,和對應作業系統,以及如果是,Windows下的CPU架構。
找到下載檔案,移動到合適的目錄,解壓即可,因為是一個可執行的consul.exe檔案
#檢視版本資訊,注意在consul.exe目錄下執行
D:\Develop\consul>consul -version
開發者模式啟動
D:\Develop\consul>consul agent -dev
透過http://localhost:8500,訪問頁面
5.服務註冊與發現
5.1 服務提供者8001
支付服務provider8001註冊進consul
5.1.1 引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<exclusions>
<!--這個因為包含了多餘的日誌依賴,這個是排除的。否則控制檯,會有警告資訊。-->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
為什麼這麼引入,見官網。
5.1.2 配置檔案修改
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
5.1.3 主啟動
@EnableDiscoveryClient註解,開啟服務發現(作為一個服務,註冊到consul,也可以從consul中,獲取其他服務的ip和埠資訊)。
5.2 服務消費者80
5.2.1 引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<exclusions>
<!--這個因為包含了多餘的日誌依賴,這個是排除的。否則控制檯,會有警告資訊。-->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
5.2.2 修改配置
server:
port: 8080
spring:
application:
name: cloud-consumer-order
####Spring Cloud Consul for Service Discovery
cloud:
consul:
host: localhost
port: 8500
discovery:
prefer-ip-address: true #優先使用服務ip進行註冊
service-name: ${spring.application.name}
5.2.3 主啟動
@EnableDiscoveryClient註解,開啟服務發現。
5.2.4 Controller類修改
@RestController
@RequestMapping("/consumer")
public class OrderController {
//public static final String PAYMENT_SRV_URL = "http://localhost:8001";//硬編碼
public static final String PAYMENT_SRV_URL = "http://cloud-payment-service";//服務註冊中心上的微服務名稱
@Resource
private RestTemplate restTemplate;
...
}
5.2.5 啟動測試
略
5.2.6 修改RestTemplateConfig類
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced//新增的,因為註冊中心 ,必須要有負載均衡。
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
5.3 註冊中心異同點
5.3.1 CAP理論
C:Consistency(強一致性)
A:Availablility(可用性)
P:Partition tolerance(分割槽容錯性)
5.3.2 經典CAP圖
中介軟體,一般能支援CAP中的兩項特性,就不錯了。
5.3.3 AP(Eureka/Nacos)
AP架構
當網路分割槽出現後,為了保證可用性,系統B可以返回舊值,保證系統的可用性。
當資料出現不一致時,雖然A, B上的註冊資訊不完全相同,但每個Eureka節點依然能夠正常對外提供服務,這會出現查詢服務資訊時如果請求A查不到,但請求B就能查到。如此保證了可用性但犧牲了一致性結論:違背了一致性C的要求,只滿足可用性和分割槽容錯,即AP。
5.3.4 CP(Zookerper/Consul)
CP架構
當網路分割槽出現後,為了保證一致性,就必須拒接請求,否則無法保證一致性,Consul 遵循CAP原理中的CP原則,保證了強一致性和分割槽容錯性,且使用的是Raft演算法,比zookeeper使用的Paxos演算法更加簡單。雖然保證了強一致性,但是可用性就相應下降了,例如服務註冊的時間會稍長一些,因為 Consul 的 raft 協議要求必須過半數的節點都寫入成功才認為註冊成功 ;在leader掛掉了之後,重新選舉出leader之前會導致Consul 服務不可用。結論:違背了可用性A的要求,只滿足一致性和分割槽容錯,即CP。
6.服務配置與重新整理
6.1 分散式系統面臨的->配置問題
微服務意味著要將單體應用中的業務拆分成一個個子服務,每個服務的粒度相對較小,因此係統中會出現大量的服務。由於每個服務都需要必要的配置資訊才能執行,所以一套集中式的、動態的配置管理設施是必不可少的。比如某些配置檔案中的內容大部分都是相同的,只有個別的配置項不同。就拿資料庫配置來說吧,如果每個微服務使用的技術棧都是相同的,則每個微服務中關於資料庫的配置幾乎都是相同的,有時候主機遷移了,我希望一次修改,處處生效。
當下我們每一個微服務自己帶著一個application.yml,上百個配置檔案的管理....../(ㄒoㄒ)/~~
6.2 官網說明
Consul可作為註冊中心和配置中心。
作為配置中心介紹。
6.3 服務使用配置中心
既然可以使用全域性配置資訊,直接註冊進Consul伺服器,從Consul獲取。但是要遵守Consul的配置規則要求。
6.3.1 引入依賴
<!--SpringCloud consul config-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
為什麼需要引入註冊中心,和bootstrap依賴。見官網
6.3.2 修改配置
Consul配置規則說明
You can change the data key using spring.cloud.consul.config.data-key
.可以使用該屬性key修改配置檔案和其分組間使用的分隔符。
例如Consul中預設','作為分隔符,application,dev.yml 設定了屬性為'-' ,就可以使用該方式,application-dev.yml。
新增bootstrap.yml配置檔案
applicaiton.yml
是使用者級的資源配置項。
bootstrap.yml
是系統級的,優先順序更加高。
Spring Cloud會建立一個“Bootstrap Context”,作為Spring應用的Application Context
的父上下文。初始化的時候,Bootstrap Context
負責從外部源載入配置屬性並解析配置。這兩個上下文共享一個從外部獲取的Environment
。
Bootstrap
屬性有高優先順序,預設情況下,它們不會被本地配置覆蓋。 Bootstrap context
和Application Context
有著不同的約定,所以新增了一個bootstrap.yml
檔案,保證Bootstrap Context
和Application Context
配置的分離。
applicaiton.yml
檔案改為bootstrap.yml
,這是很關鍵的或者兩者共存。因為bootstrap.yml
是比applicaiton.yml
先載入的。bootstrap.yml
優先順序高於applicaiton.yml
。yml
和properties
只是檔名字尾,以及配置是,相同字首的key是否省略不同(寫法上),優先順序方面無區別。
6.3.3 配置檔案內容
bootstrap.yml
spring:
application:
name: cloud-payment-service
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
config:
profile-separator: '-' # default value is ",",we update '-'
format: YAML
applicaiton.yml
server:
port: 8001
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: xxx
password: xxx
profiles:
active: # 多環境配置載入內容dev/prod,不寫就是預設default配置
# ========================mybatis===================
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.atguigu.cloud.entities
configuration:
map-underscore-to-camel-case: true
6.3.4 consul伺服器Key/Value配置填寫
1.參考規則
config/cloud-payment-service/data //沒寫就是預設default
config/cloud-payment-service-dev/data
config/cloud-payment-service-prod/data
2.建立config資料夾,以/結尾
開啟,consul的web管理介面,Key/value選單,Create按鈕新建即可。
3.在config資料夾下建立其他3個資料夾,以/結尾
4.在上述3個資料夾下分別建立data內容,data不再是資料夾
6.3.5 測試配置中心配置的方法
@Value("${server.port}")
private String port;
@GetMapping(value = "/get/info")
private String getInfoByConsul(@Value("${info}") String info) {//要和data檔案中寫入的配置資訊相同
return "Info: " + info + "\t" + "port: " + port;
}
透過修改application.yml裡面的啟用配置部分,進行內容的驗證。
6.3.6 測試
略
6.3.7 使用ConfigUtil靜態獲取系統配置的類
一般情況下,開發時,都會使用一個工具類靜態的獲取系統配置,見博文。
6.4 動態重新整理
在周陽老師影片中,修改了data中的配置內容,不會立刻刷洗,但是我學習,操作過程中,會自動重新整理,且不用配置或者,在主啟動類上加@RefreshScope
註解。
周洋老師影片中,需要在主啟動類,加@RefreshScope
註解,修改spring.cloud.consul.config.watch.wait-time
配置,改項配置預設值是55秒。
6.5 思考
存在問題,在Key/Value新增的配置,在consul重啟後,就沒了。Consul的配置持久化...
只是為了記錄自己的學習歷程,且本人水平有限,不對之處,請指正。