如何解決高并發(fā)問題

一個小型的網(wǎng)站,比如個人網(wǎng)站九秀,可以使用最簡單的html靜態(tài)頁面就實(shí)現(xiàn)了遗嗽,配合一些圖片達(dá)到美化效果,所有的頁面均存放在一個目錄下鼓蜒,這樣的網(wǎng)站對系統(tǒng)架構(gòu)痹换、性能的要求都很簡單,隨著互聯(lián)網(wǎng)業(yè)務(wù)的不斷豐富都弹,網(wǎng)站相關(guān)的技術(shù)經(jīng)過這些年的發(fā)展娇豫,已經(jīng)細(xì)分到很細(xì)的方方面面,尤其對于大型網(wǎng)站來說畅厢,所采用的技術(shù)更是涉及面非常廣冯痢,從硬件到軟件、編程語言框杜、數(shù)據(jù)庫浦楣、WebServer、防火墻等各個領(lǐng)域都有了很高的要求咪辱,已經(jīng)不是原來簡單的html靜態(tài)網(wǎng)站所能比擬的振劳。

大型網(wǎng)站,比如門戶網(wǎng)站油狂。在面對大量用戶訪問历恐、高并發(fā)請求方面,基本的解決方案集中在這樣幾個環(huán)節(jié):使用高性能的服務(wù)器专筷、高性能的數(shù)據(jù)庫弱贼、高效率的編程語言、還有高性能的Web容器仁堪。但是除了這幾個方面哮洽,還沒法根本解決大型網(wǎng)站面臨的高負(fù)載和高并發(fā)問題。

上面提供的幾個解決思路在一定程度上也意味著更大的投入弦聂,并且這樣的解決思路具備瓶頸鸟辅,沒有很好的擴(kuò)展性氛什,下面我從低成本、高性能和高擴(kuò)張性的角度來說說我的一些經(jīng)驗(yàn)匪凉。

1枪眉、HTML靜態(tài)化

其實(shí)大家都知道,效率最高再层、消耗最小的就是純靜態(tài)化的html頁面贸铜,所以我們盡可能使我們的網(wǎng)站上的頁面采用靜態(tài)頁面來實(shí)現(xiàn),這個最簡單的方法其實(shí)也是最有效的方法聂受。但是對于大量內(nèi)容并且頻繁更新的網(wǎng)站蒿秦,我們無法全部手動去挨個實(shí)現(xiàn),于是出現(xiàn)了我們常見的信息發(fā)布系統(tǒng)CMS蛋济,像我們常訪問的各個門戶站點(diǎn)的新聞頻道棍鳖,甚至他們的其他頻道,都是通過信息發(fā)布系統(tǒng)來管理和實(shí)現(xiàn)的碗旅,信息發(fā)布系統(tǒng)可以實(shí)現(xiàn)最簡單的信息錄入自動生成靜態(tài)頁面渡处,還能具備頻道管理、權(quán)限管理祟辟、自動抓取等功能医瘫,對于一個大型網(wǎng)站來說,擁有一套高效旧困、可管理的CMS是必不可少的醇份。

除了門戶和信息發(fā)布類型的網(wǎng)站,對于交互性要求很高的社區(qū)類型網(wǎng)站來說叮喳,盡可能的靜態(tài)化也是提高性能的必要手段被芳,將社區(qū)內(nèi)的帖子缰贝、文章進(jìn)行實(shí)時(shí)的靜態(tài)化馍悟,有更新的時(shí)候再重新靜態(tài)化也是大量使用的策略,像Mop的大雜燴就是使用了這樣的策略剩晴,網(wǎng)易社區(qū)等也是如此锣咒。

同時(shí),html靜態(tài)化也是某些緩存策略使用的手段赞弥,對于系統(tǒng)中頻繁使用數(shù)據(jù)庫查詢但是內(nèi)容更新很小的應(yīng)用毅整,可以考慮使用html靜態(tài)化來實(shí)現(xiàn),比如論壇中論壇的公用設(shè)置信息绽左,這些信息目前的主流論壇都可以進(jìn)行后臺管理并且存儲再數(shù)據(jù)庫中悼嫉,這些信息其實(shí)大量被前臺程序調(diào)用,但是更新頻率很小拼窥,可以考慮將這部分內(nèi)容進(jìn)行后臺更新的時(shí)候進(jìn)行靜態(tài)化戏蔑,這樣避免了大量的數(shù)據(jù)庫訪問請求蹋凝。

2、圖片服務(wù)器分離

大家知道总棵,對于Web服務(wù)器來說鳍寂,不管是Apache、IIS還是其他容器情龄,圖片是最消耗資源的迄汛,于是我們有必要將圖片與頁面進(jìn)行分離,這是基本上大型網(wǎng)站都會采用的策略骤视,他們都有獨(dú)立的圖片服務(wù)器鞍爱,甚至很多臺圖片服務(wù)器。這樣的架構(gòu)可以降低提供頁面訪問請求的服務(wù)器系統(tǒng)壓力专酗,并且可以保證系統(tǒng)不會因?yàn)閳D片問題而崩潰硬霍,在應(yīng)用服務(wù)器和圖片服務(wù)器上,可以進(jìn)行不同的配置優(yōu)化笼裳,比如apache在配置ContentType的時(shí)候可以盡量少支持唯卖,盡可能少的LoadModule,保證更高的系統(tǒng)消耗和執(zhí)行效率躬柬。

3拜轨、數(shù)據(jù)庫集群和庫表散列

大型網(wǎng)站都有復(fù)雜的應(yīng)用,這些應(yīng)用必須使用數(shù)據(jù)庫允青,那么在面對大量訪問的時(shí)候橄碾,數(shù)據(jù)庫的瓶頸很快就能顯現(xiàn)出來,這時(shí)一臺數(shù)據(jù)庫將很快無法滿足應(yīng)用颠锉,于是我們需要使用數(shù)據(jù)庫集群或者庫表散列法牲。

