SpringCloud
一、微服務概述
1.什麼是微服務?
微服務(Microservice Architecture) 是近幾年流行的一種架構思想
通常而言,微服務架構是一種架構模式,或者說是一種架構風格,它将單一的應用程式劃分成一組小的服務,每個服務運作在其獨立的自己的程序内,服務之間互相協調,互相配置,為使用者提供最終價值,服務之間采用輕量級的通信機制(HTTP)互相溝通,每個服務都圍繞着具體的業務進行建構,并且能狗被獨立的部署到生産環境中,另外,應盡量避免統一的,集中式的服務管理機制,對具體的一個服務而言,應該根據業務上下文,選擇合适的語言,工具(Maven)對其進行建構,可以有一個非常輕量級的集中式管理來協調這些服務,可以使用不同的語言來編寫服務,也可以使用不同的資料存儲。
再來從技術次元角度了解下:
微服務化的核心就是将傳統的一站式應用,根據業務拆分成一個一個的服務,徹底地去耦合,每一個微服務提供單個業務功能的服務,一個服務做一件事情,從技術角度看就是一種小而獨立的處理過程,類似程序的概念,能夠自行單獨啟動或銷毀,擁有自己獨立的資料庫。
2.微服務與微服務架構
傳統架構
将所有的業務邏輯代碼全部都放入在同一個jar包中,沒有實作解耦,
如果中間有一個小的子產品,引發當機的情況下,會導緻整個系統無法使用。
微服務
強調的是服務的大小,它關注的是某一個點,是具體解決某一個問題/提供落地對應服務的一個服務應用,狹義的看,可以看作是IDEA中的一個個微服務工程,或者Moudel。IDEA 工具裡面使用Maven開發的一個個獨立的小Moudel,它具體是使用SpringBoot開發的一個小子產品,專業的事情交給專業的子產品來做,一個子產品就做着一件事情。強調的是一個個的個體,每個個體完成一個具體的任務或者功能。
微服務架構
一種新的架構形式,Martin Fowler 于2014年提出。
微服務架構是一種架構模式,它體長将單一應用程式劃分成一組小的服務,服務之間互相協調,互相配合,為使用者提供最終價值。每個服務運作在其獨立的程序中,服務與服務之間采用輕量級的通信機制**(如HTTP)互相協作,每個服務都圍繞着具體的業務進行建構,并且能夠被獨立的部署到生産環境中,另外,應盡量避免統一的,集中式的服務管理機制,對具體的一個服務而言,應根據業務上下文,選擇合适的語言、工具(如Maven)**對其進行建構
3.微服務優缺點
優點
單一職責原則;
每個服務足夠内聚,足夠小,代碼容易了解,這樣能聚焦一個指定的業務功能或業務需求;
開發簡單,開發效率高,一個服務可能就是專一的隻幹一件事;
微服務能夠被小團隊單獨開發,這個團隊隻需2-5個開發人員組成;
微服務是松耦合的,是有功能意義的服務,無論是在開發階段或部署階段都是獨立的;
微服務能使用不同的語言開發;
易于和第三方內建,微服務允許容易且靈活的方式內建自動部署,通過持續內建工具,如jenkins,Hudson,bamboo;
微服務易于被一個開發人員了解,修改和維護,這樣小團隊能夠更關注自己的工作成果,無需通過合作才能展現價值;
微服務允許利用和融合最新技術;
微服務隻是業務邏輯的代碼,不會和HTML,CSS,或其他的界面混合;
每個微服務都有自己的存儲能力,可以有自己的資料庫,也可以有統一的資料庫;
可以實作解耦、如果某子系統當機的情況下,不會影響其他的子系統,适合于多團隊人數實作開發。
缺點
開發人員要處理分布式系統的複雜性;
多服務運維難度,随着服務的增加,運維的壓力也在增大;
系統部署依賴問題;
服務間通信成本問題;
資料一緻性問題;
系統內建測試問題;
性能和監控問題;
部署比較複雜的、開發難度比較大、需要有團隊溝通成本。
二、SpringCloud入門概述
1.SpringCloud和SpringBoot的關系
SpringBoot專注于友善的開發單個個體微服務;
SpringCloud是關注全局的微服務協調整理治理架構,它将SpringBoot開發的一個個單體微服務,整合并管理起來,為各個微服務之間提供:配置管理、服務發現、斷路器、路由、為代理、事件總棧、全局鎖、決策競選、分布式會話等等內建服務;
SpringBoot可以離開SpringCloud獨立使用,開發項目,但SpringCloud離不開SpringBoot,屬于依賴關系;
SpringBoot專注于快速、友善的開發單個個體微服務,SpringCloud關注全局的服務治理架構;
2.為什麼我們要使用SpringCloud
SpringCloud并不是rpc遠端調用架構,而是一套全家桶的微服務解決架構,理念就是解決我們在微服務架構中遇到的任何問題。
服務治理:eureka
分布式配置:config
用戶端調用工具rest/feign用戶端 rpc遠端調用
3.SpringCloud第一代與第二代的差別

