當下10後都能在手機鍵盤上敲字如飛,60後的均可以坦然的搖微信,移動互聯網可謂煊赫一時。隨着智能手機的快速發展,移動APP做爲登入移動互聯網最便捷的方式,扼守着移動互聯網的入口。如今這類軟件被愈來愈多的人所青睞,在沒有大量資金的狀況下,手機APP是中小企業發展方向的一個很好選擇。對於我的和企業移動APP 已是創業和發展的必備工具。移動互聯網APP開發,對於企業來講面臨着項目週期,資源投入,推廣等諸多問題,而對於我的更是望而卻步。html
傳統移動開發技術方案:java
終端移動平臺太多:Android,IOS,Windows Phone,微信 …. 並且不一樣平臺還有版本差別,對於開發調試簡直是一場噩夢,要想實現統一覆蓋沒有雄厚的資本支持是很是困難的。node
開發成本:招人難,找到合適的更難,成本高,移動開發門檻障礙git
撿了芝麻丟了西瓜:企業把精力投入到本身不擅長的領域大多時候並非一件好事情,對於我的來講更是如此。github
全站解決方案:一個優秀的APP除了核心業務同時也須要其餘優秀的組件,如:推送,用戶行爲分析,市場活動,數據統計等等。web
運維困難:要保證APP的穩定可靠運行,運維是必不可少的一部分,這些工做須要專業的運維團隊來作。這樣也加劇了企業的負擔。sql
如今是一個屌絲逆襲的時代,爲了幫助企業和我的無門檻擁有屬於本身的APP,MaxWon 應運而生。docker
MaxWon 是基於MaxLeap SaaS 雲服務,集成不一樣行業模塊,集 APP 生成,運營,分析,自動化運維與一體的服務,用戶只須要關心本身的業務,徹底擺脫上面的各類難題。shell
用戶組合本身想要的模塊,點擊生成APP,就能夠生成本身想要的不一樣平臺的APP,包括Android,IOS,微官網,PC官網。數據庫
差別化服務。因爲是面向多租戶的服務,不一樣的APP產生的流量可能差別很大,系統要能作到服務隔離和水平擴展。
數據隔離與擴展。爲了保證數據安全,每個APP 都會有一個獨立的DB,數據只能被本身的APP訪問,防止數據hack,保證數據安全。對於大數據量的APP,DB 可以支持無限擴展。
快速部署與自動化運維。
服務的監控。因爲服務遍及在集羣的不一樣機器上,須要可以監控全部租戶服務的健康狀態,保證服務的高可用行,而且可以水平擴展。
支持服務和數據的遷移
因爲MaxWon 須要支持不一樣行業,業務就會比複雜,比較多。項目業務層是按模塊來劃分,經過不一樣模塊的組合來不一樣知足行業的需求。
初版架構遵循兩個原則:第一, 以業務實現爲目標,儘快作出產品原型。因爲MaxLeap已經有不少基礎的中間件能夠直接拿來使用,如:推送,FAQ&Issue,支付,IM&社交等。如今只須要把精力放在MaxWon 本身的業務中去。第二,快速響應產品的需求,產品指導研發,不少場景、不少的玩法必須幫助產品實現,並且速度要很是快,要快速迭代。
描述 | 名稱 |
---|---|
平臺 | JDK 1.8 |
Web框架 | vertx-jersey(異步) |
ORM | JOOQ |
RDS | Mysql |
NoSql | Mongo |
對於大部分人來講 Vert.x可能會有點陌生,它是基於Netty實現的異步架構,和node.js 極其類似。因爲以前作MaxLeap服務,一直在用Vert.x作爲基礎架構,整個團隊對Vert.x 也很熟悉,該踩得坑也都踩過了,經過Verx-Rpc 能夠直接訪問的MaxLeap 的微服務。在使用Vert.x 時最大的感覺就是不能寫同步代碼,不然就會阻塞,致使致使服務不可用,因此咱們的服務全是基於異步的方式來寫的。因爲它是一個輕量級高性能JVM應用平臺,支持多語言開發,它的簡單actor-like 機制能幫助脫離直接基於多線程編程,天生支持分佈式,之後對於服務擴展也是水到渠成的事情。
對於ORM 並無使用主流的 Hibernate或者IBATIS,而是使用小衆的JOOQ。JOOQ 相對於其餘ORM算是很輕量,提供了強大的DSL 來訪問數據庫,靈活,上手很容易,代碼很是接近sql。
JOOQ runtime schema mapping 對於多租戶應用程序有很好的支持,能夠很容易的實現爲每一個租戶分配獨立的DB。
還有一個重要的緣由就是 JOOQ 已經和Java8 的Stream API 徹底融合,cool!!。函數式編程表達性強,而且很是通用。它是數據及數據流處理的核心。Java開發人員如今也都知道函數式編程,並且你們又都用過SQL。想象一下,你用SQL來聲明表來源,把數據轉化成新的元組流,而後要麼將它們做爲派生表提供給其它更高級的SQL語句來使用,要麼將它們交給你的應用程序來處理。
下面就是一段典型的Java代碼
DSLContext create = DSL.using(connection, dialect); create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, count()) .from(AUTHOR) .join(BOOK).on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) .where(BOOK.LANGUAGE.equal("DE")) .and(BOOK.PUBLISHED.greaterThan("20017-01-01")) .limit(2) .offset(1) .fetch(record -> transfer(record)) .stream() .filter(ele -> null != ele) .collect(Collectors.toList());
有了JOOQ,Java 8以及Streams API,你能夠寫出強大的數據轉化的API,並且簡單易懂。
將架構特色劃分爲優勢和缺點進行描述。那麼優勢是:
簡單,易於實現,不須要額外的基礎支撐
利於業務的功能快速實現
服務都是以Docker Container 啓動,能夠實現快速發佈與部署
缺點:
不一樣租戶的應用沒法隔離,全部的APP 都使用相同的Container,這樣會帶來APP之間相互影響,致使服務不穩定的風險。
缺乏服務健康檢查。
運維成本過大。
1.0的架構就是一個簡單的Web系統。負載均衡使用Nignx,並無細化到租戶級別。業務系統經過代碼模塊的形式組織各類業務就是一個簡單的Web系統,後面直接掛了數據庫,好比商品、訂單、會員、客服,等等。能夠看到,咱們這個基礎的架構,對外就是HTTP。當時兩我的的小團隊開發各類業務,咱們考慮只能用最簡單、最粗暴的方式實現,能快速地實現業務。當時的流量不是第一重要的問題,也不是最主要的矛盾。
對於這個階段,總結了三點。第一,技術來源於業務同時提高業務發展,業務發展又反過來推進技術的前進,他們是一個相互影響相互促進的關係。和業務共同發展的技術纔是有生命力的。第二,成熟簡單的技術就是最合適的,這個理念一直貫穿始終。不要把事情複雜的形態呈現給你們,腦子要保持簡單,不要想那麼複雜的事兒。第三,要把能遇到的場景儘可能到考慮到,之後架構升級不至於很被動。你們看到初始的架構等於沒有架構,可是這種形式在這時是最符合業務需求的一個,能快速迭代,能很是方便上線。
在MaxWon1.0時代的時候,咱們的關注點更偏向業務的實現,隨着用戶增加,性能和穩定性問題逐漸浮上水面,做爲一個多租戶的應用系統,系統不穩定,是很是致命的,2.0解決這些問題也迫在眉睫。
首先要解決的就是服務分離。其中有兩種方案 :
每個租戶APP都有屬於本身的 服務 Container,這樣就解決了租戶之間的相互影響。可是 大部分 APP 訪問點可能很小,甚至是殭屍應用。雖然Docker 容器使用的資源很小,可是大量的不活躍應用仍是會浪費掉太多的系統資源,資源利用率低。
按租戶的真實的訪問量劃分爲不一樣的組,普通規模應用或者是殭屍應用都公用同一組Container,中等規模應用 某幾個使用一組Container,對於大量數據流量的應用 獨佔 同一組Container,這樣的話資源利用率就會很高。缺點就是 普通規模和中等規模應用 服務之間仍是會有影響,因爲這兩種規模的數據訪問的會少不少,出現慢查詢而致使拖慢整個系統的可能性會很小。
對比上面的兩個方案優缺點,基於現實的考慮最終選擇了第二種方案。這就須要可以隨時監控APP的數據訪問量,當某個APP訪問量快速上升時可以隨時獨立出服務來,這樣就能夠最大限度的防止租戶以前相互影響而產生的服務抖動。
對於服務監控,則採用心跳檢測的方式,每一個服務Container對外暴露一組健康檢查的接口,監控系統會定時的巡視全部服務的健康狀態,若是因爲某種緣由被Kill掉,則重啓對應Container的併產生告警。
對於數據存儲分離 也採用了一樣的思路。對於Mongo ,Pandora自己就支持按不一樣App 數據分治。對於Mysql代理則採用 MaxLeap 研發的 Circe組件,能夠實現不一樣App數據的隔離。使用AWS ELB 解決了Circe的負載均衡與高可用。
2.0的採用了服務和數據分離的思想,如今回顧也並不複雜,對於碼農來講這種思想已是很是熟悉的了。若是你的產品功能很少,迭代不是很快,能夠放慢一下腳步,停下來一段時間來集中一次重構。但對於MaxWon來講這一版本的迭代就像是鳥槍換炮,知足了大部分的應用場景。對於業務快速迭代,上線時間緊迫的系統來講,此次重構也是一個不小的挑戰。
繼承了原有1.0的特色,保留了其優點
解決了數據和服務隔離與擴容的問題
實現不一樣租戶的差別化服務
添加了服務監控與檢查
使用docker 構建能夠完美的解決環境衝突的問題,也能夠方便快速部署和擴容。
FROM 10.10.10.160:8010/maxleap/vertx:3.2.1 MAINTAINER ben.ma <cma@maxleap.com> #----------------------------Copy 項目目錄到容器裏------------------------------------------ RUN \ mkdir -p /opt/maxwon #覆蓋vert.x 相關配置 ADD lib/ $VERTX_HOME/lib/ ADD log4j2.xml $VERTX_HOME/conf/ ADD zookeeper.properties $VERTX_HOME/conf/ ADD config.json /opt/maxwon/ WORKDIR /opt/maxwon ENTRYPOINT ["vertx", "run", "java-hk2:as.leap.ama.module.jersey.JerseyVerticle", "--conf", "config.json"]
經過spotify docker-maven-plugin 插件,根據事先定義在項目中的DockerFile能夠輕鬆的把項目打包成可執行的docker Image並push到生產環境中。
$ mvn clean deploy -DpushImage -Pcn
Hydra: 海德拉 古希臘神話人物,是一種傳說中有九個頭的大蛇,爲冥王看守門戶。在這裏Hydra 做爲 MaxWon的API網關,管理來自不一樣端的請求,根據請求的來源轉發到相應的的MaxWon的服務容器組中。同時它也會管理和監控容器狀態以及對服務的動態擴容。
Circe:希臘神話裏一個能製造幻覺的女巫,這裏用來隱喻可以製造Mysql服務的代理的項目.經過它能夠實現不一樣租戶的數據隔離,過濾非法,有毒的sql語句,保證數據隱私和安全。
Pandora:訪問MongoDB的基礎組件,也是MaxLeap 核心組件之一,提供了同步和異步的兩種接口。Pandora最爲核心的功能是實現了資源限制和數據庫訪問的路由策略,這對數據庫進行平滑的動態擴展及遷移提供了可靠的支持。感興趣的能夠參考同事寫的MONGO 集羣設計
脫離業務談架構都是扯淡,利用技術手段提高工做效率是好事,別陷進去,產品最終拿出來講話的仍是有沒有解決用戶的問題,而不是解決你本身的問題。對於MaxWon 這種快速迭代的系統,系統也會考慮更多的業務場景,體積也愈來愈龐大,遇到棘手的問題也會愈來愈多,作好優化的準備。
系統要儘可能保持簡單,技術架構的選型建議是尋找當前最短路徑,而後進行不斷優化迭代,想一口吃個大胖子不太可能。
代碼不要寫死。
本文做者來自 MaxLeap 團隊_數據服務組 成員:馬傳林
馬傳林,從事開發工做已經有5年。當前在MaxLeap數據服務組擔任開發工程師,主要負責MaxWon服務器開發。
本文連接:https://blog.maxleap.cn/archives/734
歡迎關注微信訂閱號:從移動到雲端歡迎加入咱們的MaxLeap活動QQ羣:555973817,咱們將不按期作技術分享活動。