當我看完《深入了解 Spring Cloud 與微服務構建》的時候,我就打算將所學習到的 Spring Cloud 組件使用到項目中做成一個小項目,加深理解。
項目Github地址:https://github.com/MuggleLee/ManagePlatform
項目簡介:
登錄模塊:
- 賬號登錄
- 微信授權登錄(由于是個體測試者,只能通過關注我個人的測試公眾號才能微信授權,如有需要,可通過微信關注以下公眾號)
- 手機號碼登錄:使用阿里云短信服務。通過帳號登錄后可在頁面右上方綁定手機號碼,以后登錄的話可以直接通過 手機號碼+驗證碼 登錄

管理后臺模塊:
- 菜單管理:菜單列表、添加菜單、修改菜單、刪除菜單、菜單圖標設置
- 角色管理:角色查詢、添加角色、修改角色、刪除角色、分配菜單、分配權限
- 權限管理:權限查詢、添加權限、修改權限、刪除權限
- 用戶管理:用戶查詢、添加用戶、修改用戶、給用戶分配角色、重置密碼
- 文件管理:上傳文件、文件列表、文件刪除
- 郵件管理:發(fā)送郵件、查詢郵件
- 注冊中心:查看微服務注冊情況
- 監(jiān)控中心:監(jiān)控微服務信息
- 接口swagger文檔
- ip黑名單:查詢、添加、刪除ip黑名單
- 日志查詢
- 個人信息修改
- 修改密碼
- 頭像修改
開發(fā)環(huán)境:
系統:Windows10 —— 項目的子項目和運行環(huán)境都通過啟動 Docker 鏡像運行。詳情可查看父項目的 docker-compose.yml 配置
技術實現:
Spring Cloud (Finchley)、Spring Security、JDK8、Maven、Mysql 5.6、Mybatis-Plus、Redis5、Rabbitmq、Docker
項目結構:
├─CommonModel:基礎Model
├─CommonUnits:工具包
├─ConfigCenter:配置中心
├─FileCenter:文件上傳中心
├─GatewayCenter:網關中心
├─LogCenter:日志中心
├─LogStarter:日志配置
├─ManageBackend:門戶中心
├─MonitorCenter:監(jiān)控中心
├─NotificationCenter:通知中心
├─OauthCenter:權限中心
├─RegisterCenter:注冊中心
├─UserCenter:用戶中心
├─buildImage:將所有子項目都打包后構建成鏡像
├─docker-compose.yml:構建容器
├─Starting Sequence.md:查看子項目的啟動順序
技術實現:
Spring Cloud (Finchley)、Spring Security、JDK8、Maven、Mysql 5.6、Mybatis-Plus、Redis5、Rabbitmq、Docker
技術選型:
搭建框架:Spring Boot + Spring Cloud 2.0(Finchley版本)
好處:由于Spring Boot 默認大于配置的原則,可以快速搭建 Spring Cloud 微服務。
注冊中心:Eureka
常用的注冊中心有:Eureka,Zookeeper。那為什么選擇使用 Eureka ?(沒有實際項目支持說法,如有理解錯誤望幫助我改正...)
我覺得有以下幾點:
| Eureka | Zookeeper | |
|---|---|---|
| 集群模式 | peer-to-peer 模式。集群中的 Eureka Server 地位都是相同,服務注冊的時候可以向任意一臺 Eureka Server 注冊,然后會同步服務注冊信息給集群中其它的 Eureka Server | 服務注冊的時候向 ZK 集群中的 Leader 注冊,然后 Leader 會立即同步注冊信息給集群中的其它 Follower。讀取注冊表信息的時候可以向 Leader 或 Follower 讀 |
| CAP | 保證了可用性,犧牲了強一致性。少部分的 Eureka Server 宕機后對整個注冊中心集群的影響小,但有存在注冊表信息不一致的可能。如果 Eureka Server 宕機前獲取到新的注冊信息,但來不及同步信息給集群其他的 Eureka Server 就導致集群獲取不了新的注冊信息 | 保證了強一致性,犧牲了可用性。當 Leader 宕機后,整個注冊中心集群都會阻塞,直到選舉其中一個 Follower 成為 Leader 并保證 Leader 和 Follower 的注冊表信息是一樣的才會恢復正常,期間可能會有一段時間導致整個注冊中心不可用 |
| 時效性 | 如果使用默認配置,注冊信息改動后最糟糕的情況可能需要幾分鐘才會同步注冊中心集群和向注冊中心注冊的所有實例。優(yōu)化配置后也可達到秒級或者10幾秒 | 一般來說,注冊信息改動會秒級的通知整個注冊中心集群和向注冊中心注冊的所有實例 |
| 容量 | 當注冊實例達到幾千數量的時候,都會占用大量的帶寬 | 當注冊實例達到幾千數量的時候,都會占用大量的帶寬 |
ps.常見的服務注冊組件還有 Consul,其屬于 CA,但對此組件了解不多,因此也不作過多解釋...
當前項目我并沒有部署集群,也不必要保證當前的節(jié)點信息是最新的,另外為了能夠與其他 Spring Cloud 組件無縫對接,我選擇使用 Eureka。
配置中心:Config
常見可以作為配置中心的組件還有Spring Cloud 提供的 Config 組件、攜程開源的 Apollo 組件、阿里開源的 Nacos 的組件。
由于都沒有試用過,了解也不深,因此我使用了 Spring Cloud 提供的 Config 組件,因為可以無縫的和其它微服務組件對接。不過以后有時間的話,還是需要了解一下這幾個組件的區(qū)別和優(yōu)缺點才行...
負載均衡調用服務:Feign
常見的負載均衡方式有兩種,一種是客戶端使用 Ribbon 組件,另外一種就是使用類似 Nginx 這樣的服務,啟動獨立進程通過負載均衡策略將請求分配到不同的服務器上。
客戶端使用 Ribbon 組件可以簡單的理解為,將負載均衡的邏輯以代碼的形式封裝到客戶端上,通過客戶端提供的服務注冊表信息就能夠負載均衡的將請求分配到各個服務器上。
在微服務中,多個服務是如何通信呢?常見的可以使用 RestTemplate 類的方法向各個服務通信,注入 RestTemplate 的時候加上 @LoadBalanced 注解就可以結合 Ribbon 達到負載均衡的調用服務了。
在本項目中,我使用了另外一種方式也可以達到負載均衡的調用服務,那就是使用 Feign 組件。Feign 采用了聲明式API接口的風格,將 Java Http 客戶端綁定到內部,這樣就可以遠程調用其它服務了。另外一點就是,Feign 組件默認集成了 Ribbon,這樣的話,調用服務就可以做到負載均衡啦!
網關中心:Zuul
常用的網關有 Nginx、OpenResty、Zuul 和 Spring Cloud Gateway。由于該項目對性能要求不高,所以沒有使用高性能的 Nginx 和 Opensty。
而 Spring Cloud Gateway 作為了官方的網關組件,可以與 Spring Cloud 其它組件無縫對接。但現在網上相關的資料還是相對 Zuul 少。雖然 Zuul 是阻塞式,不支持長連接的,但現在網上的相關資料較多,出了問題還是比較容易找到解決辦法,因此該項目選擇了 Zuul 作為網關組件。
(不過正在考慮接下來將Zuul組件替代為Spring Cloud Gateway,據說配置更簡單...)
斷路器:Hystrix
Spring Cloud 提供了帶有熔斷機制的框架——Hystrix。熔斷器的作用是當某個服務節(jié)點出現故障可以通過快速失敗機制保證其他遠程調用服務不會導致系統卡死。因此在微服務中,熔斷器是十分重要的,而 Spring Cloud 提供的 Hystrix 是當前比較熱門的熔斷器組件。
監(jiān)控中心:Spring Boot Admin
Spring Boot Admin 是一個針對 Spring Boot 的 Actuator 接口進行 UI 美化封裝的監(jiān)控工具??梢栽诹斜碇袨g覽所有被監(jiān)控 Spring Boot 項目的基本信息,詳細的 Health 信息、內存信息、JVM 信息、垃圾回收信息、各種配置信息(比如數據源、緩存列表和命中率)等,還可以直接修改 logger 的 level。
甚至根據監(jiān)控的服務狀況發(fā)送郵件或者短信通知管理員,譬如某個節(jié)點或者某個服務掛了,可以立即通知管理員上線解決問題。
鏈路:Zipkin
Zipkin 是 Twitter 的一個開源項目,致力于分析分布式系統的鏈路數據,提供持久化策略,也提供UI頁面方便開發(fā)人員查看接口,查詢服務之間的調用鏈路信息。
消息隊列:RabbitMQ
常見的消息隊列有 RabbitMQ、RocketMQ、ActiveMQ、Kafka。在實際項目中如何選型呢?這要根據各種 MQ 的特性和使用場景決定。
ActiveMQ維護越來越少,即使出問題也不容易解決;Kafka適合流計算和大數據場景,而且延遲相對RabbitMQ和RocketMQ較高,因此該項目不使用ActiveMQ和Kafka。至于RabbitMQ和RocketMQ的選型上,在本項目中我個人認為沒什么差別,但RabbitMQ提供了非常完善便捷的后臺管理界面,因此我選用RabbitMQ。
| RabbitMQ | RocketMQ | Kafka | ActiveMQ | |
|---|---|---|---|---|
| 使用場景 | 在線業(yè)務場景 | 在線業(yè)務場景 | 大數據和流計算領域 | 在線業(yè)務場景 |
| 社區(qū)活躍度 | 社區(qū)活躍度高 | 活躍的中文社區(qū) | 社區(qū)活躍度高 | 社區(qū)活躍度很低 |
| 優(yōu)點 | 輕量級的消息隊列,非常容易部署和使用,性能穩(wěn)定 | 響應快,能達到ms級的響應 | 擁有強大的性能及吞吐量,兼容性好 | 存在時間長,有大量的參考文檔,可用性高 |
| 缺點 | 性能和吞吐量較差,基于Erlang開發(fā),不易進行二次開發(fā) | 國內流行的消息隊列,相對國外流程的 MQ ,在集成周邊生態(tài)和兼容度會稍微差點 | 延遲比較高 | 社區(qū)活躍度低,維護越來越少 |
數據庫:Mysql5.6
持久層框架:Mybatis-Plus
項目一開始是使用 Mybatis 作為持久層框架,項目完成之后看到一些文章介紹 Mybatis 的升級版——Mybatis-Plus。
打開Mybatis-Plus的官網,最吸引眼球的就是其 slogan ——“為簡化開發(fā)而生”。原先的 Mybatis 框架雖然能夠很靈活的操作 SQL 語句,但弊端是要創(chuàng)建大量的 XML 文件,后期也不容易維護。而Mybatis-Plus不再需要創(chuàng)建XML文件,只需要定義一些接口,直接調用CRUD的方法,也很方便的使用注釋自定義SQL語句,熱加載、代碼生成、分頁、性能分析等功能一應俱全。不僅如此,Mybatis-Plus 還有函數式編程的特性,可以發(fā)現項目中大量的使用 Stream 流,拼裝對象屬性和CRUD不再是幾十行冗長的代碼,而是簡簡單單的幾行甚至一行代碼就能搞掂,大大提高了開發(fā)效率!更多 Mybatis-Plus 使用參考官方。(力推學習!)