更新時間:2020-03-19 來源:傳智播客 瀏覽量:
1、微服務(wù)架構(gòu)
目前微服務(wù)是非常火的架構(gòu)或者說概念,也是在構(gòu)建大型互聯(lián)網(wǎng)項(xiàng)目時采用的架構(gòu)方式。
1.1 單體架構(gòu)
在軟件設(shè)計(jì)中,經(jīng)常提及和使用經(jīng)典的3層模型,即表示層、業(yè)務(wù)邏輯層和數(shù)據(jù)訪問層。
·表示層:用于直接和用戶交互,也稱為交互層,通常是網(wǎng)頁、UI 等。
·業(yè)務(wù)邏輯層:即業(yè)務(wù)邏輯處理層,例如用戶輸入的信息要經(jīng)過業(yè)務(wù)邏輯層的處理后,才能展現(xiàn)給用戶。
·數(shù)據(jù)訪問層:用于操作數(shù)據(jù)庫,用戶在表示層會產(chǎn)生大量的數(shù)據(jù),通過數(shù)據(jù)訪問層對數(shù)據(jù)庫進(jìn)行讀寫操作。
雖然在軟件設(shè)計(jì)中劃分了經(jīng)典的3層模型,但是對業(yè)務(wù)場景沒有劃分。一個典型的單體應(yīng)用就是將所有的業(yè)務(wù)場景的表示層、業(yè)務(wù)邏輯層和數(shù)據(jù)訪問層放在一個工程中,最終經(jīng)過編譯、打包,部署在一臺服務(wù)器上。
單體架構(gòu)圖如下所示:
1.1.1 單體架構(gòu)的優(yōu)點(diǎn)·部署簡單由于是完整的結(jié)構(gòu)體,可以直接部署在一個服務(wù)器上即可。
·技術(shù)單一 項(xiàng)目不需要復(fù)雜的技術(shù)棧,往往一套熟悉的技術(shù)棧就可以完成開發(fā)。
·用人成本低 單個程序員可以完成業(yè)務(wù)接口到數(shù)據(jù)庫的整個流程。
1.1.2 單體架構(gòu)的缺點(diǎn)
·系統(tǒng)啟動慢 , 一個進(jìn)程包含了所有的業(yè)務(wù)邏輯,涉及到的啟動模塊過多,導(dǎo)致系統(tǒng)的啟動、重啟時間周期過長
·系統(tǒng)錯誤隔離性差、可用性差,任何一個模塊的錯誤均可能造成整個系統(tǒng)的宕機(jī)·可伸縮性差;系統(tǒng)的擴(kuò)容只能只對這個應(yīng)用進(jìn)行擴(kuò)容,不能做到對某個功能點(diǎn)進(jìn)行擴(kuò)容
·線上問題修復(fù)周期長;任何一個線上問題修復(fù)需要對整個應(yīng)用系統(tǒng)進(jìn)行全面升級
1.2 微服務(wù)架構(gòu)
就目前來看微服務(wù)并沒有一個 嚴(yán)格 的定義 每一個人對 微服務(wù) 的理解都是不一樣的 . Martin Fowler在它的博客中是這樣表述微服務(wù)的
博客地址 : https://martinfowler.com/articles/microservices.html
微服務(wù)架構(gòu)風(fēng)格是一種將一個單一應(yīng)用程序開發(fā)為一組小型服務(wù)的方法每一個服務(wù)運(yùn)行在自己的進(jìn)程中服務(wù)間通信采用的輕量級通信機(jī)制通(常用HTTP 資源 API ). 這些服務(wù)圍繞業(yè)務(wù)能力構(gòu)建并且可通過全自動部署機(jī)制獨(dú)立部署這些服務(wù)公用一個最小型的集中式的管理服務(wù)可用不同的語言開發(fā),使用不同的數(shù)據(jù)存儲技術(shù)。
微服務(wù)架構(gòu)架構(gòu)如如下圖所示下圖所示:
·易于開發(fā)和維護(hù):一個微服務(wù)只會關(guān)注一個特定的業(yè)務(wù)功能,所以它業(yè)務(wù)清晰、代碼量少。開發(fā)和維護(hù)單個微服務(wù)相當(dāng)簡單。而整個應(yīng)用是若干個微服務(wù)構(gòu)建而成的,所以整個應(yīng)用也被維持在一個可控狀態(tài)。
·單個微服務(wù)啟動較快 單個微服務(wù)代碼量較少,所以啟動會比較快。
·局部修改容易部署:單個應(yīng)用只要有修改,就得重新部署整個應(yīng)用,微服務(wù)解決了這樣的問題。一般來說,對某個微服務(wù)進(jìn)行修改,只需要重新部署這個服務(wù)即可。
·技術(shù)棧不受限:在微服務(wù)架構(gòu)中,可以結(jié)合項(xiàng)目業(yè)務(wù)及團(tuán)隊(duì)的特點(diǎn),合理選擇技術(shù)棧。例如某些服務(wù)可以使用關(guān)系型數(shù)據(jù)庫Mysql有些服務(wù)??梢允褂梅顷P(guān)系型數(shù)據(jù)庫如redis;甚至可根據(jù)需求,部分微服務(wù)使用Java開發(fā),部分微服務(wù)使用Node.js開發(fā)。
·按需收縮可根據(jù)需求,實(shí)現(xiàn)細(xì)粒度的擴(kuò)展。例如,系統(tǒng)中的某個微服務(wù)遇到了瓶頸,可以結(jié)合這個微服務(wù)的業(yè)務(wù)特點(diǎn),增加內(nèi)存、升級CPU或者增加節(jié)點(diǎn)。
1.2.2 微服務(wù)的缺點(diǎn)
·運(yùn)維要求較高: 更多的服務(wù)意味著更多的運(yùn)維投入。在單體架構(gòu)中,只需要保證一個應(yīng)用的正常運(yùn)行。而在微服務(wù)中,需要保證幾十甚至幾百個服務(wù)正常運(yùn)行與協(xié)作,這給運(yùn)維帶來了很大的挑戰(zhàn)。
·分布式固有的復(fù)雜性:使用微服務(wù)構(gòu)建的是分布式 系統(tǒng)。對于一個分布式系統(tǒng),系統(tǒng)容錯、網(wǎng)絡(luò)延遲等都會帶來巨大的挑戰(zhàn)。
·接口調(diào)整成本高:微服務(wù)之間通過接口進(jìn)行通信。如果修改某一個微服務(wù) API ,可能所有使用該接口的微服務(wù)都需要調(diào)整。
2、Spring Cloud 簡介
2.1 簡介
Spring Cloud項(xiàng)目的官方網(wǎng)址: https://projects.spring.io/spring-cloud/
Spring Cloud并不是一個項(xiàng)目而是一組項(xiàng)目的集合在Spring Cloud中包含了很多的子項(xiàng)目每一個子項(xiàng)目都是一種微服務(wù)開發(fā)過程中遇到的問題的一種解決方案它利用Spring Boot的開發(fā)便利性巧妙地簡化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開發(fā),如服務(wù)發(fā)現(xiàn)注冊、配置中心、消息總線、負(fù)載均衡、斷路器、數(shù)據(jù)監(jiān)控等,都可以用Spring Boot的開發(fā)風(fēng)格做到一鍵啟動和部署。Spring Cloud并沒有重復(fù)制造輪子,它只是將目前各家公司開發(fā)的比較成熟、經(jīng)得起實(shí)際考驗(yàn)的服務(wù)框架組合起來,通過Spring Boot風(fēng)格進(jìn)行再封裝屏蔽掉了復(fù)雜的配置和實(shí)現(xiàn)原理,最終給開發(fā)者留出了一套簡單易懂、易部署和易維護(hù)的分布式系統(tǒng)開發(fā)工具包。
2.2 子項(xiàng)目介紹
當(dāng)我們通過搜索引擎查找一些Spring Cloud 的文章或者示例的時候往往可以在依賴中看到很多不同版本的名字 , 比如 : Angel.SR6, Brixton.SR5等。 那么,為什么 Spring Cloud 沒有像其他的 Spring 的項(xiàng)目使用類似1.x.x 版本命名規(guī)則呢?
由于Spring Cloud不像Spring社區(qū)其他項(xiàng)目那樣相對獨(dú)立,它是擁有諸多子項(xiàng)目的大型綜合項(xiàng)目??梢哉f是對微服務(wù)架構(gòu)解決方案的綜合套件的組合,起包含的各個子項(xiàng)目也都是進(jìn)行獨(dú)立的更新和迭代,各自都維護(hù)自己的發(fā)布版本號。因此,每一個Spring Cloud的版本都會包含多個不同版本的子項(xiàng)目,為了管理每一個版本的子項(xiàng)目清單避免Spring Cloud的版本號與其子項(xiàng)目的版本號相混淆,沒有采用版本號的方式,而是通過命名的方式。
我們也可以在spring的官網(wǎng)上查看到對應(yīng)的最新穩(wěn)定版本信息 : https://projects.spring.io/spring-cloud/
并且也可以看到最新Edgware.SR4穩(wěn)定版對應(yīng)的子項(xiàng)目的各個版本號。關(guān)于Spring Cloud的歷史版本信息我們可以在github上查看到 : https://github.com/spring-cloud/spring-cloud/release/releases我們本次講解的是最新的穩(wěn)定版本Edgware.SR4 ,是基于Spring Boot 1.5.14.RELEASE版本實(shí)現(xiàn)的。
3、Spring Boot 實(shí)現(xiàn)微服務(wù)
業(yè)務(wù)非常簡單:
1、商品微服務(wù):通過商品id 查詢商品的服務(wù);2、訂單微服務(wù):通過訂單id 查詢訂單數(shù)據(jù),同時需要調(diào)用商品微服務(wù)查詢出訂單詳情數(shù)據(jù)對應(yīng)的商品數(shù)據(jù)。
3.1 實(shí)現(xiàn)商品微服務(wù)
3.1.1 pom .xml文件的配置
3.1.3 編寫ItemService
3.1.4 編寫ItemController
3.1.5 程序入口
3.1.6 創(chuàng)建配置文件
指定服務(wù)啟動占用的端口
3.1.7 啟動項(xiàng)目進(jìn)行訪問
3.2 實(shí)現(xiàn)訂單微服務(wù)
3.2.1 pom.xml文件的配置
3.2.3 創(chuàng)建實(shí)體OrderDetail
3.2.4 復(fù)制Item實(shí)體
3.2.6 實(shí)現(xiàn)ItemService
3.2.8 編寫OrderController
3.2.10 創(chuàng)建配置文件
在src/main/resources 目錄下創(chuàng)建一個application.properties 配置文件在該文件中可以配置如下內(nèi)容
server.port=8082
3.2.11 啟動測試
3.3 發(fā)現(xiàn)問題與解決問題
3.3.1 問題描述
·在剛才的服務(wù)調(diào)用過程中我們的商品服務(wù)地址是直接寫死在程序中存在硬編碼問題
·如果商品微服務(wù)部署了多個,那么我們訂單微服務(wù)如何去調(diào)用呢?
3.3.2 問題處理
關(guān)于硬編碼的問題我們可以使用配置文件處理,我們可以將地址信息編寫到配置文件中然后讀取配置文件獲取請求地址信息。
在配置文件中加入如下配置:itcast.item.url=http://127.0.0.1:8081/item/修改ItemService的實(shí)現(xiàn)通過@Value 注解獲取該值2. 如果商品微服務(wù)部署了多個那么我們訂單微服務(wù)如何去調(diào)用呢?關(guān)于這個問題有的開發(fā)人員可能會想 . 我們可以將多個商品微服務(wù)的地址配置到配置文件中,然后在進(jìn)行讀取配置文件的地址進(jìn)行調(diào)用聽起來好像可以,但是我們需要考慮以后問題就是后期維護(hù)的問題。
·如果商品微服務(wù)的我們又添加或者減少了一個部署,相應(yīng)的我們需要去更改配置文件的內(nèi)容;
·如果商品微服務(wù)的ip地址發(fā)送了改變,那么我們也需要相應(yīng)的修改配置文件的地址。
所以我們自己這樣實(shí)現(xiàn)比較麻煩。
我們可以使用服務(wù)注冊于發(fā)現(xiàn)機(jī)制來完成。
由上圖可以看出:
1、服務(wù)提供者將服務(wù)注冊到注冊中心
2、服務(wù)消費(fèi)者通過注冊中心查找服務(wù)
3、查找到服務(wù)后進(jìn)行調(diào)用(這里就是無需硬編碼 url 的解決方案)
4.1 注冊中心 Eureka
Spring Cloud提供了多種注冊中心的支持,如: Eureka 、 ZooKeeper 等。推薦使用Eureka 。
Spring Cloud Eureka是Spring Cloud Netflix 微服務(wù)套件中的一部分,它基于Netflix Eureka做了二次封裝。主要負(fù)責(zé)完成微服務(wù)架構(gòu)中的服務(wù)治理功能。
原理如下圖所示
Eureka包含兩個組件: Eureka Server 和 Eureka Client 。
Eureka Server 提供服務(wù)注冊服務(wù),各個節(jié)點(diǎn)啟動后,會在 Eureka Server中進(jìn)行注冊,這樣 EurekaServer中的服務(wù)注冊表中將會存儲所有可用服務(wù)節(jié)點(diǎn)的信息,服務(wù)節(jié)點(diǎn)的信息可以在界面中直觀的看到。
Eureka Client是一個java 客戶端,用于簡化與 Eureka Server的交互在應(yīng)用啟動后,將會向Eureka Server發(fā)送心跳默認(rèn)周期為 30 秒,如果 Eureka Server在多個心跳周期內(nèi)沒有接收到某個節(jié)點(diǎn)的心跳,Eureka Server將會從服務(wù)注冊表中把這個服務(wù)節(jié)點(diǎn)移除默認(rèn) 90 秒 。
Eureka Server之間通過復(fù)制的方式完成數(shù)據(jù)的同步,Eureka還提供了客戶端緩存機(jī)制,即使所有的Eureka Server都掛掉,客戶端依然可以利用緩存中的信息消費(fèi)其他服務(wù)的 API 。綜上,Eureka通過心跳檢查、客戶端緩存等機(jī)制,確保了系統(tǒng)的高可用性、靈活性和可伸縮性。
啟動類
4.2.3 配置文件
4.2.4 啟動程序訪問服務(wù)端
訪問地址 : http://localhost:6868/
4.3 商品微服務(wù)注冊到注冊中心
接下來,我們需要將商品的微服務(wù)注冊到Eureka服務(wù)中。
4.3.1 修改pom文件
引入Spring Cloud的管理依賴以及Eureka服務(wù)依賴。
4.3.3 修改啟動類
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient // 聲明這是 Eureka 的客戶端
@SpringBootApplication // 聲明這是一個 Spring Boot 項(xiàng)目
public class ItemApplication {
public static void main(String[] args) {SpringApplication.run(ItemApplication.class, args);
}}4.5.4 Eureka的高可用
前面的測試,我們會發(fā)現(xiàn),Eureka服務(wù)是一個單點(diǎn)服務(wù),在生產(chǎn)環(huán)境就會出現(xiàn)單點(diǎn)故障,為了確保Eureka服務(wù)的高可用,我需要搭建Eureka服務(wù)的集群。
搭建Eureka集群非常簡單,只要啟動多個Eureka服務(wù)并且讓這些服務(wù)之間彼此進(jìn)行注冊即可實(shí)現(xiàn)。
修改itcast microservice eureka的application.properties配置文件
可以看到,2個Eureka服務(wù)進(jìn)行了彼此注冊
4.5.5 將服務(wù)注冊到 Eureka集群中