前言
今天是9月17日,趁着山竹的臨幸,得以在家里舒適的辦公。項目從3月底開始,至今剛好半年。抽幾十分鍾,總結下半年的歷程。對后面的項目,應該也有一點幫助吧。
學習前的七個問題
項目開始前,由於某些特殊的原因,對spring cloud一無所知(甚至聽都沒聽過,希望這種情況今后不再出現),所以我用手機的markdown軟件Lite馬上記錄了7個疑問。我相信,不知道多少天后,這些疑問看起來將多么的可笑,呵呵。
- 這是一個什么樣的技術框架,用來做什么的
- 和他相似的還有什么?各自優劣勢?從什么框架發展而來?是否有后續新框架?
- 如何使用?
- 如何搭建
- 和spring什么關系?和springmvc什么關系?
6.什么樣的系統應該用它?什么不應該用? - 最常用功能是哪些
定一個目標(學習后)
項目結束后,檢查學會了哪些問題。
學習過程
- 3月19號星期一開始,到今天4月15號,已經四個星期了,即是一個月了。
- 4.30,發現很多疑問,特別架構上。
- 7.22,基本沒有什么疑問了,就是有一些報錯不知道怎么解決。
時間過得真快
4.30總結一些問題
微服務
- 一個系統怎么划分模塊?也就是怎么划分server?
- 怎么划分一個服務?也就是rest api?
- 唯一流水號怎么生成
- 分布式事務怎么實現?還是說同一個事務的代碼都寫在一個服務里?
- 和領域驅動開發有什么關系或者聯系
- 內部是否需要一個客戶端,進行連接貫穿幾個服務的處理,然后再提供rest給外部調用
Spring cloud
- 內部調用服務,eureka輪詢的機制是啥?
- 效率如何?與直接調用本地方法差多少?
- @Transactional加在controller還是service
- 服務調用超時的話如何進行處理,會不會導致整個服務都用不了?
- 是不是應該一個外部接口一個容器?還是說同一個外圍系統的接口都放在一個容器?還是說可以將所有的外部接口都放在一個容器
- 同一個方法被不同的模塊共用,應該怎么處理
代碼
- base64
- Uuid
- @Transactional
- threadlocal
- spring cloud代碼目錄結構
- Spring boot代碼目錄結構
- 是否需要vo、dto、bo、do、po
- 是否需要一個貫穿流程的類
- 邏輯寫在數據庫語句好還是寫在代碼里好
- 是否一個服務一個類, service dao都分開
- dao mapper什么區別
7.22總結一些問題
- 前面兩大類的問題基本解決,第三類最后一來代碼的問題的確有一些疑問還沒有解決還不知道。
- 連接重置報錯怎么解決
- 連接沒有http返回報錯怎么解決
- 數據庫連接失敗報錯怎么解決
- 任務調度,批處理應該用什么,怎么寫
- 令牌應該怎么生成
9.17解答問題
概念問題
- 這是一個什么樣的技術框架,用來做什么的
- 微服務框架,用來提供微服務框架的常用功能,包括服務注冊、服務網關、分布式配置等。
- 和他相似的還有什么?各自優劣勢?從什么框架發展而來?是否有后續新框架?
- 相似的有dubbo、kibernate等。
- dubbo用rpc,快一點,但不怎么更新;kibernate大而全,但好像與開源社區比較遠離。
- 基於springboot開發,集成了很快框架,包括Netflix里的eureka、ribbon、zuul等,spring自己也弄了很多,網關后面也不用zuul了,用自己的spring cloud gateway。
- 如何使用?
- 對於業務開發者,就是開發restful api,開發業務,寫controller、service、dao,與平常使用springboot開發沒什么區別。有一些小區別可能就是要學一下Feign怎么調用、怎么讀取config的配置(其實也是用spring的特性來讀取),但是遇到難題,就需要對spring cloud有深入了解了。
- 對於搭建框架的,需要搭建zuul、config、eureka這些基本的,如果有需要,還需要看情況搭建zipkin、oauth2、elk
- 如何搭建
- 搭建其實需要寫的代碼很少,主要是配置pom,引入相關的starter,然后配置application或者Bootstrap文件。
- 和spring什么關系?和springmvc什么關系?
- 基於springboot,但其實springboot並沒有太多東西,只是弄了一堆starter簡化開發,內嵌了servlet容器等等。開發代碼其實主要還是要懂spring開發,@RestController、@Configuration、@Bean、@GetMapping、@Transactional、@RestTemplate、@ComponentScan、@Retryalbe、@Cacheable等等這些技術,其實還是spring的技術。
6.什么樣的系統應該用它?什么不應該用? - 需要用到微服務的,都可以用它。那什么系統需要微服務?這是一個大話題,只要不是很小的系統,而又不想做成龐大的單體應用,希望可以降低運維難度的,都可以考慮使用。
- 太小的系統,沒必要用。已經運行的好好的單體系統,沒有遷移的錢,也不要用。喜歡weblogic、jboss這些商用軟件,不喜歡開源的也不要用(現在這種觀點越來越少了把)。不是微服務的,也不要用,比如要做頁面展示。不是企業級應用的,可能也不適合,比如要做一個壓縮軟件。
- 基於springboot,但其實springboot並沒有太多東西,只是弄了一堆starter簡化開發,內嵌了servlet容器等等。開發代碼其實主要還是要懂spring開發,@RestController、@Configuration、@Bean、@GetMapping、@Transactional、@RestTemplate、@ComponentScan、@Retryalbe、@Cacheable等等這些技術,其實還是spring的技術。
- 最常用功能是哪些
- 服務注冊、分布式配置、api網關這三個是必須的。如果這三個都不用,也沒必要用啥springcloud了。不是太簡單的鏈路,sleuth也是需要的。安全、feign那些看需要吧。如果搞企業級,task、batch那些也可能用到。畢竟后台處理大量數據。
用了之后的問題
- 一個系統怎么划分模塊?也就是怎么划分server?
- 按領域划分。但其實很難,最簡單可以按數據庫划分。
- 怎么划分一個服務?也就是rest api?
- 一個server-service是一個微服務。微服務里很多RESTful的api,只要可以封裝為對外或者對內調用的一個完整的功能的都可以是一個api。但考慮到事務,也不要操作一張表就一定弄成一個api。
- 唯一流水號怎么生成
- 分布式中,最簡單的用uuid
- 但uuid很長,很亂,無序,不好看,不好查,很多缺點
- 最好還是搭建一個生成器,需要依賴mongodb或者redis這些分布式nosql
- 分布式事務怎么實現?還是說同一個事務的代碼都寫在一個服務里?
- 沒有現成的成熟框架,目前。不像oracle、tuxedo有xa等事務機制。
- 一般同一個事務寫在一個服務,但涉及多個數據庫,需要通過自己寫代碼或者公司寫一個框架封裝保證最終事務一致性。
- 和領域驅動開發有什么關系或者聯系
- 很有關系。但大部分同事不懂,也很難落實,在國內目前。
- 內部是否需要一個客戶端,進行連接貫穿幾個服務的處理,然后再提供rest給外部調用
- 這確實是一個不錯的方案。client對外提供api,server端對內提供。
繼續關於Spring cloud的。
- 內部調用服務,eureka輪詢的機制是啥?
- 有很多種,可以配置。原理是用了ribbon的機制,默認是輪詢(round)
- 效率如何?與直接調用本地方法差多少?
- 不經過網關,效率還是可以的。但畢竟跨了主機,淡然是調用本地的方法快一點,但分布式嘛,這點損耗可以接收。
- @Transactional加在controller還是service
- 99%的書都是建議在service,但是引起的問題的需要維護的開發人員非常小心修改前人的代碼
- 不像之前用商用軟件,可以隨便改,都是保證在一個事務
- 但微服務嘛,本來就應該簡單,既然簡單的,事務也不會太復雜
- 服務調用超時的話如何進行處理,會不會導致整個服務都用不了?
- zuul和spring都有Retryalbe機制
- 預防雪崩的話,spring cloud有熔斷機制,可配置熔斷規則。
- 是不是應該一個外部接口一個web容器?還是說同一個外圍系統的接口都放在一個容器?還是說可以將所有的外部接口都放在一個容器
- 其實這個問題很奇怪。一個容器肯定就是一個完整的微服務。
- 掉不調用外圍系統,只是系統內的一個功能,也就是一個service的一個方法,要調用幾個外圍系統,根本沒有關系,所以也就沒什么要放在單獨的容器了
- 如果怕調用過程中,超時導致tomcat默認的200個線程全部占滿,完全可以啟用熔斷機制解決。
- 如果為了解耦,確實可以單獨出去一個微服務,比如是接口微服務,專門調外圍系統,但是真的有必要嗎?除非外圍系統比較多,跟這個數據庫又沒什么關聯的話。
- 同一個方法被不同的模塊共用,應該怎么處理
- 千萬不要把代碼拷貝過去!
- 可以封裝成rest,互相調用
- 也可以封存成公用的jar,來調用
- 如果只是1、2行代碼,拷貝一下,也未嘗不可
- 如果以上三種方法都不合適,那要思考一下,你的模塊划分是不是出了問題?
下午要上班了,剩余的以后補充。
這半年還學了很多別的東西,看了很多書,后面的博客再分享。
也會把代碼(非業務的)放到gitee分享出來。
bye
