始學(xué)習(xí)java spring cloud(八))
用豆包輔助從頭開(kāi)始學(xué)習(xí)java spring cloud八昨天學(xué)習(xí)了redis的一些基本操作今天學(xué)習(xí)以理論為主學(xué)習(xí)架構(gòu)理論 RESTful API 規(guī)范。第一部分架構(gòu)演進(jìn)1.單體架構(gòu)所有功能全部卸載一個(gè)springboot工程里面以商城為例用戶(hù)、訂單、支付、商品全部在一起一份代碼、一個(gè)包一套數(shù)據(jù)庫(kù)。這種架構(gòu)的優(yōu)點(diǎn)就是開(kāi)發(fā)簡(jiǎn)單部署簡(jiǎn)單小項(xiàng)目效率高。但是缺點(diǎn)也非常明顯1.代碼量大模塊耦合嚴(yán)重改其中一處容易牽連其他功能2.全部功能公用一個(gè)實(shí)例當(dāng)某一個(gè)功能壓力大的時(shí)候需要整體擴(kuò)容不能單獨(dú)給高壓力部分?jǐn)U容3.所有人在一個(gè)代碼庫(kù)開(kāi)發(fā)代碼沖突頻繁4.一個(gè)模塊出現(xiàn)了漏洞整個(gè)應(yīng)用可能就宕機(jī)了。所以也就限制了這類(lèi)項(xiàng)目的適用范圍小型項(xiàng)目?jī)?nèi)部管理系統(tǒng)。tips耦合就是兩個(gè)功能模塊之間綁的太緊密了當(dāng)a模塊小小改動(dòng)b模塊也跟著受影響。生活化的類(lèi)比一下高耦合計(jì)算機(jī)一體機(jī)顯示器、內(nèi)存、cpu、顯卡、風(fēng)扇、電源整體焊死在一塊板子上當(dāng)其中不論是內(nèi)存或是顯示器或是電源存在一點(diǎn)損壞整臺(tái)計(jì)算機(jī)一起報(bào)廢低耦合臺(tái)式計(jì)算機(jī)組裝機(jī)現(xiàn)在的品牌臺(tái)式計(jì)算機(jī)也大多如此顯卡壞了只需要把顯卡換掉其他部件依舊正??梢允褂酶鱾€(gè)部件通過(guò)接口插在一起。為了解決這個(gè)問(wèn)題解耦開(kāi)始進(jìn)行項(xiàng)目拆分出現(xiàn)了項(xiàng)目拆分。2.垂直拆分多個(gè)單體把大的單體項(xiàng)目按照業(yè)務(wù)類(lèi)別拆分成多個(gè)獨(dú)立的單體項(xiàng)目以商城為例用戶(hù)系統(tǒng)、訂單系統(tǒng)分成獨(dú)立系統(tǒng)各自部署。特點(diǎn)是各個(gè)項(xiàng)目代碼完全隔離可以單獨(dú)擴(kuò)容某一個(gè)業(yè)務(wù)模塊問(wèn)題是服務(wù)和服務(wù)之間調(diào)用很麻煩沒(méi)有統(tǒng)一的服務(wù)治理數(shù)據(jù)可能存在重復(fù)。3.SOA面向服務(wù)架構(gòu)把公共能力抽離成服務(wù)其他業(yè)務(wù)系統(tǒng)調(diào)用服務(wù)出現(xiàn)了ESB企業(yè)服務(wù)總線(xiàn)所有服務(wù)的交互都從總線(xiàn)走。特點(diǎn)是公共服務(wù)的復(fù)用能力好缺點(diǎn)是ESB總線(xiàn)很重配置復(fù)雜粒度依然偏大適合傳統(tǒng)企業(yè)。tips1ESBEnterprise Service Bus企業(yè)服務(wù)總線(xiàn)在SOA架構(gòu)里面的核心組件想象成一條中央總線(xiàn)網(wǎng)所有的服務(wù)不直接互相調(diào)用全部接入這條ESB總線(xiàn)。當(dāng)服務(wù)A需要調(diào)用服務(wù)B時(shí)請(qǐng)求發(fā)送給ESB由ESB做轉(zhuǎn)發(fā)、協(xié)議轉(zhuǎn)換、鑒權(quán)、日志、數(shù)據(jù)格式轉(zhuǎn)換、再轉(zhuǎn)給服務(wù)B。好處就是所有服務(wù)都有ESB管控缺點(diǎn)是ESB本身是一個(gè)龐大的、獨(dú)立的軟件部署維護(hù)麻煩配置繁瑣所有服務(wù)必須經(jīng)過(guò)ESBESB癱瘓時(shí)成為整個(gè)系統(tǒng)的瓶頸點(diǎn)。2粒度粒度就是拆分出來(lái)的服務(wù)的大小粒度大指的就是一個(gè)服務(wù)里面包含了許許多多的業(yè)務(wù)服務(wù)需要做的事很多相反的粒度小指的是一個(gè)服務(wù)職責(zé)單一只做一小塊業(yè)務(wù)。SOA時(shí)代基于ESB拆分出來(lái)的服務(wù)不夠細(xì)以商城舉例只拆分出電商業(yè)務(wù)、會(huì)員服務(wù)其中電商業(yè)務(wù)里面同時(shí)包含了商品、訂單、庫(kù)存等一大堆的業(yè)務(wù)這就是粒度大粒度小就拆成更多、更小、職責(zé)更單一的服務(wù)。以SOA為基礎(chǔ)進(jìn)一步演進(jìn)為微服務(wù)架構(gòu)。4.微服務(wù)架構(gòu)把系統(tǒng)拆分成粒度更小、高度自治的業(yè)務(wù)服務(wù)。每一個(gè)微服務(wù)獨(dú)立開(kāi)發(fā)、獨(dú)立部署、獨(dú)立數(shù)據(jù)庫(kù)服務(wù)之間通過(guò)HTTP/RPC遠(yuǎn)程調(diào)用通信。?微服務(wù)優(yōu)點(diǎn)獨(dú)立擴(kuò)容哪個(gè)服務(wù)壓力大就只擴(kuò)容哪個(gè)服務(wù)技術(shù)異構(gòu)不同服務(wù)可以選用適合自己的技術(shù)棧局部故障隔離訂單服務(wù)掛掉不會(huì)直接導(dǎo)致用戶(hù)服務(wù)不可用團(tuán)隊(duì)解耦不同團(tuán)隊(duì)維護(hù)不同微服務(wù)代碼互不干擾?微服務(wù)缺點(diǎn)復(fù)雜度大幅上升不再是本地方法調(diào)用變成遠(yuǎn)程網(wǎng)絡(luò)調(diào)用引入一堆組件注冊(cè)中心、配置中心、網(wǎng)關(guān)、分布式事務(wù)、鏈路追蹤運(yùn)維成本暴漲需要容器、監(jiān)控、日志分布式帶來(lái)新問(wèn)題網(wǎng)絡(luò)超時(shí)、數(shù)據(jù)一致性問(wèn)題重要認(rèn)知微服務(wù)不是萬(wàn)能神器不是項(xiàng)目一用上所有問(wèn)題自動(dòng)全部解決小業(yè)務(wù)不要強(qiáng)行上微服務(wù)tips1.SOA、微服務(wù)是軟件架構(gòu)設(shè)計(jì)的思想是一套架構(gòu)方案是架構(gòu)演進(jìn)概念和具體代碼框架不綁定2.Spring Boot是開(kāi)發(fā)框架用來(lái)快速開(kāi)發(fā)Java應(yīng)用的工具微服務(wù)里的每個(gè)服務(wù)是可以使用Spring Boot開(kāi)發(fā)出來(lái)的3.Spring Cloud是微服務(wù)的整套解決方案、是實(shí)現(xiàn)微服務(wù)的組件集合是建立在Spring Boot基礎(chǔ)之上的Spring Boot開(kāi)發(fā)每個(gè)服務(wù)Spring Cloud提供微服務(wù)的配套組件比如Nacos 注冊(cè)中心、網(wǎng)關(guān)、分布式鎖、分布式事務(wù)等。第二部分微服務(wù)拆分原則1.**按業(yè)務(wù)域拆分最核心**圍繞業(yè)務(wù)能力而不是按技術(shù)層拆分。?錯(cuò)誤拆法把所有 controller 抽一個(gè)服務(wù)所有 service 抽一個(gè)服務(wù)。?正確拆法用戶(hù)域、訂單域、商品域一個(gè)業(yè)務(wù)域作為一個(gè)微服務(wù)。2.單一職責(zé)一個(gè)微服務(wù)只負(fù)責(zé)自己業(yè)務(wù)域的事情。3.高內(nèi)聚低耦合域內(nèi)功能盡量?jī)?nèi)聚服務(wù)之間盡量少依賴(lài)。4.數(shù)據(jù)私有微服務(wù)盡量不要跨庫(kù)直接訪(fǎng)問(wèn)別人的表通過(guò)接口拿數(shù)據(jù)。第三部分RESTful API 接口規(guī)范這個(gè)部分內(nèi)容在我們之前學(xué)習(xí)代碼的時(shí)候部分使用過(guò)下面學(xué)習(xí)一下基礎(chǔ)理論。核心思想U(xiǎn)RL 代表「資源」HTTP Method請(qǐng)求方式代表「動(dòng)作」。URL 里面盡量不要寫(xiě)動(dòng)詞不要寫(xiě)getXXX / addXXX / deleteXXX。資源系統(tǒng)里的實(shí)體用戶(hù)、訂單、商品、購(gòu)物車(chē)都叫資源。1、HTTP 方法與語(yǔ)義方法含義使用場(chǎng)景示例 URLGET查詢(xún)獲取數(shù)據(jù)不修改服務(wù)器數(shù)據(jù)GET /users查詢(xún)?nèi)坑脩?hù)GET /users/{id}根據(jù) id 查單個(gè)用戶(hù)POST新增創(chuàng)建新資源POST /users新增一個(gè)用戶(hù)PUT全量更新把對(duì)象完整覆蓋更新所有字段都傳PUT /users/{id}修改 id 對(duì)應(yīng)的用戶(hù)DELETE刪除刪除資源DELETE /users/{id}刪除指定用戶(hù)PATCH局部更新只傳要修改的部分字段項(xiàng)目實(shí)際用的少PATCH /users/{id}只修改 agetipsGET 請(qǐng)求不能做新增、修改、刪除GET 會(huì)被瀏覽器緩存、日志記錄用來(lái)改數(shù)據(jù)會(huì)產(chǎn)生安全問(wèn)題。2、URL 命名規(guī)范資源用名詞復(fù)數(shù)優(yōu)先/users、/orders、/goods獲取單個(gè)資源/users/1路徑放 id子資源訂單下面的明細(xì)GET /orders/1001/items查詢(xún) 1001 號(hào)訂單的所有訂單項(xiàng)禁止帶有動(dòng)作的命名如/getUserById?id1,/addUser,/updateUser,/delUser,動(dòng)作是要交給對(duì)應(yīng)類(lèi)的方法去執(zhí)行的違背了REST思想tipsREST 思想Representational State Transfer表述性狀態(tài)轉(zhuǎn)移用資源為中心通過(guò) HTTP 標(biāo)準(zhǔn)方法完成對(duì)資源的操作不需要額外自定義動(dòng)作。3、請(qǐng)求參數(shù)我想細(xì)心的朋友可能會(huì)注意到我們放問(wèn)某些網(wǎng)頁(yè)的時(shí)候網(wǎng)址會(huì)出現(xiàn)、這樣的符號(hào)下面詳細(xì)學(xué)習(xí)一下1.路徑變量pathVariable資源唯一標(biāo)識(shí)寫(xiě)在 url 路徑上GET /users/11 是用戶(hù) id。2.query 查詢(xún)參數(shù)? 后面過(guò)濾、分頁(yè)、排序如GET /users?pageNum1pageSize10age20,分頁(yè)、篩選條件放在?后面不要寫(xiě)到路徑里。3.body 請(qǐng)求體POST、PUT新增 / 修改時(shí)JSON 放 BodyGET 請(qǐng)求不要使用 body很多網(wǎng)關(guān)、瀏覽器會(huì)丟棄 GET 的 body。4、返回?cái)?shù)據(jù)規(guī)范1.使用統(tǒng)一返回體就是我們 common 模塊寫(xiě)的ResultT2.集合查詢(xún)data 返回?cái)?shù)組分頁(yè)返回 data 里面包含列表 總條數(shù)。3.異常場(chǎng)景全局異常處理器統(tǒng)一捕獲依然返回 Result 格式 JSON不要返回 html 錯(cuò)誤頁(yè)面。5.HTTP 狀態(tài)碼語(yǔ)義REST 建議200 OK查詢(xún)、修改成功201 CreatedPOST 新增資源成功400 Bad Request參數(shù)錯(cuò)誤404 Not Found訪(fǎng)問(wèn)的資源不存在500 Internal Server Error服務(wù)內(nèi)部異常實(shí)際開(kāi)發(fā)很多項(xiàng)目 http 狀態(tài)碼統(tǒng)一返回 200業(yè)務(wù)錯(cuò)誤放到 code 字段里面就是我們 Result 的 code兩種都可以團(tuán)隊(duì)保持統(tǒng)一即可。6、舉一套完整用戶(hù) CRUD REST 示例查詢(xún)?nèi)坑脩?hù)GET /users查詢(xún)單個(gè)用戶(hù)GET /users/2新增用戶(hù)POST /usersbody 傳 json全量修改用戶(hù)PUT /users/2body 完整用戶(hù) json刪除用戶(hù)DELETE /users/27.無(wú)狀態(tài)**每一次 HTTP 請(qǐng)求服務(wù)器不保存客戶(hù)端會(huì)話(huà)狀態(tài)。**每個(gè)請(qǐng)求自帶全部需要信息token、參數(shù)服務(wù)端不用記住上一次請(qǐng)求。好處服務(wù)端更容易擴(kuò)容、集群壞處每次請(qǐng)求都要帶上身份憑證 token。7、現(xiàn)實(shí)開(kāi)發(fā)注意點(diǎn)RESTful 是設(shè)計(jì)思想不是強(qiáng)制法律很多公司會(huì)做折中。如果業(yè)務(wù)動(dòng)作不是簡(jiǎn)單增刪改查例如用戶(hù)登錄、導(dǎo)出沒(méi)有合適 HTTP 方法允許 URL 帶動(dòng)詞POST /users/login這種屬于合理妥協(xié)。RESTful API遵循 REST 思想寫(xiě)出來(lái)的接口。REST 是思想RESTful 是遵循這套思想的實(shí)踐產(chǎn)物。簡(jiǎn)單 CRUD 嚴(yán)格遵守特殊業(yè)務(wù)動(dòng)作可以妥協(xié)。第四部分電商系統(tǒng)如何做微服務(wù)拆分這是一道思考題大家可以先自行思考再往下看我們先思考一下參照現(xiàn)在的電商系統(tǒng)想象一下電商系統(tǒng)需要的模塊1.首先是用戶(hù)注冊(cè)、登錄、用戶(hù)信息、地址信息等用戶(hù)相關(guān)的2.登錄之后開(kāi)始查看商品對(duì)商品管理的商品信息、分類(lèi)、圖片、商品的上架和下架信息3.查看商品之后考慮是不是要加入購(gòu)物車(chē)購(gòu)物車(chē)的增刪改查以及分類(lèi)下架的商品正常的商品4.不論是不是加入購(gòu)物車(chē)都需要考慮是不是下單也就是訂單的增刪改查包括訂單退貨流程5.下單之后就要對(duì)應(yīng)商品庫(kù)存了商品庫(kù)存的增刪改查6.下單的話(huà)還要考慮支付問(wèn)題是對(duì)接三方支付還是自有支付暫不考慮對(duì)接三方的話(huà)接口的調(diào)用和回調(diào)7.下單之后的物流發(fā)貨、物流軌跡查詢(xún)等。所以對(duì)應(yīng)的拆分思路就是user?service 用戶(hù)服務(wù)注冊(cè)、登錄、用戶(hù)信息、地址管理goods?service 商品服務(wù)商品信息、分類(lèi)、圖片、商品上下架cart?service 購(gòu)物車(chē)服務(wù)購(gòu)物車(chē)增刪改查order?service 訂單服務(wù)創(chuàng)建訂單、訂單狀態(tài)、訂單查詢(xún)stock?service 庫(kù)存服務(wù)商品庫(kù)存扣減、庫(kù)存查詢(xún)pay?service 支付服務(wù)對(duì)接第三方支付支付回調(diào)logistics?service 物流服務(wù)發(fā)貨、物流軌跡查詢(xún)訂單產(chǎn)生和退單過(guò)程都調(diào)用商品服務(wù)商品服務(wù)再去調(diào)用庫(kù)存服務(wù)訂單并發(fā)產(chǎn)生的商品庫(kù)存增減也是事務(wù)問(wèn)題。第五部分小結(jié)今天學(xué)習(xí)了編程思想的演進(jìn)過(guò)程以及接口規(guī)范的做法最后簡(jiǎn)單思考了一下電商系統(tǒng)該如何設(shè)計(jì)拆分服務(wù)。截止當(dāng)前第一階段學(xué)習(xí)完畢明天是對(duì)第一階段的整體回顧考慮到都是各種問(wèn)題就直接羅列在今天學(xué)習(xí)的后面了明天不再單獨(dú)羅列下一次學(xué)習(xí)進(jìn)入第二階段學(xué)習(xí)。問(wèn)題的答案大家自行思考和搜索不再?gòu)?fù)述了第一階段通關(guān)驗(yàn)收清單全部需要可以口述出來(lái)一共 6 大項(xiàng)每一項(xiàng)下面附帶提問(wèn)全部理解清楚才算通關(guān)才能進(jìn)入 第二階段。題目 1 SpringBoot 自動(dòng)配置原理說(shuō)出ConfigurationFull 模式 和 Lite 模式區(qū)別ConditionalOnMissingBean的作用是什么簡(jiǎn)單說(shuō)下 SpringBoot 自動(dòng)配置的加載原理META?INF/spring/org.springframework.boot.autoconfigure.imports題目 2 common 公共模塊RestControllerAdvice ExceptionHandler作用是什么BizException 自定義業(yè)務(wù)異常和通用 RuntimeException處理器如何區(qū)分處理為什么項(xiàng)目拋出異常不能直接返回原生錯(cuò)誤頁(yè)面要統(tǒng)一封裝為 Result 返回題目 3 獨(dú)立單體 SpringBoot MyBatis?PlusMyBatis?Plus 的QueryWrapper條件構(gòu)造器作用是什么::方法引用寫(xiě)法含義MyBatis?Plus 分頁(yè)插件必須配置什么否則分頁(yè) total 總數(shù)不對(duì)Druid 數(shù)據(jù)源作用是什么題目 4 Spring 本地事務(wù)事務(wù) ACID 分別代表什么Transactional(rollbackFor Exception.class)rollbackFor 不加會(huì)有什么坑說(shuō)出 2 種以上事務(wù)失效場(chǎng)景非 public、內(nèi)部 this 調(diào)用、try?catch 吃掉異常以及失效原因題目 5 Redis 緩存三大問(wèn)題緩存穿透現(xiàn)象 解決方案緩存擊穿現(xiàn)象 解決方案緩存雪崩現(xiàn)象 解決方案實(shí)操為什么不能直接把 null 存入 RedisTemplateJackson 序列化坑我們是如何解決緩存穿透的題目 6 架構(gòu)演進(jìn) RESTful 規(guī)范架構(gòu)演進(jìn)路線(xiàn)單體 → 垂直拆分 → SOA → 微服務(wù)每個(gè)階段簡(jiǎn)單特點(diǎn)ESB 是什么SOA 粒度偏大什么意思微服務(wù)優(yōu)點(diǎn)、缺點(diǎn)為什么微服務(wù)不是銀彈微服務(wù)拆分核心原則REST 思想是什么GET/POST/PUT/DELETE 各自語(yǔ)義URL 編寫(xiě)禁忌什么場(chǎng)景可以適度妥協(xié) REST 規(guī)范簡(jiǎn)單說(shuō)電商系統(tǒng)如何做微服務(wù)拆分用戶(hù)、商品、訂單、庫(kù)存、支付…