輕量級微服務架構實踐之 ANOYI-IM

weixin_33924312發表於2017-11-17
3424642-e64cbe2ad0bba8e8.png

一、概述

WebSocket 應用場景非常廣泛,例如社交聊天、彈幕、多玩家遊戲、協同編輯、股票基金實時報價、體育實況更新、視訊會議/聊天、實時定位、線上教育、智慧家居等,這些場景都與我們的生活息息相關。

ANY-IM 2.0 是基於 Spring Boot 2.X 框架開發的 WEB 線上即時通訊應用,混合使用了 Spring MVC 及 Spring WebFLux,支援點對點通訊、群通訊、系統群發訊息等多種方式。由於單體應用的侷限性,又在單體應用的基礎上設計了叢集方案,解決資源合理利用的問題。

演示地址:https://anoyi.com/

二、系統架構

3424642-7b752a6fcfe81737.png

高清圖地址:http://on-img.com/chart_image/5a0e8e5de4b0143a78b3d509.png

架構簡單說明:

  • KeepAlived:配合VIP,實現高可用
  • 通訊服務:基於 Spring Boot 及 Spring Framework 開發的 WebSocket 後端服務
  • 使用者服務:基於 Spring Boot 及 Spring Security 開發的使用者服務
  • MongoDB:用於儲存 Http Session 資訊,實現 Http Session 共享,還用於儲存使用者訊息
  • Nats:優雅的釋出訂閱模型,用於服務間通訊,負責訊息轉發
  • 日誌系統:ELK搭建,視覺化所有元件日誌內容
  • 監控系統:容器級別的視覺化監控及報警

三、基於 Spring Boot 的 WebSocket 應用實現

作為一名 Java 工程師,使用 Spring Boot 來構建單體應用無疑是最好的選擇,簡潔、高效、穩定!

1、工欲善其事必先利其器

2、建立 Spring Boot 應用

快速建立,參考官方文件 https://projects.spring.io/spring-boot/ ,為了加快開發速度,使用到 LombokJsoupFastjson 等第三方依賴,開發時使用熱部署,避免頻繁地重啟應用。

3、整合 WebSocket

<!-- 通訊 websocket -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

前端需要使用 sockjs.jsstomp.js 來連線 WebSocket, 推薦使用 Vue.js 來渲染前端頁面。

入門 DEMO:https://spring.io/guides/gs/messaging-stomp-websocket/
STOMP協議詳解:https://www.cnblogs.com/my_life/articles/7002138.html

4、整合 Spring Security 、Spring Session 及 MongoDB

需求 參考資料 官方文件
Spring Security Spring Security Demo Spring Security
Spring Session Spring Session Data MongoDB Spring Session
MognoDB Spring Boot 整合 MongoDB docker 安裝方式

MongoDB Web視覺化工具:Mongo Express

四、基於 Redis 的跨容器 WebSocket Session 共享

3424642-d4cfc60086d6b35e.png
使用者與任意服務節點建立長連線

如圖所示,小明和服務A建立了長連線,小紅和服務B建立了長連線。此時,小明想給小紅髮訊息,但是服務A和服務B之間互不關聯,所以小明發給小紅的訊息會丟失。要想小明能聯絡到小紅,就要實現服務A和服務B之間的通訊。

3424642-16af8562737e8376.png
跨服務 WebSocket 通訊實現
  • 〇 客戶端和伺服器端建立連線時需要將自己的身份ID和伺服器ID寫到資料庫,斷開連線時刪除記錄
  • 〇 每個服務上線時,根據服務唯一ID在Redis上訂閱對應的Topic
  • ① 小明傳送給小紅的訊息先被傳輸到服務A
  • ② 服務A收到訊息從資料庫中查到小紅所連線的伺服器是服務B
  • ③ 服務A將小明的訊息轉發到Redis中服務B的Topic
  • ④ 服務B收到Redis發來的訊息
  • ⑤ 服務B將訊息傳送給小紅

至此,小明就能到把訊息傳送給小紅了。

五、基於 Docker Swarm 的叢集解決方案

Docker Swarm 是 Docker 官網維護的叢集管理工具,應用 Docker Swarm 可以很便捷地解決跨主機網路、動態擴容等問題。

入門文章可以參考:http://www.jianshu.com/p/096244610e15

3424642-4c85704f8bd22a21.png

如圖所示,實現任意容器之間的網路互通,只需要兩步即可。

1、在Docker Swarm 叢集的 Manager 上建立網路

docker network create -d overlay --attachable [networkName]

2、啟動容器時,帶上網路引數

  • 啟動單個容器:docker run --net [networkName] IMAGE
  • 啟動服務:docker service create --network [networkName] IMAGE

動態擴容,也比較簡單。

1、將 Spring Boot 應用構建成映象
參考文章:http://www.jianshu.com/p/b06de710c109

2、在 Swarm 叢集中啟動

docker service create --name anyim --network [networkName] IMAGE

3、動態擴容

docker service scale anyim=[擴容數量]
3424642-9fc91d6b41f66080.png

六、基於 Registrator 和 Consul 的服務註冊與發現

Registrator:https://gliderlabs.com/registrator/latest/
Consul:https://www.consul.io/

1、啟動服務註冊中心 Consul

docker run -d --name=consul -p 8500:8500 --net [networkName] consul

啟動完畢後,可以訪問 http://localhost:8500/ 檢視服務資訊

2、啟動 Registrator 監聽 Docker 容器

docker run -d \
    --name=registrator \
    -v /var/run/docker.sock:/tmp/docker.sock \
    --net [networkName] \
    --link consul:consul \
    registrator \
    -cleanup=true \
    -internal \
    -resync=60 \
    consul://consul:8500

額外說明: 需要在每臺主機上部署


3424642-e6e73dcf6442d1d7.png

3、使用 Consul Template 重新整理 HAProxy 配置

此處,已封裝好映象,直接啟動即可:

docker run -d \
 --name consul-template-haproxy \
-p 8080:8080 \
--link consul:consul \
--net [networkName] \
registry.cn-hangzhou.aliyuncs.com/anoy/consul-template-haproxy

獲取映象:

docker pull registry.cn-hangzhou.aliyuncs.com/anoy/consul-template-haproxy

七、基於 HAProxy 和 KeepAlived 的負載均衡與高可用

詳見文章:http://www.jianshu.com/p/83036a320036

八、AB 測試

詳見文章:http://www.jianshu.com/p/43d04d8baaf7

九、常見問題總結

1、 WebSocket 協議詳解

https://tools.ietf.org/html/rfc6455#section-1.9

2、STOMP 協議詳解

https://stomp.github.io/stomp-specification-1.2.html

3、NATS 官方文件

https://nats.io/documentation/

如有疑問,可以“評論”或者通過“簡信”聯絡作者

版權宣告:未經許可,不得轉載

相關文章