性能
一開始的重點(diǎn)是提高服務(wù)的性能、反應(yīng)速度攀例,并且盡可能的保證系統(tǒng)的安全振坚。
第一階段
商城第一階段的框架采用的是傳統(tǒng)的動(dòng)靜分離+負(fù)載均衡的配置购撼。
- 最外層是采用
F5
做的負(fù)載均衡和反向代理 - 兩臺(tái)
Ngnix服務(wù)器
負(fù)責(zé)處理靜態(tài)資源的請(qǐng)求媒佣,并將動(dòng)態(tài)請(qǐng)求分發(fā)給Tomcat服務(wù)器
集群 - 商城的應(yīng)用(網(wǎng)站匕累、觸屏版等)都建立在
Tomcat服務(wù)器
上,主要采用SpringMVC
+Freemarker
- 應(yīng)用通過
API服務(wù)器
暴露出的接口對(duì)數(shù)據(jù)庫進(jìn)行增刪改查的操作
第二階段
第二階段框架的出現(xiàn)是為了解決第一階段暴露出的幾個(gè)問題:
-
Tomcat服務(wù)器
過于忙碌:-
Tomcat服務(wù)器
的一般工作流為:接收到Ngnix服務(wù)器
轉(zhuǎn)發(fā)的動(dòng)態(tài)請(qǐng)求 => 將動(dòng)態(tài)請(qǐng)求按照業(yè)務(wù)邏輯調(diào)用API服務(wù)器
的接口 => 將API服務(wù)器
返回的數(shù)據(jù)和Freemarker
結(jié)合丈攒,生成HTML
文件 - 對(duì)于經(jīng)常被訪問到的頁面(首頁、商品詳情頁等)授霸,
Tomcat服務(wù)器
需要不斷重復(fù)他的一般工作流巡验,即使最后生成的HTML
文件都是一模一樣的。
-
Tomcat服務(wù)器
和API服務(wù)器
交互過于頻繁:即使API服務(wù)器
有如memcached
類的緩存碘耳,依然會(huì)有很多不必要的網(wǎng)絡(luò)消耗
因此显设,我們覺得最好能將HTML
文件緩存下來
我們?cè)?code>Tomcat服務(wù)器上加上了EhCache
過濾器。一些經(jīng)常會(huì)被訪問到的頁面(譬如首頁辛辨、商品詳情頁等)在第一次被訪問過并成功生成HTML
頁面后捕捂,會(huì)被記錄在內(nèi)存中,下一次訪問的時(shí)候就不會(huì)再向API服務(wù)器
請(qǐng)求斗搞,也不會(huì)再解析Freemarker
模板指攒,內(nèi)存中的頁面會(huì)直接返回。
第三階段
第二階段的框架一上線就暴露出了問題:頁面不能及時(shí)更新僻焚,需要等EhCache
自帶的緩存更新機(jī)制(通常是緩存池滿了)激活允悦,緩存才會(huì)更新;而我們需要緩存更新是及時(shí)的虑啤、是可控的隙弛。
所以架馋,我們自制了一個(gè)叫Backbone
的微服務(wù)
其實(shí)Backbone
目前就被當(dāng)成了一個(gè)定時(shí)任務(wù)系統(tǒng),只不過起名的時(shí)候全闷,我們對(duì)這個(gè)系統(tǒng)寄以重托叉寂,所以給了一個(gè)很大的名號(hào)。
工作流是這樣的:
- 當(dāng)有緩存的內(nèi)容進(jìn)入
EhCache
的時(shí)候总珠,Backbone
會(huì)接收到請(qǐng)求的參數(shù) -
Backbone
根據(jù)接收到的請(qǐng)求參數(shù)屏鳍,按照業(yè)務(wù)邏輯,請(qǐng)求API服務(wù)器
姚淆;之后將API服務(wù)器
返回的結(jié)果拼接孕蝉,生成一個(gè)簽名,最后將<請(qǐng)求參數(shù)腌逢,簽名>
存入Redis
中 -
Backbone
定期從Redis
中取出請(qǐng)求參數(shù)降淮,并按照頁面邏輯,請(qǐng)求API服務(wù)器
搏讶,如果API服務(wù)器
返回的結(jié)果拼接后的簽名和Redis
中存的簽名一致佳鳖,則無變化;如果不一致媒惕,Backbone
會(huì)刪除Redis
中的記錄系吩,并調(diào)用Tomcat服務(wù)器
暴露的接口刪除EhCache
中該請(qǐng)求的緩存。
第四階段
第三階段的框架還是有瑕疵妒蔚,有這么三個(gè)最為明顯:
- 既然第二次訪問同鏈接訪問的是緩存的內(nèi)容穿挨,為什么還要到
Tomcat服務(wù)器
才處理 - 緩存的
HTML
文件能不能看到 -
EhCache
中存的很多數(shù)據(jù)都是冗余的
于是,我們采用了Ngnix+Lua
的方式來解決上面三個(gè)問題肴盏。
Ngnix服務(wù)器
將Tomcat服務(wù)器
生成的HTML
文件保存到Redis
中科盛,這樣Redis
就被做成了Ngnix服務(wù)器
集群統(tǒng)一存儲(chǔ)HTML
文件的地方。
優(yōu)化
日志系統(tǒng)
經(jīng)過四個(gè)階段的性能優(yōu)化菜皂,整個(gè)商城的服務(wù)應(yīng)該算OK贞绵,接下來我們想讓開發(fā)調(diào)試更輕松一些愁茁。
我們覺得目前開發(fā)調(diào)試的瓶頸是日志:
- 一方面 因?yàn)檎江h(huán)境需要堡壘機(jī)才能操作橘券,如果需要通過看日志來解決問題,需要到堡壘機(jī)看日志或者讓運(yùn)維拖日志下來竖伯,整個(gè)流程非常的難受章母。日志不是什么生死攸關(guān)的東西母蛛,我們想要看到線上實(shí)時(shí)的日志。
- 日志中打印了很多很多的內(nèi)容乳怎,使用
tail -f
之類的命令溯祸,滾屏?xí)浅5目欤@樣看日志太傷神了。我們想要更優(yōu)雅焦辅、更簡單的查看日志的方法博杖。
一種解決方法是將日志保存到專門的一臺(tái)服務(wù)器,然后通過tail -f XX | grep XXX
之類的命令來看筷登。這種方法是能基本解決以上兩個(gè)問題剃根,但是不那么優(yōu)雅,不能算作一個(gè)系統(tǒng)的解決方案前方。
于是狈醉,我們采用了ElasticSearch
+ LogStash
+ Kinaba
(ELK
)。一開始我們想自己利用Bootstrap
或者Framework7
寫一套系統(tǒng)惠险,但是太懶苗傅,同時(shí)也發(fā)現(xiàn)ELK已經(jīng)把我們想做的都做了,有些小功能班巩,我們改改Kinaba
就能實(shí)現(xiàn)渣慕,所以直接把ELK
拿來用了。
首先我們自制了一個(gè)Admin
微服務(wù)來監(jiān)聽處理Tomcat服務(wù)器
通過MQ
發(fā)送過來的日志
日志服務(wù)的工作流是這樣的:
-
Tomcat服務(wù)器
的日志會(huì)被發(fā)送到MQ
的Exchanger
-
Admin系統(tǒng)會(huì)
將監(jiān)聽到的日志進(jìn)行處理(Tomcat服務(wù)器
的日志利用拓展log4j.appender
抱慌,封裝了一些附加信息)逊桦,打印到admin-log.log
文件中 -
LogStash
會(huì)分析admin-log.log
,并將分析的結(jié)果實(shí)時(shí)的放入ElasticSearch
里 -
Kinaba
為ElasticSearch
提供了一個(gè)可視化的界面抑进,在這個(gè)界面中强经,我們能篩選日志,能實(shí)時(shí)打印日志
小助手
最初的想法是利用Slack
+ Hubot
寺渗,但是依然是因?yàn)閼心淝椋D(zhuǎn)用了微信。
微信小助手的主要用處就是檢查服務(wù)的上線狀態(tài)信殊,發(fā)送上線檢查
之類的關(guān)鍵字炬称,就會(huì)激活我們寫的檢查程序,主要涉及商城頁面能不能正常打開鸡号,有些流程能不能走通转砖,如果走不通是因?yàn)楦鶤PI服務(wù)器的溝通斷了還是API服務(wù)器壞了還是什么须鼎。其次還加上了一些權(quán)限設(shè)置以及小助手注冊(cè)機(jī)制等等鲸伴。
未完待續(xù)
之前堅(jiān)持要自己做日志系統(tǒng),還有部分原因是會(huì)根據(jù)分析日志得到的結(jié)果加上推薦系統(tǒng)和優(yōu)化搜索晋控。