在數(shù)據(jù)庫集群方面,很多數(shù)據(jù)庫都有自己的解決方案琼掠,Oracle拒垃、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是類似的方案瓷蛙,您使用了什么樣的DB悼瓮,就參考相應(yīng)的解決方案來實(shí)施即可。

上面提到的數(shù)據(jù)庫集群由于在架構(gòu)艰猬、成本横堡、擴(kuò)張性方面都會受到所采用DB類型的限制,于是我們需要從應(yīng)用程序的角度來考慮改善系統(tǒng)架構(gòu)冠桃,庫表散列是常用并且最有效的解決方案命贴。我們在應(yīng)用程序中安裝業(yè)務(wù)和應(yīng)用或者功能模塊將數(shù)據(jù)庫進(jìn)行分離,不同的模塊對應(yīng)不同的數(shù)據(jù)庫或者表,再按照一定的策略對某個頁面或者功能進(jìn)行更小的數(shù)據(jù)庫散列胸蛛,比如用戶表培己,按照用戶ID進(jìn)行表散列,這樣就能夠低成本的提升系統(tǒng)的性能并且有很好的擴(kuò)展性胚泌。sohu的論壇就是采用了這樣的架構(gòu)省咨,將論壇的用戶、設(shè)置玷室、帖子等信息進(jìn)行數(shù)據(jù)庫分離零蓉,然后對帖子、用戶按照板塊和ID進(jìn)行散列數(shù)據(jù)庫和表穷缤,最終可以在配置文件中進(jìn)行簡單的配置便能讓系統(tǒng)隨時(shí)增加一臺低成本的數(shù)據(jù)庫進(jìn)來補(bǔ)充系統(tǒng)性能敌蜂。

4、緩存

緩存一詞搞技術(shù)的都接觸過津肛,很多地方用到緩存章喉。網(wǎng)站架構(gòu)和網(wǎng)站開發(fā)中的緩存也是非常重要。這里先講述最基本的兩種緩存身坐。高級和分布式的緩存在后面講述秸脱。
架構(gòu)方面的緩存,對Apache比較熟悉的人都能知道Apache提供了自己的緩存模塊部蛇,也可以使用外加的Squid模塊進(jìn)行緩存摊唇,這兩種方式均可以有效的提高Apache的訪問響應(yīng)能力。
網(wǎng)站程序開發(fā)方面的緩存涯鲁,Linux上提供的Memory Cache是常用的緩存接口巷查,可以在web開發(fā)中使用,比如用Java開發(fā)的時(shí)候就可以調(diào)用MemoryCache對一些數(shù)據(jù)進(jìn)行緩存和通訊共享抹腿,一些大型社區(qū)使用了這樣的架構(gòu)岛请。另外,在使用web語言開發(fā)的時(shí)候警绩,各種語言基本都有自己的緩存模塊和方法崇败,PHP有Pear的Cache模塊,Java就更多了房蝉,.net不是很熟悉僚匆,相信也肯定有。

5搭幻、鏡像

鏡像是大型網(wǎng)站常采用的提高性能和數(shù)據(jù)安全性的方式,鏡像的技術(shù)可以解決不同網(wǎng)絡(luò)接入商和地域帶來的用戶訪問速度差異逞盆,比如ChinaNet和EduNet之間的差異就促使了很多網(wǎng)站在教育網(wǎng)內(nèi)搭建鏡像站點(diǎn)檀蹋,數(shù)據(jù)進(jìn)行定時(shí)更新或者實(shí)時(shí)更新。在鏡像的細(xì)節(jié)技術(shù)方面,這里不闡述太深俯逾,有很多專業(yè)的現(xiàn)成的解決架構(gòu)和產(chǎn)品可選贸桶。也有廉價(jià)的通過軟件實(shí)現(xiàn)的思路,比如Linux上的rsync等工具桌肴。

6皇筛、負(fù)載均衡

負(fù)載均衡將是大型網(wǎng)站解決高負(fù)荷訪問和大量并發(fā)請求采用的終極解決辦法。

負(fù)載均衡技術(shù)發(fā)展了多年坠七,有很多專業(yè)的服務(wù)提供商和產(chǎn)品可以選擇水醋,我個人接觸過一些解決方法,其中有兩個架構(gòu)可以給大家做參考彪置。

1)硬件四層交換

第四層交換使用第三層和第四層信息包的報(bào)頭信息拄踪,根據(jù)應(yīng)用區(qū)間識別業(yè)務(wù)流,將整個區(qū)間段的業(yè)務(wù)流分配到合適的應(yīng)用服務(wù)器進(jìn)行處理拳魁。 第四層交換功能就象是虛IP惶桐,指向物理服務(wù)器。它傳輸?shù)臉I(yè)務(wù)服從的協(xié)議多種多樣潘懊,有HTTP姚糊、FTP、NFS授舟、Telnet或其他協(xié)議叛拷。這些業(yè)務(wù)在物理服務(wù)器基礎(chǔ)上,需要復(fù)雜的載量平衡算法岂却。在IP世界忿薇,業(yè)務(wù)類型由終端TCP或UDP端口地址來決定,在第四層交換中的應(yīng)用區(qū)間則由源端和終端IP地址躏哩、TCP和UDP端口共同決定署浩。

在硬件四層交換產(chǎn)品領(lǐng)域,有一些知名的產(chǎn)品可以選擇扫尺,比如Alteon筋栋、F5等,這些產(chǎn)品很昂貴正驻,但是物有所值弊攘,能夠提供非常優(yōu)秀的性能和很靈活的管理能力。Yahoo中國當(dāng)初接近2000臺服務(wù)器使用了三四臺Alteon就搞定了姑曙。

2)軟件四層交換

大家知道了硬件四層交換機(jī)的原理后襟交,基于OSI模型來實(shí)現(xiàn)的軟件四層交換也就應(yīng)運(yùn)而生,這樣的解決方案實(shí)現(xiàn)的原理一致伤靠,不過性能稍差捣域。但是滿足一定量的壓力還是游刃有余的,有人說軟件實(shí)現(xiàn)方式其實(shí)更靈活,處理能力完全看你配置的熟悉能力焕梅。