Spring Cloud Alibaba實際上對SpringCloud實作了拓展元件能夠完美整合到SpringCloud rpc遠端調用整合。
1、nacos分布式注冊中心,分布式配置中心SpringCloud Eureka+Config組合
2、目的是為了推廣阿裡雲産品,如果使用了Spring Cloud Alibaba建議最好使用Alibaba Mq rocketmq
總結:Spring Cloud Alibaba實際上對我們的SpringCloud做拓展元件開發naoocs、setata分布式解決架構、scheduler、Alibaba Cloud OSS等目的推廣阿裡雲産品。
三、nacos
服務注冊與發現
Nacos 分布式注冊與發現功能|分布式配置中心
官網的介紹: https://nacos.io/zh-cn/docs/what-is-nacos.html
1.傳統的rpc遠端調用中存在哪些問題
1)逾時的問題
2)安全的問題
3)服務與服務之間URL位址管理
在我們微服務架構通訊,服務之間依賴關系非常大,如果通過傳統的方式管理我們服務的url位址的情況下,一旦位址發生變化的情況下,還需要人工修改rpc遠端調用位址。
每個服務的url管理位址發出複雜,是以這是我們采用服務url治理技術,可以實作對我們整個實作動态服務注冊與發現、本地負載均衡、容錯等。
2.服務治理概念:
在RPC遠端調用過程中,服務與服務之間依賴關系非常大,服務Url位址管理非常複雜,是以這時候需要對我們服務的url實作治理,通過服務治理可以實作服務注冊與發現、負載均衡、容錯等。
2.1.基于資料庫形式實作服務url治理
把每個伺服器位址資訊和端口人工存放到資料庫表中
缺點:維護成本非常高、沒有完全絕對實作動态智能
2.2.微服務中的注冊中心
整個微服務架構中最為核心的肯定是 注冊中心。
每次調用該服務如果位址直接寫死的話,一旦接口發生變化的情況下,這時候需要重新釋出版本才可以該接口調用位址,是以需要一個注冊中心統一管理我們的服務注冊與發現。
**2.2.1.注冊中心:**實際就是存放我們的服務的位址資訊,能夠實作動态感覺。我們的服務注冊到我們注冊中心,key為服務名稱、value為該服務調用位址,該類型為集合類型。
例:Dubbo依賴Zookeeper、Eureka、Consul、Nacos、Redis、資料庫
**2.2.2.服務注冊:**我們生産者項目啟動的時候,會将目前服務自己的資訊位址注冊到注冊中心。
2.2.3.服務發現: 消費者從我們的注冊中心上擷取生産者調用的位址(集合),在使用負載均衡的政策擷取叢集中某個位址實作本地rpc遠端調用。
3.Nacos的環境的準備
Nacos可以在linux/windows/Mac版本上都可以安裝
具體安裝教程位址:https://nacos.io/zh-cn/docs/quick-start.html
實作服務發現:http://127.0.0.1:8848/nacos/
賬号:nacos 密碼:nacos
4.Nacos整合SpringCloud
Maven依賴資訊
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<!-- springboot 整合web元件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
</dependencies>
配置檔案
application.yml檔案
spring:
cloud:
nacos:
discovery:
###服務注冊位址
server-addr: 127.0.0.1:8848
application:
name: xinzhi-member
server:
port: 8081
4.3.建立生産者
服務接口
@RestController
public class MemberService {
@Value("${server.port}")
private String serverPort;
/**
* 會員服務提供的接口
*
* @param userId
* @return
*/
@RequestMapping("/getUser")
public String getUser(Integer userId) {
return "欣知,端口号:" + serverPort;
}
}
進行代碼測試,自動實作對服務進行注冊
4.4.消費者
@RestController
public class OrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private LoadBalancer loadBalancer;
/**
* 訂單調用會員服務
*
* @return
*/
@RequestMapping("/orderToMember")
public String orderToMember() {
// 從注冊中心上擷取該注冊服務清單
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("mayikt-member");
ServiceInstance serviceInstance = loadBalancer.getSingleAddres(serviceInstanceList);
URI rpcMemberUrl = serviceInstance.getUri();
// 使用本地rest形式實作rpc調用
String result = restTemplate.getForObject(rpcMemberUrl + "/getUser", String.class);
return "訂單調用會員擷取結果:" + result;
}
}
負載均衡算法
負載均衡算法有哪些
A、一緻性hash計算
B、輪訓、權重
C、随機
公式:通路次數%叢集size
5.Nacos與其他注冊對比分析
5.1.CAP定律
這個定理的内容是指的是在一個分布式系統中、Consistency(一緻性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可得兼。
一緻性(C)
在分布式系統中的所有資料備份,在同一時刻是否同樣的值。(等同于所有節點通路同一份最新的資料副本)
可用性(A)
在叢集中一部分節點故障後,叢集整體是否還能響應用戶端的讀寫請求。(對資料更新具備高可用性)
分區容錯性(P)
以實際效果而言,分區相當于對通信的時限要求。系統如果不能在時限内達成資料一緻性,就意味着發生了分區的情況,必須就目前操作在C和A之間做出選擇。
采用:
Cp情況下 雖然我們服務不能用,但是必須要保證資料的一緻性
Ap情況下 可以短暫保證資料不一緻性,但是最終可以一緻性,不管怎麼樣,要能夠保證我們的服務可用
大多的注冊中心都是Ap
5.2.Nacos對比Zookeeper、Eureka之間的差別
Eureka與Zookeeper
相同點:都可以實作分布式服務注冊中心
**不同點:**Zookeeper采用CP保證資料的一緻性的問題,原理采用Zab原子廣播協定,當我們的zk上司因為某種原因當機的情況下,會自動觸發重新選一個新的上司角色,整個選舉的過程為了保證資料的一緻性問題,在選舉的過程中整個zk環境是不可使用的可短暫可能無法使用到zk。意味着微服務采用該模式情況下,可能無法實作通訊(本地有緩存除外)
注意:可運作的節點必須滿足過半機制,整個zk采用使用。
Eureka采用ap的設計理念架構注冊中心,完全去中心化思想,也就是沒有主從之分
每個節點都是均等,采用互相注冊的原理,你中有我我中有你,隻要最後有一個eureka節點存在就可以保證整個微服務可以實作通訊。
我們在使用注冊中心,可用性在優先級最高,可以讀取資料短暫不一緻性,但是至少要能夠保證注冊中心可用性。
中心化 必須圍繞一個上司角色作為核心,選舉上司和跟随者角色
去中心化 每個角色都是均等
Nacos與Eureka差別
1、Eureka采用ap模式形式實作注冊中心
2、Nacos預設采用AP模式。在1.0版本之後采用ap+cp模式混合實作注冊中心。
最大差別:Nacos支援兩種模式CP/Ap模式 從Nacos1.0版本開始 注意模式就是Ap模式
6.Nacos的叢集部署
Nacos 核心幫助我們做的事情注冊中心、分布式配置中心
注冊中心 沒有必要将資料持久化到資料庫中,可以持久化到本都的硬碟。
分布式配置中心 預設是将資料持久化到本地嵌入式的資料庫改為持久化到myql中
**注意事項:**Nacos在不同版本下運作叢集是不一樣
在linux版本中運作的時候預設是叢集模式,如果需要改為單機啟動修改配置
- nacos在windows版本下運作預設是單機版本 需要指定startup.cmd -m cluster
- nacos在linux版本下運作預設是叢集版本 如果想連接配接單機版本 startup.cmd –m standalone
步驟:
1.建立cluster檔案夾
---nacos-server-8848
---nacos-server-8849
---nacos-server-8850
2.cluster.conf
### ip和端口号
192.168.18.224:8848
192.168.18.224:8849
192.168.18.224:8850
3.Nginx相關配置
4.用戶端連接配接
spring:
application:
###服務的名稱
name: xinzhi-nacos-client
cloud:
nacos:
discovery:
###nacos注冊位址
server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
enabled: true
config:
###配置中心連接配接位址
server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
###分組
group: DEFAULT_GROUP
###類型
file-extension: yaml
7.Nacos的資料持久化
資料持久化
7.1.預設的情況下,分布式配置中心的資料存放到本地data目錄下,但是這種情況如果nacos叢集的話無法保證資料的同步性。
7.2.在0.7版本增加了支援mysql資料源能力,具體的操作步驟:
1、安裝資料庫,版本要求:5.6.5+
2、初始化mysql資料庫,資料庫初始化檔案:nacos-mysql.sql
3、修改conf/application.properties檔案,增加支援mysql資料源配置(目前隻支援mysql),添加mysql資料源的url、使用者名和密碼。
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root
相當于配置檔案資料源,統一放到資料庫中。
8.分布式配置中心
8.1.分布式配置中心産生的背景
在項目中定義配置檔案,最大的缺陷:
如果在生産環境正在運作的時候突然需要修改配置檔案的話,必須重新開機我們的伺服器。
8.2.分布式配置中心的架構有哪些:
攜程的阿波羅、Nacos(屬于輕量級)、SpringCloud Config(沒有界面)、攜程的阿波羅(屬于比較重的分布式配置)/disConfig等。
8.3.輕量級與重量級分别表示什麼意思?
輕量級:部署、架構設計原理都比較簡單,學習成本也是比較低:
重量級:部署、架構設計、體量都是非常大,學習成本是比較高。
8.6.分布式配置中心實作原理:
1、本地應用讀取我們雲端分布式配置中心檔案(第一次建立長連接配接)
2、本地應用讀取到配置檔案之後,本地jvm和硬碟中都會緩存一份。
3、本地應用與分布式配置中心伺服器端一緻保持長連接配接。
4、當我們的配置檔案發生變化(MD5|版本号)實作區分,将變化的結果通知給我們的本地應用實時的重新整理我們的配置檔案。
完全百分百實作動态化修改我們的配置檔案。
注意:Nacos分布式配置中心和注冊中心都部署在同一個應用,就是一個單體的應用。
8.7.分布式配置中心的作用
分布式配置中心可以實作不需要重新開機我們的伺服器,動态的修改我們的配置檔案内容。
8.8.基于Nacos實作分布式配置中心
伺服器端
在Naocs平台中建立配置檔案
名稱:(預設為伺服器名稱)-版本.properties|yaml;
用戶端
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
建立一個bootstrap.yml
spring:
application:
###服務的名稱
name: meitemayikt-nacos-client
cloud:
nacos:
discovery:
###nacos注冊位址
server-addr: 127.0.0.1:8848
enabled: true
config:
###配置中心連接配接位址
server-addr: 127.0.0.1:8848
###分組
group: DEFAULT_GROUP
###類型
file-extension: yaml
@RestController
@SpringBootApplication
@RefreshScope
public class NacosController {
@Value("${mayikt.name}")
private String userName;
@RequestMapping("/getConfig")
public String getConfig() {
return userName;
}
public static void main(String[] args) {
SpringApplication.run(NacosController.class);
}
}
可以實作動态實作@RefreshScope;可以對配置内容進行監聽,察覺到内容被編輯之後會立刻重新整理,而不用重新開機伺服器。
注意:連接配接nacos分布式配置中心一定采用bootstrap形式優先加載 否則可能會錯。
bootstrap.yml 用于應用程式上下文的引導階段。
application.yml 由父Spring ApplicationContext加載。
多版本控制
分别在nacos伺服器端建立
xinzhi-nacos-client-dev.yaml
xinzhi-nacos-client-prd.yaml
用戶端指定讀取版本:profiles active: prd
* 1、如何使用Nacos作為配置中心統一管理配置
*
* 1)、引入依賴,
* <dependency>
* <groupId>com.alibaba.cloud</groupId>
* <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
* </dependency>
* 2)、建立一個bootstrap.properties。
* spring.application.name=gulimall-coupon
* spring.cloud.nacos.config.server-addr=127.0.0.1:8848
* 3)、需要給配置中心預設添加一個叫 資料集(Data Id)gulimall-coupon.properties。預設規則,應用名.properties
* 4)、給 應用名.properties 添加任何配置
* 5)、動态擷取配置。
* @RefreshScope:動态擷取并重新整理配置
* @Value("${配置項的名}"):擷取到配置。
* 如果配置中心和目前應用的配置檔案中都配置了相同的項,優先使用配置中心的配置。
*
* 2、細節
* 1)、命名空間:配置隔離;
* 預設:public(保留白間);預設新增的所有配置都在public空間。
* 1、開發,測試,生産:利用命名空間來做環境隔離。
* 注意:在bootstrap.properties;配置上,需要使用哪個命名空間下的配置,
* spring.cloud.nacos.config.namespace=9de62e44-cd2a-4a82-bf5c-95878bd5e871
* 2、每一個微服務之間互相隔離配置,每一個微服務都建立自己的命名空間,隻加載自己命名空間下的所有配置
*
* 2)、配置集:所有的配置的集合
*
* 3)、配置集ID:類似檔案名。
* Data ID:類似檔案名
*
* 4)、配置分組:
* 預設所有的配置集都屬于:DEFAULT_GROUP;
* 1111,618,1212
*
* 項目中的使用:每個微服務建立自己的命名空間,使用配置分組區分環境,dev,test,prod
*
* 3、同時加載多個配置集
* 1)、微服務任何配置資訊,任何配置檔案都可以放在配置中心中
* 2)、隻需要在bootstrap.properties說明加載配置中心中哪些配置檔案即可
* 3)、@Value,@ConfigurationProperties。。。
* 以前SpringBoot任何方法從配置檔案中擷取值,都能使用。
* 配置中心有的優先使用配置中心中的,