最近一直在研究高并發(fā)架構的設計,看了很多關于SOA設計思想,dubbo+zookeeper的分布式服務設計,mq等等,但目前項目處于初步期,還沒上線,不能預估用戶數量以及將來的并發(fā)數量,所以為了節(jié)約成本(老板吝嗇),快速上線項目,我們項目依舊處于集中式,沒有分模塊,沒有分表分庫,只是提高了集中式項目的一個并發(fā)處理。
首先我們來看一下項目整體的架構(很不規(guī)范,湊合著看)
我們先介紹下架構中的技術選型為什么這么選。
1.使用nginx進行反向代理實現(xiàn)負載均衡而不使用其他的。網上有很多種實現(xiàn)負載均衡的軟硬件方案,其中F5,apache的負載均衡,lvs的負載均衡為什么我們都不選?F5,沒錢。apache,復雜,在高并發(fā)上性能低于nginx。lvs,沒怎么了解,直接拋棄了。
2.使用redis作為緩存。redis跟mencache,ehcache選哪個一直都是人們所頭疼的。首先ehcache是存在于本地內存的,多個tomcat做負載的時候就特別麻煩了。mencache是支持多線程的緩存,但它只支持一種數據結構---key-value,這使我們在使用它的時候會有很多瓶頸。redis分布式緩存,提供了多種數據結構的存儲,雖然它只支持單線程訪問,但速度不亞于mencache。
3.mysql我們使用的是5.6的版本,主要是支持事務,顏表情等功能,沒啥好說的
4.至于mysql主從處理(代碼層),我們是在mybatis層面定義兩個mapper,一個讀,一個寫,人工操作,沒啥復用性,就是為了項目趕緊上線。(想實現(xiàn)高可用,隨時加從庫的話可以使用一些中間件,例如mysql-proxy,當然使用中間件效率相對就會下來一點)
接下來講一下架構
1.首先我們前端是構造了一個虛擬IP(暴露給用戶)進行主熱雙備,然后連接到一個nginx,在nginx進行請求過濾,比如惡意的壓力測試之類的行為(百度有很多解決方案,例如lua腳本,redis黑白名單等)。通過nginx進行反向代理把請求分發(fā)給各個tomcat(可以通過配置權重,輪詢方式配置分發(fā)),此處的tomcat可以根據需求設置多個(一臺mysql大概每秒能撐2000個并發(fā),所以自己看著辦啦)。
2.到了tomcat層后,我們會先把請求分為兩種,一種是查詢請求,一種是更新請求。
1)其中查詢請求先會訪問redis緩存(減少mysql壓力,提高并發(fā)),若命中則返回數據給用戶,若不命中則查詢mysql(從庫:myisam引擎,只讀庫,提高讀取效率),并把查詢結果set到redis中
2)更新請求會發(fā)送到mysql(主庫:innodb,保證事務,數據安全)
3.由于我們項目對于實時性要求不是很高,所以此時可以不用考慮mysql主從復制時的延時性。(網上有很多種解決延時的方案,例如緩存,中間件等)
4.至于靜態(tài)文件我們存放在自己構建的cdn上,也是為了提升訪問效率
最后講一下sql
1.設計表的時候適當的加些冗余字段,這樣會少了很多的連表查詢(當然冗余字段改變了對項目需求影響不大或冗余字段不會改變的情況下)
2.預估好字段大小,畢竟定義好字段大小后mysql就給該字段定義了相對大小的空間,定義過大會很浪費資源。當然也避免定義一些沒用的字段
3.適當索引,當然跟廢話差不多啦,加索引的技巧也很多,上網搜搜。
4.不是一條sql搞定全部就是好,有時候把大的sql拆分成小的sql效率會高很多
大概就講這么多啦,當然這里面還有很多需要優(yōu)化的東西,以后會陸續(xù)跟大家分享的