軟件四層交換我們可以使用Linux上常用的LVS來解決迹鹅,LVS就是Linux Virtual Server,他提供了基于心跳線heartbeat的實(shí)時(shí)災(zāi)難應(yīng)對解決方案贞言,提高系統(tǒng)的魯棒性斜棚,同時(shí)可供了靈活的虛擬VIP配置和管理功能,可以同時(shí)滿足多種應(yīng)用需求该窗,這對于分布式的系統(tǒng)來說必不可少弟蚀。

一個典型的使用負(fù)載均衡的策略就是,在軟件或者硬件四層交換的基礎(chǔ)上搭建squid集群挪捕,這種思路在很多大型網(wǎng)站包括搜索引擎上被采用粗梭,這樣的架構(gòu)低成本、高性能還有很強(qiáng)的擴(kuò)張性级零,隨時(shí)往架構(gòu)里面增減節(jié)點(diǎn)都非常容易断医。這樣的架構(gòu)我準(zhǔn)備空了專門詳細(xì)整理一下和大家探討。

一:高并發(fā)高負(fù)載類網(wǎng)站關(guān)注點(diǎn)之?dāng)?shù)據(jù)庫

沒錯,首先是數(shù)據(jù)庫,這是大多數(shù)應(yīng)用所面臨的首個SPOF奏纪。尤其是Web2.0的應(yīng)用鉴嗤,數(shù)據(jù)庫的響應(yīng)是首先要解決的。
一般來說MySQL是最常用的序调,可能最初是一個mysql主機(jī)醉锅,當(dāng)數(shù)據(jù)增加到100萬以上卒密,那么藻治,MySQL的效能急劇下降酣难。常用的優(yōu)化措施是M-S(主-從)方式進(jìn)行同步復(fù)制孽糖,將查詢和操作和分別在不同的服務(wù)器上進(jìn)行操作。我推薦的是M-M-Slaves方式钧汹,2個主Mysql猴娩,多個Slaves钟些,需要注意的是墩朦,雖然有2個Master坯认,但是同時(shí)只有1個是Active,我們可以在一定時(shí)候切換氓涣。之所以用2個M牛哺,是保證M不會又成為系統(tǒng)的SPOF。
Slaves可以進(jìn)一步負(fù)載均衡劳吠,可以結(jié)合LVS,從而將select操作適當(dāng)?shù)钠胶獾讲煌膕laves上引润。
以上架構(gòu)可以抗衡到一定量的負(fù)載,但是隨著用戶進(jìn)一步增加赴背,你的用戶表數(shù)據(jù)超過1千萬椰拒,這時(shí)那個M變成了SPOF晶渠。你不能任意擴(kuò)充Slaves凰荚,否則復(fù)制同步的開銷將直線上升燃观,怎么辦?我的方法是表分區(qū)便瑟,從業(yè)務(wù)層面上進(jìn)行分區(qū)缆毁。最簡單的,以用戶數(shù)據(jù)為例到涂。根據(jù)一定的切分方式脊框,比如id,切分到不同的數(shù)據(jù)庫集群去践啄。

全局?jǐn)?shù)據(jù)庫用于meta數(shù)據(jù)的查詢浇雹。缺點(diǎn)是每次查詢,會增加一次屿讽,比如你要查一個用戶nightsailer,你首先要到全局?jǐn)?shù)據(jù)庫群找到nightsailer對應(yīng)的cluster id昭灵,然后再到指定的cluster找到nightsailer的實(shí)際數(shù)據(jù)。
每個cluster可以用m-m方式伐谈,或者m-m-slaves方式烂完。這是一個可以擴(kuò)展的結(jié)構(gòu),隨著負(fù)載的增加诵棵,你可以簡單的增加新的mysql cluster進(jìn)去抠蚣。

需要注意的是:
1、禁用全部auto_increment的字段
2履澳、id需要采用通用的算法集中分配
3嘶窄、要具有比較好的方法來監(jiān)控mysql主機(jī)的負(fù)載和服務(wù)的運(yùn)行狀態(tài)。如果你有30臺以上的mysql數(shù)據(jù)庫在跑就明白我的意思了距贷。
4柄冲、不要使用持久性鏈接(不要用pconnect),相反,使用sqlrelay這種第三方的數(shù)據(jù)庫鏈接池储耐,或者干脆自己做羊初,因?yàn)閜hp4中mysql的鏈接池經(jīng)常出問題。
二:高并發(fā)高負(fù)載網(wǎng)站的系統(tǒng)架構(gòu)之HTML靜態(tài)化

其實(shí)大家都知道什湘,效率最高长赞、消耗最小的就是純靜態(tài)化 http://www.ablanxue.com/shtml/201207/776.shtml的html頁面,所以我們盡可能使我們的網(wǎng)站上的頁面采用靜態(tài)頁面來實(shí)現(xiàn)闽撤,這個最簡單的方法其實(shí)也是 最有效的方法得哆。但是對于大量內(nèi)容并且頻繁更新的網(wǎng)站,我們無法全部手動去挨個實(shí)現(xiàn)哟旗,于是出現(xiàn)了我們常見的信息發(fā)布系統(tǒng)CMS贩据,像我們常訪問的各個門戶站點(diǎn) 的新聞頻道栋操,甚至他們的其他頻道,都是通過信息發(fā)布系統(tǒng)來管理和實(shí)現(xiàn)的饱亮,信息發(fā)布系統(tǒng)可以實(shí)現(xiàn)最簡單的信息錄入自動生成靜態(tài)頁面矾芙,還能具備頻道管理、權(quán)限 管理近上、自動抓取等功能剔宪,對于一個大型網(wǎng)站來說,擁有一套高效壹无、可管理的CMS是必不可少的葱绒。

