基於非同步IO框架Tornado的開源分散式部落格blog_xtg

weixin_34337265發表於2017-04-17

blog_xtg是我個人寫的一個開源分散式部落格,其web框架使用的是tornado(一個基於非同步IO的python web框架)。同時我把它設計成一個可以多程式多主機部署的分散式架構,如果你對非同步IO的web框架感興趣,或者對高併發分散式的架構感興趣並處於入門階段,那麼很希望你來嘗試blog_xtg,一定會有所收穫。

一、為什麼寫blog_xtg

作為一個碼農怎麼能沒有一個屬於自己的個人部落格呢?即便沒人看,作為日記來記錄編碼生涯也是很有必要。其實開源的blog有很多,比如WordPress、LifeType等等,但是There are a thousand Hamlets in a thousand people's eyes(一千個讀者眼裡有一千個哈姆雷特),所以我還是喜歡自己寫屬於自己的"哈姆雷特"。既然要做新專案,那不用點新東西就會覺得沒有意義。恰逢當時淘寶雙11,雙11會場的頁面都是由node.js支撐,node.js做web專案最大的特點就是非同步IO,我js不怎麼熟,我就選擇了python的非同步IO框架tornado。但是單個tornado例項無法充分利用多核CPU的資源,所以就實現了blog_xtg這樣一個簡單的基於tornado的分散式架構部落格。

二、blog_xtg簡介

首先非常感謝開源部落格Blog_mini,因為整個blog_xtg是基於Blog_mini重構的。

我不太擅長前端,所以基本照搬Blog_mini的頁面,但是整個後端邏輯都是重寫的,以下是與Blog_mini的主要區別:

  1. 改用tornado框架,是個基於非同步IO的web server。
  2. 分散式架構,可以多程式多主機啟動server例項,再通過nginx等代理伺服器做負載均衡,實現橫向擴充套件提高併發效能。
  3. 提高多數主要頁面訪問效能。對頻繁查詢的元件(例如部落格標題、選單、公告、訪問統計)進行快取,優化sql查詢(多條sql語句合併一次執行、僅查需要的欄位,例如搜尋博文列表不查博文的具體內容)以提高首頁博文等主要頁面訪問效能。
  4. 訪問統計改為日pv和日uv。
  5. 博文編輯器改為markdown編輯器。
  6. 引入alembic管理資料庫版本。
  7. 可使用docker快速部署。

但是,作為一個個人blog,其實並不需要分散式的架構,即便引入了這樣的架構,我依然希望其他開發者能夠快捷的搭建環境並上手使用,因此blog_xtg只是簡單的實現了分散式,並不能保證絕對的高可用,主從需要啟動例項時手動指定,存在單點故障的可能,如果有開發者希望以此架構擴充套件到大型生產環境請自行配合zookeeper等實現動態選主+完整的日誌分析、效能監控以及完善報警機制來保證高可用。

三、blog_xtg部署與開發環境搭建

1. 如果你熟悉docker,那麼可以用docker來快速部署。

#新建資料庫(理論上支援sqlalchemy支援的所有資料庫,表會自動建立更新)
#搭建redis
#下載config.py並編輯相關配置(修改資料庫、redis、日誌等)
curl -o xxx/config.py https://raw.githubusercontent.com/xtg20121013/blog_xtg/master/config.py
#通過docker啟動後即可訪問
docker run -d -p 80:80 --restart=always --name blog_xtg -v xxx/config.py:/home/xtg/blog-xtg/config.py daocloud.io/xtg20121013/blog_xtg:latest

這個映象啟動時包含兩個server例項(一主一從)+nginx(動靜分離、負載均衡)+supervisor(程式管理),當然你也可以根據自己的需求構建映象,Dockerfile在專案/docker目錄下。

2. 構建執行環境

需要安裝以下元件:
  1. python2.7(python3 沒試過,不知道行不行)
  2. mysql(或者其他sqlalchemy支援的資料庫)
  3. redis
clone專案,安裝依賴:
git clone https://github.com/xtg20121013/blog_xtg.git
#專案依賴(如果用的不是mysql可以將MySQL-python替換使用的資料庫成所對應的依賴包)
pip install -r requirements.txt
建立資料庫
啟動redis
修改config.py,配置資料庫、redis、日誌等
建立資料庫或更新表
python main.py upgradedb
啟動server
python main.py --master=true --port=8888
初始化管理員賬戶

訪問[host]/super/init註冊管理員賬號。

注:僅沒有任何管理員時才可以訪問到該頁面。

四、開發注意事項

blog_xtg是個非同步IO的架構,相對於常見的同步IO框架,需要注意以下幾點:

  • IO密集型的操作請務必使用非同步的client,否則無法利用到非同步的優勢
  • 由於多數非同步IO的框架都是單執行緒的,所以對於CPU密集型的操作最好交由外部系統處理,防止阻塞,大型專案可以配合訊息佇列使用更佳
  • 如果必須用同步的IO元件,可以配合執行緒池使用(blog_xtg中使用了sqlalchemy就是配合執行緒池使用的)
  • 如果你是ORM+執行緒池使用(blog_xtg中就是sqlalchemy+執行緒池),一般的ORM都有lazy load的機制,在非同步框架中請勿使用,因為lazy load的執行在主執行緒中,很可能會阻塞主執行緒,影響別的請求。

blog_xtg是分散式的架構,相對於單程式的專案一般需要注意以下幾點:

  • 多例項間的日誌衝突。
  • 多例項間的快取同步。
  • 多例項間的session同步。
  • 多例項間主從關係,例如一些定時任務可能主需要叢集中一個節點處理。

當然以上幾點都可以從blog_xtg的原始碼中找到至少一種解決方案。

如果你對非同步IO的web框架、分散式的架構感興趣,或者想對blog_xtg做二次開發,那麼你可以閱讀以下blog_xtg的其他相關博文,並配合原始碼學習,一定會很快掌握。

  1. 開源部落格blog_xtg技術架構-非阻塞IO web框架tornado

五、技術支援

如果你有任何疑問,可以給我留言:

附:


歡迎來我的個人部落格逛逛: https://blog.52xtg.com

相關文章