構建安全可靠的微服務 | Nacos 在顏鋪 SaaS 平臺的應用實踐
阿新 • • 發佈:2020-04-02
![1.jpeg](https://ucc.alicdn.com/pic/developer-ecology/29d47f2f266944c9a2bbc8341c0a58db.jpeg)
作者 | 殷銘 顏鋪科技架構師
本文整理自架構師成長系列 3 月 19 日直播課程。
關注“阿里巴巴雲原生”公眾號,回覆 **“319”**,即可獲取對應直播回放連結及 PPT 下載連結。
**導讀:**顏鋪科技因美業⽽⽣,“顏鋪專家”是一款專為美業商家打造的 SaaS 平臺,為了能夠給商戶提供更加安全、穩定、高效的平臺,我們在技術方面做了很多嘗試,經過幾次演進,使系統變得更加穩定可靠。今天主要和大家分享一下顏鋪科技的架構演進,以及 Nacos 在顏鋪的應用實踐。
# 單體應用時代
![2.png](https://ucc.alicdn.com/pic/developer-ecology/6931c9353f1b4a63bb9541f445676a15.png)
上圖是我們單體服務時的架構圖,分為會員、訂單、門店等很多模組,看架構圖似乎還算清晰,但是真正看到包結構的時候,真的令人頭禿!改起程式碼特別頭痛。單體服務帶來的幾個挑戰:
- **釋出週期慢:**雖然當時業務量不算大,但是程式碼量很大,業務迭代牽一髮而動全身,每次釋出需要對整個服務進行重新編譯打包部署。特別是最開始在沒有構建工具的時候,釋出過程需要一堆的命令,總有一種 **“一頓操作猛如虎,定睛一看原地杵” **的感覺。
- **協同效率低:**合併衝突多,有時你在前面開心地寫程式碼,而別人在解決衝突時,可能也在開心地刪著你的程式碼,增加了很多的溝通成本。
- **穩定性差:**當服務出現故障時,可能會導致整個系統不可用,並且系統不易擴容,當商戶搞促銷時,可能活動結束了,伺服器還沒有擴容完成。
- **效能差:**因為在單體服務內,有些開發人員為了滿足自己的業務,很多無關業務間 SQL 聯表查詢,並且不關注效能問題,導致線上時常出現負載警告。
另外,我們在業務上也遇到了一些挑戰:
- **業務轉型: **2018 年 6 月,我們公司決定從泛行業轉向美業,需要打造一個專為美業商戶提供技術支援的麗人 SaaS 平臺。
- **快速佔領市場:**業務的轉型帶來了更多商戶的新需求,如果不能快速迭代,則意味著被市場淘汰。因此,提升開發效率,快速佔領市場成為我們急需解決的問題。
- **商戶體驗差:**隨著越來越多的商戶入住,效能和可靠性的問題逐漸顯現,出現問題,不能及時修正,商戶體驗變得很差,違揹我們客戶第一的原則。
**綜上所述,我們認為進行服務化改造刻不容緩。**
# 微服務改造
**經過公司開發同學們的討論,我們最終決定分兩步進行改造:**
**服務化改造 1.0 的目標:**
- 用最小的改造成本先將新、舊商戶平臺進行打通,做到功能上的快速遷移;
- 業務抽象,將新舊商戶中心的公用部分進行抽象,並優化舊商戶中心的程式碼邏輯,為後續的業務中臺建設做好鋪墊。
**服務化改造 2.0 的目標:初步建設業務中臺,讓平臺的各種能力能夠快速複用、快速組合,支援業務更快捷地探索與發展。**
**服務化改造 1.0 預期效果:**
![3.png](https://ucc.alicdn.com/pic/developer-ecology/090f8ac42f5a47bcb3cb32453e196f83.png)
- 我們希望老商戶中心在對外提供服務的同時,還能夠作為提供者,對新商戶中心提供服務支援;
- 新商戶中心僅對外提供服務,不直連資料庫,業務層只對美業的特殊邏輯進行處理。
因此,我們的想法是:新商戶中心直接呼叫舊商戶中心通過 Controller 暴露出的介面,進行遠端呼叫,於是我們決定嘗試使用 Spring Cloud 。
服務發現選型:
![4.png](https://ucc.alicdn.com/pic/developer-ecology/8637129bf73e469f853bd1d48c7dab5e.png)
- Consul 支援服務發現的同時,支援 kv 儲存服務,因為我們想做一個配置中心的 KV 儲存,所以想利用 Consul 做一個嘗試;
- 服務健康檢查相對更為詳細;
- 在我們選型的期間,突然出現了 Eureka 2.x 開源工作宣告停止的訊息,雖然後來發現,這個對我們並沒有什麼太大的影響,但在當時的決策讓我們最終選擇了 Consul 。
**服務化改造 1.0 架構圖:**
![5.png](https://ucc.alicdn.com/pic/developer-ecology/0e3a11ccd51d4ec09393cbfc6b3c495c.png)
服務化 1.0 我們的技術改造方案是:將舊的商戶中心註冊到 Consul 上面,新商戶中心到 Consul 上獲取伺服器列表,通過 Feign 進行遠端呼叫,打通了新老商戶中心的功能。
經過服務化 1.0 的改造,我們解決了如下幾個問題:
- **功能快速完善:**舊商戶中心的功能快速遷移到了新的商戶中心,並完成對美業的適配;
- **迭代速度加快:**新商戶中心大部分功能,能夠通過舊商戶中心進行修改相容,為後續的業務中臺的抽象打好基礎;
- **效能優化:**業務開發的同時,我們對舊商戶中心的老程式碼進行優化,效能和穩定性均有所提高。
但服務化 1.0 改造後,還是有一些挑戰沒有解決:
- **釋出週期依舊不夠快:**大部分程式碼還是在就商戶中心,業務迭代依然牽一髮而動全身;
- **協同效率沒有提高:**在程式碼衝突多,溝通成本高的同時,又出現了令開發同學頭痛的新老業務的相容問題;
- **維護成本:**Consul 是 Go 語言開發的,不易維護;Spring Cloud 在開發過程中體驗不佳,在寫業務的同時,還要摸索 Spring Cloud 的最佳實踐,花費了一些時間去做 Spring Cloud 的基礎建設。
於是我們決定開啟,服務化 2.0 的改造。
**服務化改造 2.0 的預期效果:**
![6.png](https://ucc.alicdn.com/pic/developer-ecology/faf2707cc0d846c381d72a491fbf76ef.png)
- 完成業務中臺的初步建設,將模組重新劃分,抽象為獨立服務;
- 新、舊商戶中心服務僅做自己的業務相容,並對外暴露介面;
- 新增專門支援 H5、小程式 的 C 端 WEB 服務。 因 Spring Cloud 體驗不佳,我們決定服務化改造 2.0 嘗試使用 Dubbo 作為基礎服務的 RPC 遠端呼叫框架,因此我們要對註冊中心進行選型。
首先,註冊中心我認為應該具備的基本功能 :
- 服務註冊及時被發現,異常時的及時下線;
- 服務管理,能夠手動恢復/剔除服務;
- 健康檢查,檢測服務是否可用;
- 元資料管理;
- 註冊中心保證自身的高可用。
![7.png](https://ucc.alicdn.com/pic/developer-ecology/0b4af885254643d4aa4da943d495e9eb.png)
**Zookeeper :**
- 不能保證每次服務請求都是可達的,當 zk 叢集 master 掛掉時,需要進行選舉,在選舉期間中,服務是不可用的;
- 不支援跨機房的路由,比如 eureka 的 zone,當前機房不可用時,可以路由到其他機房;
- “驚群效應”, zk 的節點過多的時候,當 service 的節點發生變更,會同時通知到客戶端,瞬時流量有可能將網絡卡瞬間打滿,並且會有重複通知的問題。
**Nacos :**
- 註冊中心部分更側重於可用性
- 服務發現與服務管理
- 服務元資料的管理
- 動態配置管理
![8.png](https://ucc.alicdn.com/pic/developer-ecology/f1b1e8295a194a57a008b8cca0dfbd4f.png)
在此期間,我們也關注到了 Spring Cloud Alibaba。阿里巴巴技術經受多年“雙十一”的考驗,其效能和穩定性是值得信任的。Spring Cloud Alibaba 的元件開源社群活躍度很高,並且比起國外開源專案更容易交流。其元件由 Java 語言開發,對我們來說更易維護,在出現問題時能夠更快地定位問題進行修復。而且與阿里雲配合,更加容易上雲,比如 Nacos 可以與阿里雲的 MSE 和 ACM 配合,將註冊中心及配置管理全部上雲。 ![9.png](https://ucc.alicdn.com/pic/developer-ecology/f9a6d1237f19487b81726c7ba469d020.png)
**因此,我們決定擁抱阿里技術棧。**
服務化改造2.0架構圖:
![10.png](https://ucc.alicdn.com/pic/developer-ecology/97bed48ca77d49d3ac1ef2a83b3a7dbe.png)
我們將之前的模組直接抽到基礎服務之中,新增了 會員、訂單、門店 等服務作為Provider,暴露自己的Service,並註冊到 Nacos 上。新商戶中心服務做美業業務邏輯的處理,舊商戶中心服務做泛行業的業務處理,C端服務同理對外提供服務。通過 Dubbo 進行遠端呼叫。
通過服務化 2.0 的改造,效果如下:
- 伺服器成本降低30%:20+臺伺服器,由4核16G 降配到2核8G;
- 系統可靠性提升80%:load 告警明顯減少,線上的問題修正能夠快速修復,完成部署;
- 程式碼衝突減少75%:因為邊界有了基本各自維護,衝突顯著減少;
- 釋出迭代效率提升50%:之前5個人每個迭代開發評估可完成30個點,現在可完成45個點左右。
# Nacos 落地實踐與問題分析
Nacos 在我們公司處理做註冊中心之外,配置管理也對我們提供了很好的服務。下面說一下,Nacos 我們的使用情況,以及我們遇到的問題。
首先是使用情況:
- 部署方式:開發/測試環境單機部署,生產環境 3 臺叢集部署;
- 版本:生產環境從 0.9.0 開始使用,目前生產環境使用的版本為 1.1.4 ;
- 使用時間:2019 年 3 月份開始在生產環境下使用;
- 服務數量:線上 20+ 臺伺服器,提供了 600+ 個服務;
- 穩定性:一年的時間裡沒有出現大的問題,並且平滑升級;
- 相容性:新老服務,在我們公司無論是 Spring 4.3+ 的工程,還是 Spring Boot 的工程均相容良好。
**Nacos 註冊中心:**
![11.png](https://ucc.alicdn.com/pic/developer-ecology/0e6d357d0e9d443fa60be7ca2fa29da9.png)
- 服務註冊:將後端服務註冊到 Nacos,通過 Dubbo 進行呼叫。目前開發環境中我們正在測試Seata,並且也將 Seata 服務註冊到 Nacos 上;
- Namespace:服務統一註冊到 public 中。
**Nacos 配置管理:**
![12.png](https://ucc.alicdn.com/pic/developer-ecology/cb7a3e696a8341bb81321b1f29bc3a4a.png)
每個服務設定獨立的 Namespace 。
- 服務的配置檔案資訊:application.properties 全部配置到 Nacos,工程的配置檔案僅保留 Nacos 相關配置;
- 業務層的 KV 配置:比如業務開關,屬性預設值,定時任務配置等;
- MQ Topic 的動態配置:Binlog 服務採集動態傳送到在 Nacos 配置的 topic 及其需要的表資訊;
- Sentinel 的規則配置:Sentinel 限流規則持久化到 Nacos 。
**問題描述:**
![13.png](https://ucc.alicdn.com/pic/developer-ecology/fd0a479606b04f339aa70fa3f1fafa31.png)
2019 年 12 月 31 日,下午 3 點 15 分左右,線上突然出現大量服務告警,Dubbo 服務出現報錯,整個過程持續約 3 多分鐘。各個業務組當天均沒有任何釋出,資料庫狀態也良好。
通過日誌發現,報錯原因是門店服務無法呼叫。而門店服務日誌,出現問題的時間段內,沒有任何的呼叫記錄。系統恢復正常時,出現了很多服務註冊的通知。
因此,我們將問題瞄準了 Nacos。檢視 Nacos 的日誌發現,在系統恢復過程中,有大量的服務正在上線。
就在排查的過程中,線上突然又出現了之前相同的告警,Nacos 上的服務列表開始大量變成不健康的狀態,於是我們緊急重啟了線上的 Nacos ,在這期間又經歷了一個 3 分多鐘的驚魂後,再次恢復了平靜。
問題分析:
- 兩次出現的問題均是門店服務,但出現問題期間 JVM 和資料庫的執行狀態均良好;
- 報錯資訊都是 Dubbo 呼叫超時,且出現問題期間,門店服務沒有任何流量進入;
- 出現問題時,註冊在 Nacos 上的服務開始大量不健康。恢復正常時,這些服務又開始上線,說明出現問題時,服務被下線又重新上線。
綜上,我們開始懷疑是網路原因造成的。
問題確認:
![14.png](https://ucc.alicdn.com/pic/developer-ecology/c7eb3be62e744216999b0c4a4b3ee05d.png)
經過排查,發現我們的服務大多部署在 阿里雲華東 1 可用區 B ,只有門店服務和 Nacos 叢集沒有部署在可用區 B ,說明這段時間可用區 B 與其他區之間的發生了網路隔離。
於是,我們在可用區 B 緊急部署了門店服務,之後沒有再出現問題。
經過與阿里雲的溝通確認於北京時間 2019 年 12 月 31 日 14:05 分左右開始,部分使用者反饋阿里雲華東 1 地域可用區 B 部分網路出現異常,影響部分雲資源訪問。
問題覆盤:
- 問題出現:下午 3 點多,突然連續出現的服務告警, Dubbo 服務出現報錯;
- Nacos:Nacos 服務列表裡大量服務出現不健康的狀態;
- 網路不通:可用區 B 與其它區網路不通,導致服務無法呼叫;
- 緊急部署:在 B 區部署缺失的 門店服務;
- 恢復正常。
問題思考:
- 服務部署:應用服務和Nacos建議多機房部署,即使在雲上可用區之間也需要考慮;
- 容災:問題出現時,可用區 B 並沒有部署 Nacos,但可用區B內的服務之間依然能調通,且能夠讀到 Nacos 上的配置。因此,我們認為 Nacos 以及 Dubbo 的容災策略都是值得信賴的。
**回顧與展望:**
![15.png](https://ucc.alicdn.com/pic/developer-ecology/89e7269aa09b44d4a5cd398f1abb1d28.png)
“顏鋪專家”經過不斷地快速迭代,幫助美業商家⾼效快捷地管理門店,進行經營資料分析,資料化管理門店,建⽴完善的會員週期管理體系,為美業商家在經營管理中,提供⼀體化的解決方案,將美業傳統的門店經營模式進⾏網際網路升級。截止到目前我們累計服務 3000 多個品牌,1.1W + 個⻔店。我們提供了店務管理系統、會員管理系統、營銷拓客系統、大資料決策系統、供應鏈管理系統、員工績效管理系統6⼤系統能力,同時⽀持 PC 端、手機 APP 、 pos 機、 iPad 操作,滿⾜⻔店多端操作需求,覆蓋⻔店經營管理中的所有場景需求。
# 未來規劃
**提升系統高可用**
- **Seata :**目前我們公司的分散式事務主要依賴 MQ 的補償,今年準備引入 Seata 來完善分散式事務,保證資料一致性,減少開發修資料的情況;
- **Sentinel :**目前 Sentinel 我們只是在商戶做活動時啟用,因此我們要配置出適用於我們公司的最佳實踐,保證系統的高可用;
- **全鏈路跟蹤:**我們公司現在定位問題主要靠日誌和告警,做不到全鏈路的跟蹤,所以我們要把這部分做好,做到故障快速定位,各呼叫環節效能分析,以及資料分析;
- **異地容災:**隨著來自全國各省的商戶越來越多,我們需要對商戶的資料保障,避免資料丟失,確保服務的可靠性。
**社群回饋**
![16.png](https://ucc.alicdn.com/pic/developer-ecology/7b38dede18f44ab5a8ca953056c654c6.png)
因為我們的公司體量現在不大,我們能夠做到的是儘可能地使用最新的版本,及時嘗試新特性,對發現的問題提 issues,但我們也希望能夠對 Nacos 開源社群盡一份我們的力量。
**作者資訊:**殷銘,顏鋪科技架構師,負責顏鋪 SAAS 平臺中介軟體的應用和實踐,主導了平臺架構在顏鋪向分散式演進的全過程,目前也負責大資料在顏鋪平臺的實踐和落地。
![17.png](https://ucc.alicdn.com/pic/developer-ecology/55fba6c24df5433d878e88d4fb38eedc.png)
> “[阿里巴巴雲原生](https://mp.weixin.qq.com/s/zmE9zbyir6xlEgh119Dhag)關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公眾