除了門戶和信息發(fā)布類型的網(wǎng)站,對于交互性要求很高的社區(qū)類型網(wǎng)站來說斗锭,盡可能的靜態(tài)化也是提高性能的必要手段地淀,將社區(qū)內(nèi)的帖子、文章進(jìn)行實(shí)時(shí)的靜態(tài)化岖是,有更新的時(shí)候再重新靜態(tài)化也是大量使用的策略帮毁,像Mop的大雜燴就是使用了這樣的策略,網(wǎng)易社區(qū)等也是如此璧微。

同時(shí)作箍,html靜態(tài)化也是某些緩存策略使用的手段,對于系統(tǒng)中頻繁使用數(shù)據(jù)庫查詢但是內(nèi)容更新很小的應(yīng)用前硫,可以考慮使用html靜態(tài)化來實(shí)現(xiàn)胞得,比如論壇 中論壇的公用設(shè)置信息,這些信息目前的主流論壇都可以進(jìn)行后臺管理并且存儲再數(shù)據(jù)庫中屹电,這些信息其實(shí)大量被前臺程序調(diào)用阶剑,但是更新頻率很小,可以考慮將這 部分內(nèi)容進(jìn)行后臺更新的時(shí)候進(jìn)行靜態(tài)化危号,這樣避免了大量的數(shù)據(jù)庫訪問請求高并發(fā)牧愁。

網(wǎng)站HTML靜態(tài)化解決方案
當(dāng)一個Servlet資源請求到達(dá)WEB服務(wù)器之后我們會填充指定的JSP頁面來響應(yīng)請求:

HTTP請求---Web服務(wù)器---Servlet--業(yè)務(wù)邏輯處理--訪問數(shù)據(jù)--填充JSP--響應(yīng)請求

HTML靜態(tài)化之后:

HTTP請求---Web服務(wù)器---Servlet--HTML--響應(yīng)請求

靜態(tài)訪求如下

Servlet:

public void doGet(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
    if(request.getParameter("chapterId") != null){  
        String chapterFileName = "bookChapterRead_"+request.getParameter("chapterId")+".html";  
        String chapterFilePath = getServletContext().getRealPath("/") + chapterFileName;  
        File chapterFile = new File(chapterFilePath);  
        if(chapterFile.exists()){response.sendRedirect(chapterFileName);return;}//如果有這個文件就告訴瀏覽器轉(zhuǎn)向   
        INovelChapterBiz novelChapterBiz = new NovelChapterBizImpl();  
        NovelChapter novelChapter = novelChapterBiz.searchNovelChapterById(Integer.parseInt(request.getParameter("chapterId")));//章節(jié)信息   
        int lastPageId = novelChapterBiz.searchLastCHapterId(novelChapter.getNovelId().getId(), novelChapter.getId());  
        int nextPageId = novelChapterBiz.searchNextChapterId(novelChapter.getNovelId().getId(), novelChapter.getId());  
        request.setAttribute("novelChapter", novelChapter);  
        request.setAttribute("lastPageId", lastPageId);  
        request.setAttribute("nextPageId", nextPageId);  
        new CreateStaticHTMLPage().createStaticHTMLPage(request, response, getServletContext(),   
                chapterFileName, chapterFilePath, "/bookRead.jsp");  
    }  
}  

生成HTML靜態(tài)頁面的類:

package com.jb.y2t034.thefifth.web.servlet;  
import java.io.ByteArrayOutputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.OutputStreamWriter;  
import java.io.PrintWriter;  
import javax.servlet.RequestDispatcher;  
import javax.servlet.ServletContext;  
import javax.servlet.ServletException;  
import javax.servlet.ServletOutputStream;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.HttpServletResponseWrapper;  
/** 
* 創(chuàng)建HTML靜態(tài)頁面 
* 功能:創(chuàng)建HTML靜態(tài)頁面 
* 時(shí)間:2009年1011日 
* 地點(diǎn):home 
* @author mavk 
* 
*/  
public class CreateStaticHTMLPage {  
    /** 
     * 生成靜態(tài)HTML頁面的方法 
     * @param request 請求對象 
     * @param response 響應(yīng)對象 
     * @param servletContext Servlet上下文 
     * @param fileName 文件名稱 
     * @param fileFullPath 文件完整路徑 
     * @param jspPath 需要生成靜態(tài)文件的JSP路徑(相對即可) 
     * @throws IOException 
     * @throws ServletException 
     */  
    public void createStaticHTMLPage(HttpServletRequest request, HttpServletResponse response,ServletContext servletContext,String fileName,String fileFullPath,String jspPath) throws ServletException, IOException{  
        response.setContentType("text/html;charset=gb2312");//設(shè)置HTML結(jié)果流編碼(即HTML文件編碼)   
        RequestDispatcher rd = servletContext.getRequestDispatcher(jspPath);//得到JSP資源   
        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();//用于從ServletOutputStream中接收資源   
        final ServletOutputStream servletOuputStream = new ServletOutputStream(){//用于從HttpServletResponse中接收資源   
            public void write(byte[] b, int off,int len){  
                byteArrayOutputStream.write(b, off, len);  
            }  
            public void write(int b){  
                byteArrayOutputStream.write(b);  
            }  
        };  
        final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream));//把轉(zhuǎn)換字節(jié)流轉(zhuǎn)換成字符流   
        HttpServletResponse httpServletResponse = new HttpServletResponseWrapper(response){//用于從response獲取結(jié)果流資源(重寫了兩個方法)   
            public ServletOutputStream getOutputStream(){  
                return servletOuputStream;  
            }  
            public PrintWriter getWriter(){  
                return printWriter;  
            }  
        };  
        rd.include(request, httpServletResponse);//發(fā)送結(jié)果流   
        printWriter.flush();//刷新緩沖區(qū),把緩沖區(qū)的數(shù)據(jù)輸出   
        FileOutputStream fileOutputStream = new FileOutputStream(fileFullPath);  
        byteArrayOutputStream.writeTo(fileOutputStream);//把byteArrayOuputStream中的資源全部寫入到fileOuputStream中   
        fileOutputStream.close();//關(guān)閉輸出流外莲,并釋放相關(guān)資源   
        response.sendRedirect(fileName);//發(fā)送指定文件流到客戶端   
    }  
} 

