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的主要區別:
- 改用tornado框架,是個基于異步IO的web server。
- 分布式架構,可以多進程多主機啟動server實例,再通過nginx等代理服務器做負載均衡,實現橫向擴展提高并發性能。
- 提高多數主要頁面訪問性能。對頻繁查詢的組件(例如博客標題、菜單、公告、訪問統計)進行緩存,優化sql查詢(多條sql語句合并一次執行、僅查需要的字段,例如搜索博文列表不查博文的具體內容)以提高首頁博文等主要頁面訪問性能。
- 訪問統計改為日pv和日uv。
- 博文編輯器改為markdown編輯器。
- 引入alembic管理數據庫版本。
- 可使用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. 構建運行環境
需要安裝以下組件:
- python2.7(python3 沒試過,不知道行不行)
- mysql(或者其他sqlalchemy支持的數據庫)
- 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的其他相關博文,并配合源代碼學習,一定會很快掌握。
五、技術支持
如果你有任何疑問,可以給我留言:
附:
blog_xtg的github地址:https://github.com/xtg20121013/blog_xtg
歡迎來我的個人博客逛逛: https://blog.52xtg.com