互聯(lián)網(wǎng)的網(wǎng)站和大部分企業(yè)管理軟件一樣都是使用B/S架構模型,但是大型的公共網(wǎng)站B/S架構會(huì )更加復雜,對架構人員的要求更高,今天我想在自己博客里聊聊我設計的網(wǎng)站的B/S技術(shù)架構。
不管是B/S架構的企業(yè)管理系統還是網(wǎng)站技術(shù)架構可以抽象為如下簡(jiǎn)圖:
在傳統B/S架構的企業(yè)管理系統里,技術(shù)架構往往就是一個(gè)工程項目,各個(gè)邏輯分層都是該工程的業(yè)務(wù)邏輯模塊。但是作為提供公共服務(wù)的網(wǎng)站,由于用戶(hù)群比較龐大,網(wǎng)站并發(fā)量高,需求變化大,變更頻繁以及網(wǎng)站出于對安全的考慮,以上的邏輯分層在技術(shù)架構上的實(shí)現也就會(huì )復雜的多。本人前不久做一個(gè)網(wǎng)站,我設計的技術(shù)架構簡(jiǎn)圖如下:
我把網(wǎng)站項目拆分為三個(gè)子項目:前端項目、服務(wù)端項目和memcache項目,前端項目包含頁(yè)面、靜態(tài)資源和控制層;服務(wù)端項目包含業(yè)務(wù)層和數據庫操作層;memcache項目緩存前端項目和服務(wù)端項目公用的數據。
在系統部署上,前端項目和服務(wù)端項目都采用分布式方式(我們的網(wǎng)站前端是4臺服務(wù)器,服務(wù)端是4臺服務(wù)器),用戶(hù)請求進(jìn)入前先通過(guò)負載均衡設備進(jìn)行請求分發(fā),前端和服務(wù)端之間以及服務(wù)端和數據庫之間有防火墻保證系統的安全性,前端的集群和服務(wù)端集群分屬到不同網(wǎng)絡(luò )環(huán)境里,前端集群可以訪(fǎng)問(wèn)外網(wǎng),服務(wù)端集群和數據庫所在網(wǎng)絡(luò )不能直接訪(fǎng)問(wèn)外網(wǎng),但是前端網(wǎng)絡(luò )環(huán)境和服務(wù)端網(wǎng)絡(luò )環(huán)境之間可以進(jìn)行通信。
服務(wù)端和客戶(hù)端用我們自定義的報文進(jìn)行通訊,傳輸協(xié)議時(shí)http,由于本人所在的網(wǎng)站安全性要求比較高,用戶(hù)傳輸的請求協(xié)議使用https。
為了保證服務(wù)端和客戶(hù)端通訊的效率,客戶(hù)端和服務(wù)端通訊我們使用長(cháng)連接(我們網(wǎng)站服務(wù)端語(yǔ)言選擇的是java,通訊層使用netty框架開(kāi)發(fā)的),為了保證長(cháng)連接,我們寫(xiě)了一個(gè)心跳檢測服務(wù),該服務(wù)在后臺線(xiàn)程里運行,每個(gè)5分鐘檢測一次心跳,當然檢測的間隔時(shí)間是可以配置的。此外,我們事先估計過(guò)網(wǎng)站的最大并發(fā)量,在網(wǎng)站啟動(dòng)時(shí)候,我們構建了一個(gè)線(xiàn)程池(我們使用的服務(wù)器是8核處理器,每核最大線(xiàn)程數256,所以我們線(xiàn)程池里總共的最大線(xiàn)程總數數是8*256*4=8196),每個(gè)線(xiàn)程處理一個(gè)用戶(hù)的請求。
由于客戶(hù)端項目采取分布式部署,因此存在session共享的問(wèn)題,我們網(wǎng)站的session共享沒(méi)有使用web容器自帶的session共享機制,而是我們自己研發(fā)了一套session機制,原理很簡(jiǎn)單,具體是我們會(huì )對每個(gè)用戶(hù)會(huì )話(huà)生成一個(gè)唯一標示,我們的唯一標示是這么設計:當前用戶(hù)的session的id值+隨機16位數字和字母組合+當前的納秒值,然后將該值哈希算出一個(gè)key,原有保存在session里的值保存在memcache集群里,這些數據的key就是我們算出的用戶(hù)唯一標示。最終我們網(wǎng)站前端不在使用session對象,而是我們自己設計的session機制,對此我們還封裝了一套自定義標簽,在頁(yè)面上操作我們自定義的session。
服務(wù)端也有類(lèi)似的共享機制,但是有所不同,當客戶(hù)端請求服務(wù)端時(shí)候,請求會(huì )具體落到服務(wù)端的某一臺服務(wù)器,因為本網(wǎng)站有些請求處理時(shí)異步的,也就是說(shuō)客戶(hù)某些請求不是立即返回給用戶(hù),而是現將請求分發(fā)給服務(wù)端,此時(shí)客戶(hù)端會(huì )返回用戶(hù)一個(gè)相應標示,說(shuō)明該請求已經(jīng)被受理,正在處理中,而服務(wù)端的某個(gè)線(xiàn)程此時(shí)已經(jīng)開(kāi)始處理了該請求,客戶(hù)端按一定時(shí)間間隔發(fā)送請求給服務(wù)端,問(wèn)詢(xún)請求是否處理完成,但是服務(wù)端也是分布式,請求時(shí)隨機發(fā)送,客戶(hù)端的問(wèn)詢(xún)可能會(huì )分發(fā)到別的服務(wù)器,因此這樣的請求,我會(huì )在客戶(hù)端記錄下處理的服務(wù)端ip地址和線(xiàn)程id,在問(wèn)詢(xún)的時(shí)候就會(huì )訪(fǎng)問(wèn)指定好的服務(wù)器和線(xiàn)程,直到請求處理完畢,最后關(guān)閉詢(xún)問(wèn),將結果返回給用戶(hù)。
由于我們把一個(gè)網(wǎng)站項目拆分成了三個(gè)獨立項目,因此在項目管理和協(xié)調上增加了難度,所以我們引入maven框架對工程進(jìn)行了管理和構建,同時(shí)構建一個(gè)common工程,專(zhuān)門(mén)負責服務(wù)端和前端公共程序的開(kāi)發(fā)。
本框架將展示層和業(yè)務(wù)處理層徹底分開(kāi),因此客戶(hù)端工程師可以專(zhuān)心做客戶(hù)端,服務(wù)端工程師專(zhuān)心做服務(wù)端,大家只要學(xué)習如何封裝通訊協(xié)議就行,因此很利于項目組人員的橫向擴展。
以上就是本人為公司網(wǎng)站設計的技術(shù)架構,這里和大伙分享下,不知道好不好,希望各位大牛能給點(diǎn)建設性的意見(jiàn)。