三:高并發(fā)高負(fù)載類網(wǎng)站關(guān)注點(diǎn)之緩存猪半、負(fù)載均衡、存儲

緩存是另一個大問題偷线,我一般用memcached來做緩存集群磨确,一般來說部署10臺左右就差不多(10g內(nèi)存池)。需要注意一點(diǎn)声邦,千萬不能用使用
swap乏奥,最好關(guān)閉linux的swap。

負(fù)載均衡/加速

可能上面說緩存的時(shí)候亥曹,有人第一想的是頁面靜態(tài)化邓了,所謂的靜態(tài)html恨诱,我認(rèn)為這是常識,不屬于要點(diǎn)了骗炉。頁面的靜態(tài)化隨之帶來的是靜態(tài)服務(wù)的
負(fù)載均衡和加速照宝。我認(rèn)為Lighttped+Squid是最好的方式了。
LVS <------->lighttped====>squid(s) ====lighttpd

上面是我經(jīng)常用的痕鳍。注意硫豆,我沒有用apache龙巨,除非特定的需求笼呆,否則我不部署apache,因?yàn)槲乙话阌胮hp-fastcgi配合lighttpd,
性能比apache+mod_php要強(qiáng)很多旨别。

squid的使用可以解決文件的同步等等問題诗赌,但是需要注意,你要很好的監(jiān)控緩存的命中率秸弛,盡可能的提高的90%以上铭若。
squid和lighttped也有很多的話題要討論,這里不贅述递览。

存儲
存儲也是一個大問題叼屠,一種是小文件的存儲,比如圖片這類绞铃。另一種是大文件的存儲镜雨,比如搜索引擎的索引,一般單文件都超過2g以上儿捧。
小文件的存儲最簡單的方法是結(jié)合lighttpd來進(jìn)行分布荚坞。或者干脆使用Redhat的GFS菲盾,優(yōu)點(diǎn)是應(yīng)用透明颓影,缺點(diǎn)是費(fèi)用較高。我是指
你購買盤陣的問題懒鉴。我的項(xiàng)目中诡挂,存儲量是2-10Tb,我采用了分布式存儲临谱。這里要解決文件的復(fù)制和冗余璃俗。
這樣每個文件有不同的冗余,這方面可以參考google的gfs的論文吴裤。
大文件的存儲旧找,可以參考nutch的方案,現(xiàn)在已經(jīng)獨(dú)立為hadoop子項(xiàng)目麦牺。(你可以google it)

其他:
此外钮蛛,passport等也是考慮的鞭缭,不過都屬于比較簡單的了。
四:高并發(fā)高負(fù)載網(wǎng)站的系統(tǒng)架構(gòu)之圖片服務(wù)器分離 大家知道魏颓,對于Web 服務(wù)器來說岭辣,不管是Apache、IIS還是其他容器甸饱,圖片是最消耗資源的沦童,于是我們有必要將圖片與頁面進(jìn)行分離,這是基本上大型網(wǎng)站都會采用的策略叹话,他 們都有獨(dú)立的圖片服務(wù)器偷遗,甚至很多臺圖片服務(wù)器。這樣的架構(gòu)可以降低提供頁面訪問請求的服務(wù)器系統(tǒng)壓力驼壶,并且可以保證系統(tǒng)不會因?yàn)閳D片問題而崩潰氏豌,在應(yīng)用 服務(wù)器和圖片服務(wù)器上,可以進(jìn)行不同的配置優(yōu)化热凹,比如apache在配置ContentType的時(shí)候可以盡量少支持泵喘,盡可能少的LoadModule, 保證更高的系統(tǒng)消耗和執(zhí)行效率般妙。

利用Apache實(shí)現(xiàn)圖片服務(wù)器的分離
緣由:
起步階段的應(yīng)用纪铺,都可能部署在一臺服務(wù)器上(費(fèi)用上的原因)
第一個優(yōu)先分離的,肯定是數(shù)據(jù)庫和應(yīng)用服務(wù)器碟渺。
第二個分離的鲜锚,會是什么呢?各有各的考慮止状,我所在的項(xiàng)目組重點(diǎn)考慮的節(jié)約帶寬烹棉,服務(wù)器性能再好,帶寬再高怯疤,并發(fā)來了浆洗,也容易撐不住。因此集峦,我這篇文章的重點(diǎn)在這里伏社。這里重點(diǎn)是介紹實(shí)踐,不一定符合所有情況塔淤,供看者參考吧摘昌,
環(huán)境介紹:
WEB應(yīng)用服務(wù)器:4CPU雙核2G, 內(nèi)存4G
部署:Win2003/Apache Http Server 2.1/Tomcat6
數(shù)據(jù)庫服務(wù)器:4CPU雙核2G, 內(nèi)存4G
部署:Win2003/MSSQL2000
步驟:
步驟一:增加2臺配置為:2CPU雙核2G,內(nèi)存2G普通服務(wù)器高蜂,做資源服務(wù)器
部署:Tomcat6聪黎,跑了一個圖片上傳的簡單應(yīng)用,(記得指定web.xml的<distributable/>)备恤,并指定域名為res1..com,res2..com稿饰,采用ajp協(xié)議
步驟二:修改Apache httpd.conf配置
原來應(yīng)用的文件上傳功能網(wǎng)址為:
1锦秒、/fileupload.html
2、/otherupload.html
在httpd.conf中增加如下配置

<VirtualHost *:80>   
  ServerAdmin webmaster@***.com   
  ProxyPass /fileupload.html balancer://rescluster/fileupload lbmethod=byrequests stickysession=JSESSIONID nofailover=Off timeout=5 maxattempts=3      
  ProxyPass /otherupload.html balancer://rescluster/otherupload.html lbmethod=byrequests stickysession=JSESSIONID nofailover=Off timeout=5 maxattempts=3      
  #<!--負(fù)載均衡-->   
  <Proxy balancer://rescluster/>   
    BalancerMember ajp://res1.***.com:8009 smax=5 max=500 ttl=120 retry=300 loadfactor=100 route=tomcat1  
    BalancerMember ajp://res2.***.com:8009 smax=5 max=500 ttl=120 retry=300 loadfactor=100 route=tomcat2  
  </Proxy>   

< /VirtualHost>  

步驟三喉镰,修改業(yè)務(wù)邏輯:
所有上傳文件在數(shù)據(jù)庫中均采用全url的方式保存旅择,例如產(chǎn)品圖片路徑存成:http://res1.***.com/upload/20090101/product120302005.jpg

現(xiàn)在,你可以高枕無憂了侣姆,帶寬不夠時(shí)生真,增加個幾十臺圖片服務(wù)器,只需要稍微修改一下apache的配置文件捺宗,即可柱蟀。

五:高并發(fā)高負(fù)載網(wǎng)站的系統(tǒng)架構(gòu)之?dāng)?shù)據(jù)庫集群和庫表散列

大型網(wǎng)站都有復(fù)雜的應(yīng)用,這些應(yīng)用必須使用數(shù)據(jù)庫偿凭,那么在面對大量訪問的時(shí)候产弹,數(shù)據(jù)庫的瓶頸很快就能顯現(xiàn)出來,這時(shí)一臺數(shù)據(jù)庫將很快無法滿足應(yīng)用弯囊,于是我們需要使用數(shù)據(jù)庫集群或者庫表散列。

在數(shù)據(jù)庫集群方面胶果,很多數(shù)據(jù)庫都有自己的解決方案匾嘱,Oracle、Sybase等都有很好的方案早抠,常用的MySQL提供的Master/Slave也是類似的方案霎烙,您使用了什么樣的DB,就參考相應(yīng)的解決方案來實(shí)施即可蕊连。

上面提到的數(shù)據(jù)庫集群由于在架構(gòu)悬垃、成本、擴(kuò)張性方面都會受到所采用DB類型的限制甘苍,于是我們需要從應(yīng)用程序的角度來考慮改善系統(tǒng)架構(gòu)尝蠕,庫表散列是常用并 且最有效的解決方案。我們在應(yīng)用程序中安裝業(yè)務(wù)和應(yīng)用或者功能模塊將數(shù)據(jù)庫進(jìn)行分離载庭,不同的模塊對應(yīng)不同的數(shù)據(jù)庫或者表看彼,再按照一定的策略對某個頁面或者 功能進(jìn)行更小的數(shù)據(jù)庫散列,比如用戶表囚聚,按照用戶ID進(jìn)行表散列靖榕,這樣就能夠低成本的提升系統(tǒng)的性能并且有很好的擴(kuò)展性。sohu的論壇就是采用了這樣的 架構(gòu)顽铸,將論壇的用戶茁计、設(shè)置、帖子等信息進(jìn)行數(shù)據(jù)庫分離谓松,然后對帖子星压、用戶按照板塊和ID進(jìn)行散列數(shù)據(jù)庫和表瓶蝴,最終可以在配置文件中進(jìn)行簡單的配置便能讓系 統(tǒng)隨時(shí)增加一臺低成本的數(shù)據(jù)庫進(jìn)來補(bǔ)充系統(tǒng)性能。

集群軟件的分類:
一般來講租幕,集群軟件根據(jù)側(cè)重的方向和試圖解決的問題舷手,分為三大類:高性能集群(High performance cluster,HPC)劲绪、負(fù)載均衡集群(Load balance cluster男窟, LBC),高可用性集群(High availability cluster贾富,HAC)歉眷。
高性能集群(High performance cluster,HPC)颤枪,它是利用一個集群中的多臺機(jī)器共同完成同一件任務(wù)汗捡,使得完成任務(wù)的速度和可靠性都遠(yuǎn)遠(yuǎn)高于單機(jī)運(yùn)行的效果。彌補(bǔ)了單機(jī)性能上的不足畏纲。該集群在天氣預(yù)報(bào)扇住、環(huán)境監(jiān)控等數(shù)據(jù)量大,計(jì)算復(fù)雜的環(huán)境中應(yīng)用比較多盗胀;
負(fù)載均衡集群(Load balance cluster艘蹋, LBC),它是利用一個集群中的多臺單機(jī)票灰,完成許多并行的小的工作女阀。一般情況下,如果一個應(yīng)用使用的人多了屑迂,那么用戶請求的響應(yīng)時(shí)間就會增大浸策,機(jī)器的性能也會受到影響,如果使用負(fù)載均衡集群惹盼,那么集群中任意一臺機(jī)器都能響應(yīng)用戶的請求庸汗,這樣集群就會在用戶發(fā)出服務(wù)請求之后,選擇當(dāng)時(shí)負(fù)載最小逻锐,能夠提供最好的服務(wù)的這臺機(jī)器來接受請求并相應(yīng)夫晌,這樣就可用用集群來增加系統(tǒng)的可用性和穩(wěn)定性。這類集群在網(wǎng)站中使用較多昧诱;
高可用性集群(High availability cluster晓淀,HAC),它是利用集群中系統(tǒng) 的冗余盏档,當(dāng)系統(tǒng)中某臺機(jī)器發(fā)生損壞的時(shí)候凶掰,其他后備的機(jī)器可以迅速的接替它來啟動服務(wù),等待故障機(jī)的維修和返回。最大限度的保證集群中服務(wù)的可用性懦窘。這類系統(tǒng)一般在銀行前翎,電信服務(wù)這類對系統(tǒng)可靠性有高的要求的領(lǐng)域有著廣泛的應(yīng)用。

2 數(shù)據(jù)庫集群的現(xiàn)狀
數(shù)據(jù)庫集群是將計(jì)算機(jī)集群技術(shù)引入到數(shù)據(jù)庫中來實(shí)現(xiàn)的畅涂,盡管各廠商宣稱自己的架構(gòu)如何的完美港华,但是始終不能改變Oracle當(dāng)先,大家追逐的事實(shí)午衰,在集群的解決方案上Oracle RAC還是領(lǐng)先于包括微軟在內(nèi)的其它數(shù)據(jù)庫廠商立宜,它能滿足客戶高可用性、高性能臊岸、數(shù)據(jù)庫負(fù)載均衡和方便擴(kuò)展的需求橙数。
Oracle’s Real Application Cluster (RAC)
Microsoft SQL Cluster Server (MSCS)
IBM’s DB2 UDB High Availability Cluster(UDB)
Sybase ASE High Availability Cluster (ASE)
MySQL High Availability Cluster (MySQL CS)
基于IO的第三方HA(高可用性)集群
當(dāng)前主要的數(shù)據(jù)庫集群技術(shù)有以上六大類,有數(shù)據(jù)庫廠商自己開發(fā)的帅戒;也有第三方的集群公司開發(fā)的灯帮;還有數(shù)據(jù)庫廠商與第三方集群公司合作開發(fā)的,各類集群實(shí)現(xiàn)的功能及架構(gòu)也不盡相同逻住。
RAC(Real Application Cluster钟哥,真正應(yīng)用集群)是Oracle9i數(shù)據(jù)庫中采用的一項(xiàng)新技術(shù),也是Oracle數(shù)據(jù)庫支持網(wǎng)格計(jì)算環(huán)境的核心技術(shù)鄙信。它的出現(xiàn)解決了傳統(tǒng)數(shù)據(jù)庫應(yīng)用中面臨的一個重要問題:高性能、高可伸縮性與低價(jià)格之間的矛盾装诡。在很長一段時(shí)間里,甲骨文都以其實(shí)時(shí)應(yīng)用集群技術(shù)(Real Application Cluster践盼,RAC)統(tǒng)治著集群數(shù)據(jù)庫市場

六:高并發(fā)高負(fù)載網(wǎng)站的系統(tǒng)架構(gòu)之緩存

緩存一詞搞技術(shù)的都接觸過鸦采,很多地方用到緩存。網(wǎng)站架構(gòu)和網(wǎng)站開發(fā)中的緩存也是非常重要咕幻。這里先講述最基本的兩種緩存渔伯。高級和分布式的緩存在后面講述。
  架構(gòu)方面的緩存肄程,對Apache比較熟悉的人都能知道Apache提供了自己的緩存模塊锣吼,也可以使用外加的Squid模塊進(jìn)行緩存,這兩種方式均可以有效的提高Apache的訪問響應(yīng)能力蓝厌。
   網(wǎng)站程序開發(fā)方面的緩存玄叠,Linux上提供的Memory Cache是常用的緩存接口,可以在web開發(fā)中使用拓提,比如用Java開發(fā)的時(shí)候就可以調(diào)用MemoryCache對一些數(shù)據(jù)進(jìn)行緩存和通訊共享读恃,一些大 型社區(qū)使用了這樣的架構(gòu)。另外,在使用web語言開發(fā)的時(shí)候寺惫,各種語言基本都有自己的緩存模塊和方法疹吃,PHP有Pear的Cache模塊,Java就更多 了西雀,.net不是很熟悉萨驶,相信也肯定有。

Java開源緩存框架
JBossCache/TreeCache JBossCache是一個復(fù)制的事務(wù)處理緩存艇肴,它允許你緩存企業(yè)級應(yīng)用數(shù)據(jù)來更好的改善性能腔呜。緩存數(shù)據(jù)被自動復(fù)制,讓你輕松進(jìn)行Jboss服務(wù)器之間的集群工作豆挽。JBossCache能夠通過Jboss應(yīng)用服務(wù)或其他J2EE容器來運(yùn)行一個Mbean服務(wù)育谬,當(dāng)然,它也能獨(dú)立運(yùn)行帮哈。 JBossCache包括兩個模塊:TreeCache和TreeCacheAOP膛檀。 TreeCache --是一個樹形結(jié)構(gòu)復(fù)制的事務(wù)處理緩存。 TreeCacheAOP --是一個“面向?qū)ο蟆本彺婺锸蹋褂肁OP來動態(tài)管理POJO
OSCache OSCache標(biāo)記庫由OpenSymphony設(shè)計(jì)咖刃,它是一種開創(chuàng)性的JSP定制標(biāo)記應(yīng)用,提供了在現(xiàn)有JSP頁面之內(nèi)實(shí)現(xiàn)快速內(nèi)存緩沖的功能憾筏。OSCache是個一個廣泛采用的高性能的J2EE緩存框架嚎杨,OSCache能用于任何Java應(yīng)用程序的普通的緩存解決方案。OSCache有以下特點(diǎn):緩存任何對象氧腰,你可以不受限制的緩存部分jsp頁面或HTTP請求枫浙,任何java對象都可以緩存。 擁有全面的API--OSCache API給你全面的程序來控制所有的OSCache特性古拴。 永久緩存--緩存能隨意的寫入硬盤箩帚,因此允許昂貴的創(chuàng)建(expensive-to-create)數(shù)據(jù)來保持緩存,甚至能讓應(yīng)用重啟黄痪。 支持集群--集群緩存數(shù)據(jù)能被單個的進(jìn)行參數(shù)配置紧帕,不需要修改代碼。 緩存記錄的過期--你可以有最大限度的控制緩存對象的過期,包括可插入式的刷新策略(如果默認(rèn)性能不需要時(shí))。

JCACHE JCACHE是一種即將公布的標(biāo)準(zhǔn)規(guī)范(JSR 107)存谎,說明了一種對Java對象臨時(shí)在內(nèi)存中進(jìn)行緩存的方法,包括對象的創(chuàng)建鹅搪、共享訪問、假脫機(jī)(spooling)潦嘶、失效涩嚣、各JVM的一致性等崇众。它可被用于緩存JSP內(nèi)最經(jīng)常讀取的數(shù)據(jù),如產(chǎn)品目錄和價(jià)格列表航厚。利用JCACHE顷歌,多數(shù)查詢的反應(yīng)時(shí)間會因?yàn)橛芯彺娴臄?shù)據(jù)而加快(內(nèi)部測試表明反應(yīng)時(shí)間大約快15倍)。
Ehcache Ehcache出自Hibernate幔睬,在Hibernate中使用它作為數(shù)據(jù)緩存的解決方案眯漩。
Java Caching System JCS是Jakarta的項(xiàng)目Turbine的子項(xiàng)目。它是一個復(fù)合式的緩沖工具麻顶∩舛叮可以將對象緩沖到內(nèi)存、硬盤辅肾。具有緩沖對象時(shí)間過期設(shè)定队萤。還可以通過JCS構(gòu)建具有緩沖的分布式構(gòu)架,以實(shí)現(xiàn)高性能的應(yīng)用矫钓。 對于一些需要頻繁訪問而每訪問一次都非常消耗資源的對象要尔,可以臨時(shí)存放在緩沖區(qū)中,這樣可以提高服務(wù)的性能新娜。而JCS正是一個很好的緩沖工具赵辕。緩沖工具對于讀操作遠(yuǎn)遠(yuǎn)多于寫操作的應(yīng)用性能提高非常顯著。

SwarmCache SwarmCache是一個簡單而功能強(qiáng)大的分布式緩存機(jī)制概龄。它使用IP組播來有效地在緩存的實(shí)例之間進(jìn)行通信还惠。它是快速提高集群式Web應(yīng)用程序的性能的理想選擇。
ShiftOne ShiftOne Object Cache這個Java庫提供了基本的對象緩存能力私杜。實(shí)現(xiàn)的策略有先進(jìn)先出(FIFO)蚕键,最近使用(LRU),最不常使用(LFU)衰粹。所有的策略可以最大化元素的大小嚎幸,最大化其生存時(shí)間。
WhirlyCache Whirlycache是一個快速的寄猩、可配置的、存在于內(nèi)存中的對象的緩存骑疆。它能夠通過緩存對象來加快網(wǎng)站或應(yīng)用程序的速度田篇,否則就必須通過查詢數(shù)據(jù)庫或其他代價(jià)較高的處理程序來建立。
Jofti Jofti可對在緩存層中(支持EHCache箍铭,JBossCache和OSCache)的對象或在支持Map接口的存儲結(jié)構(gòu)中的對象進(jìn)行索引與搜索泊柬。這個框架還為對象在索引中的增刪改提供透明的功能同樣也為搜索提供易于使用的查詢功能。

cache4j cache4j是一個有簡單API與實(shí)現(xiàn)快速的Java對象緩存诈火。它的特性包括:在內(nèi)存中進(jìn)行緩存兽赁,設(shè)計(jì)用于多線程環(huán)境,兩種實(shí)現(xiàn):同步與阻塞,多種緩存清除策略:LFU, LRU, FIFO刀崖,可使用強(qiáng)引用(strong reference)與軟引用(soft reference)存儲對象惊科。

Open Terracotta 一個JVM級的開源群集框架,提供:HTTP Session復(fù)制亮钦,分布式緩存馆截,POJO群集,跨越群集的JVM來實(shí)現(xiàn)分布式應(yīng)用程序協(xié)調(diào)(采用代碼注入的方式蜂莉,所以你不需要修改任何)蜡娶。

sccache SHOP.COM使用的對象緩存系統(tǒng)。sccache是一個in-process cache和二級映穗、共享緩存窖张。它將緩存對象存儲到磁盤上。支持關(guān)聯(lián)Key蚁滋,任意大小的Key和任意大小的數(shù)據(jù)宿接。能夠自動進(jìn)行垃圾收集。

Shoal Shoal是一個基于Java可擴(kuò)展的動態(tài)集群框架枢赔,能夠?yàn)闃?gòu)建容錯澄阳、可靠和可用的Java應(yīng)用程序提供了基礎(chǔ)架構(gòu)支持。這個框架還可以集成到不希望綁定到特定通信協(xié)議踏拜,但需要集群和分布式系統(tǒng)支持的任何Java產(chǎn)品中碎赢。Shoal是GlassFish和JonAS應(yīng)用服務(wù)器的集群引擎。

Simple-Spring-Memcached Simple-Spring-Memcached速梗,它封裝了對MemCached的調(diào)用肮塞,使MemCached的客戶端開發(fā)變得超乎尋常的簡單。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姻锁,一起剝皮案震驚了整個濱河市枕赵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌位隶,老刑警劉巖拷窜,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異涧黄,居然都是意外死亡篮昧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門笋妥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來懊昨,“玉大人,你說我怎么就攤上這事春宣〗桶洌” “怎么了嫉你?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長躏惋。 經(jīng)常有香客問我幽污,道長,這世上最難降的妖魔是什么其掂? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任油挥,我火速辦了婚禮,結(jié)果婚禮上款熬,老公的妹妹穿的比我還像新娘深寥。我一直安慰自己,他們只是感情好贤牛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布惋鹅。 她就那樣靜靜地躺著,像睡著了一般殉簸。 火紅的嫁衣襯著肌膚如雪闰集。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天般卑,我揣著相機(jī)與錄音武鲁,去河邊找鬼。 笑死蝠检,一個胖子當(dāng)著我的面吹牛沐鼠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播叹谁,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼饲梭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了焰檩?” 一聲冷哼從身側(cè)響起憔涉,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎析苫,沒想到半個月后兜叨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡衩侥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年浪腐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顿乒。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泽谨,靈堂內(nèi)的尸體忽然破棺而出璧榄,到底是詐尸還是另有隱情特漩,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布骨杂,位于F島的核電站涂身,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏搓蚪。R本人自食惡果不足惜蛤售,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妒潭。 院中可真熱鬧悴能,春花似錦、人聲如沸雳灾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谎亩。三九已至炒嘲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間匈庭,已是汗流浹背夫凸。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阱持,地道東北人夭拌。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像紊选,于是被迫代替她去往敵國和親啼止。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容