成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識(shí)庫 > 提升Ruby on Rails性能的幾個(gè)解決方案

提升Ruby on Rails性能的幾個(gè)解決方案

熱門標(biāo)簽:徐州網(wǎng)絡(luò)外呼系統(tǒng)哪個(gè)好 滴滴外呼系統(tǒng) 湖州u友防封電銷卡 地圖標(biāo)注賺錢項(xiàng)目注冊 常德電銷平臺(tái)外呼系統(tǒng)軟件價(jià)格 百度地圖標(biāo)注自定義圖片 白銀外呼paas系統(tǒng) 高德地圖標(biāo)注客服 電銷機(jī)器人廠商代理

簡介

Ruby On Rails 框架自它提出之日起就受到廣泛關(guān)注,在“不要重復(fù)自己”,“約定優(yōu)于配置”等思想的指導(dǎo)下,Rails 帶給 Web 開發(fā)者的是極高的開發(fā)效率。 ActiveRecord 的靈活讓你再也不用配置繁瑣的 Hibernate 即可實(shí)現(xiàn)非常易用的持久化,Github 和 Rubygems 上豐富多樣的 Rails 插件是 Rails 開發(fā)高效率的又一有力保障。Rails 是一個(gè)真正徹底的 MVC(Model-View-Controller) 框架,Rails 清楚地將你的模型的代碼與你的控制器的應(yīng)用邏輯從 View 代碼中分離出來。Rails 開發(fā)人員很少或者可能從未遇到過某些代碼該放于哪一層的困擾,在 Rails 的世界中,你的代碼的職責(zé)很清楚的被定位,你可以輕松的決定出它們應(yīng)該位于哪一層。Rails1.2 之后的版本開始支持 Rest Service,通過這些內(nèi)嵌的特別,你在開發(fā)你 Web 應(yīng)用,展現(xiàn)給用戶 HTML 的頁面的同時(shí),幾乎不費(fèi)吹灰之力,就可又提供基于 Rest API 的 Web Service,另外,你也可以方便的像使用基本數(shù)據(jù)的 Model 一樣的去消費(fèi)第三方提供的基于 Rest API 的 Web Service。

通過搜索引擎,你可以找到很多類似于用 Ruby On Rails 十五分鐘創(chuàng)建 Blog 系統(tǒng)等類似的使用 Rails 進(jìn)行快速開發(fā)的文章。 Ruby On Rails 對(duì)于敏捷開發(fā)過程的也是非常友好,在 Rails 框架中集成了 Unit Test, Function Test 對(duì)你的 Model 和應(yīng)用邏輯進(jìn)行測試。通過這些,你不需要再安裝任何插件或者程序庫便可方便的進(jìn)行測試驅(qū)動(dòng)開發(fā),通過 Watir 的支持,你可以輕松的用 Ruby 代碼實(shí)現(xiàn)基于瀏覽器的自動(dòng)測試。 另外,在 Rspec 等插件的支持下,你甚至可以進(jìn)行行為驅(qū)動(dòng)開發(fā)(Behaviour Driven Development),讓你的測試代碼變得更加有意義,也更加容易被客戶所接受。

雖然 Rails 的優(yōu)點(diǎn)你可以一下子列出很多,你也可能會(huì)拿出用 Java/Hibernate/Spring/Struts 和 Ruby On Rails 開發(fā)同樣功能 Web 應(yīng)用程序的代碼行比較來舉例,或者提供進(jìn)行 Java/Hibernate/Spring/Struts 和 Ruby On Rails 開發(fā)所需要接受的培訓(xùn)資料的書籍的對(duì)比照片來舉例,但我們都不可避免的會(huì)面對(duì)可伸縮性(Scalability)的問題。很多 Web 應(yīng)用會(huì)面對(duì)大量的用戶群,這樣的應(yīng)用會(huì)遇到很大的并發(fā)帶來的性能的考驗(yàn)。 Rails 在這一點(diǎn)上,并沒有讓所有人信服,依然有很多的系統(tǒng)架構(gòu)師和工程師對(duì) Rails 是否適用于開發(fā)高負(fù)載高并發(fā)的 Web 應(yīng)用持懷疑的態(tài)度。但不可否認(rèn),隨著 twitter, friends for sale,basecamp 這類大負(fù)載量的應(yīng)用的出現(xiàn),Rails 也越來越被認(rèn)識(shí)是可擴(kuò)展的,這些成熟的應(yīng)用也告訴我們,開發(fā)出同時(shí)處理數(shù)百萬用戶請(qǐng)求的 Rails 應(yīng)用是可能的。Ruby On Rails 框架在可伸縮性上為人詬病無非集中于以下幾點(diǎn),Ruby 語言本身性能問題,Ruby On Rails 缺少成熟的高性能的應(yīng)用服務(wù)器,對(duì)數(shù)據(jù)庫擴(kuò)展的支持,互聯(lián)網(wǎng)上缺乏可熟可靠的網(wǎng)絡(luò)提供商等等。 本文將從這些點(diǎn)出發(fā),介紹具可伸縮性的 Rails 應(yīng)用程序的部署架構(gòu),以及開發(fā)高性能的 Rails 應(yīng)用程序的一些比較好的具體實(shí)踐。

通常的 Web2.0 應(yīng)用,特別是高負(fù)載的應(yīng)用,除了 Web 和應(yīng)用服務(wù)器選擇 , 負(fù)載均衡這類部署需要面對(duì)的問題之外,通常還必須得面對(duì)后臺(tái)任務(wù),高性能全文搜索這些開發(fā)上的問題,這些在 Java 或者 PHP 這些比較成熟的開發(fā)環(huán)境里面都有比較成熟的方案,開發(fā)和架構(gòu)人員通常都會(huì)有多種選擇,結(jié)合具體應(yīng)用做出架構(gòu)設(shè)計(jì)。在新興的 Rails 社區(qū),這些還并不完善和成熟,本文將介紹一些高性能可伸縮的 Rails 應(yīng)用程序的開發(fā)和部署的具體實(shí)踐,針對(duì)通常 Web 2.0 網(wǎng)站所遇到的具體問題做出分析和解決方案,旨在給 Rails 開發(fā)者提供具體的參考。本文將介紹的內(nèi)容可以用下圖來綜合表示:
圖 1. 本文總體結(jié)構(gòu)

使用 Nginx+Passenger 來替代 Apache+Mongrel 來部署 Rails 應(yīng)用

事實(shí)上,進(jìn)行 Rails 部署可以描述得非常簡單,我們需要一些機(jī)器配置我們的環(huán)境,為了性能和成本,我們理所當(dāng)然選用 Linux 系列的服務(wù)器,可選的有 CentOS,Debian, Ubuntu Server 等。本文的所有程序,命令以及代碼如非特別說明,都默認(rèn)是以 Linux 為基本環(huán)境的。 然后我們需要數(shù)據(jù)庫存儲(chǔ)我們的數(shù)據(jù),我們可以選用免費(fèi)的 Mysql,然后我們便開始開發(fā)我們的 Web 應(yīng)用的 Rails 代碼,部署時(shí),我們需要支持 Ruby On Rails 的應(yīng)用服務(wù)器讓我們的 Rails 代碼跑起來,這可能是 Rails 自帶的 Webrick,當(dāng)然這個(gè)可能性極小,也可能是 FastCGI, 或者是 Mongrel,Thin, Passenger 等等,然后我們通過 Apache,Nginx,Lighttpd,HAProxy 之類的 Web 服務(wù)器訪問我們的應(yīng)用服務(wù)器,這個(gè)訪問可以直接通過 HTTP 協(xié)議,也可以是 FastCGI,或者是自定義的其它協(xié)議,如此這般,我們便可以通過瀏覽器訪問我們的應(yīng)用程序了。如下圖所示,這便是通常的 Rails 應(yīng)用程序部署結(jié)構(gòu)。
圖 2. Rails 應(yīng)用程序部署結(jié)構(gòu)

對(duì)于前端的 Web Server,Apache 是事實(shí)上的工業(yè)標(biāo)準(zhǔn),在 Web 服務(wù)器市場,是占有率最高的,全球大量的網(wǎng)站采用 Apache 來部署他們的應(yīng)用,Apache 是一款成熟穩(wěn)定的 Web 服務(wù)器,功能非常強(qiáng)大,提供對(duì)幾乎所有 Web 開發(fā)語言和框架的擴(kuò)展支持,在對(duì) Rails 框架的支持上,我們可以采用 mod_fcgid 模塊,通過 FastCGI 協(xié)議與 Rails 進(jìn)程通訊?;蛘呃?mod_proxy_balancer 對(duì)后端的獨(dú)立的 Rails 服務(wù)器如 Thin Cluster,Mongrel Cluster 或者 Apach/Nginx+Passenger 進(jìn)行 HTTP 分發(fā)。但 Apache 作為一個(gè)通用的服務(wù)器,在性能上和一些輕量型的 Web 服務(wù)器相差甚遠(yuǎn)。Apache 的 mod_proxy_balancer 模塊的分發(fā)性能不高,比 Nginx 或者 HAproxy 都相差很多,另外,Apache 目前并不支持 Event(事件)模型,它僅支持 Prefork(進(jìn)程)模式和 Worker(線程)模式,每處理一個(gè)鏈接,就需要?jiǎng)?chuàng)建一個(gè)進(jìn)程或線程,而一些輕量級(jí) Web 服務(wù)器如 Nginx 和 Lighttpd,則都很好地利用內(nèi)核的事件機(jī)制提高性能,極大減少線程或進(jìn)程數(shù)量,降低系統(tǒng)負(fù)載。

Nginx 是一個(gè)輕量級(jí)的高效快速的 Web 服務(wù)器,它作為 HTTP 服務(wù)器和反向代理服務(wù)器時(shí)都具有很高的性能。Nginx 可以在大多數(shù) Unix like OS 上編譯運(yùn)行,并有 Windows 移植版。 Nginx 選擇了 Epoll 和 Kqueue 作為開發(fā)模型,它能夠支持高達(dá) 50,000 個(gè)并發(fā)連接數(shù)的響應(yīng),可以在內(nèi)部直接支持 Rails 和 PHP 程序?qū)ν膺M(jìn)行服務(wù)。另外,Nginx 作為負(fù)載均衡服務(wù)器,也可以支持作為 HTTP 代理服務(wù)器對(duì)外進(jìn)行服務(wù) , Nginx 不論是系統(tǒng)資源開銷還是 CPU 使用效率都比 Apache 要好很多。當(dāng)你打開 Nginx 官方網(wǎng)站,你會(huì)發(fā)現(xiàn)一個(gè)如此知名的 Web 服務(wù)器產(chǎn)品的官方主頁竟然如此簡單,其實(shí),Nginx 本身就是一個(gè)安裝非常簡單,配置文件非常簡潔,甚至可以在配置文件中使用 Perl 語法。

在處理靜態(tài)文件上, Apache 和 Nginx 都可以勝任。但對(duì)于應(yīng)用服務(wù)器或者是前端的負(fù)載均衡服務(wù)器,我們推薦 Nginx 而不是相對(duì) Nginx 較為重量級(jí)的 Apache。

對(duì)于應(yīng)用服務(wù)器,Mongrel 一度是最流行的部署方式,它的 HTTP 協(xié)議的解析部分是用 C 語言編寫的,效率上有所保證。Mongrel 使用了 Ruby 的用戶線程機(jī)制來實(shí)現(xiàn)多線程并發(fā) , 但是 Ruby 并不是本地線程 ,Rails 也不是線程安全的,因此 Mongrel 在執(zhí)行 Rails 代碼的過程中,完全是加鎖的狀態(tài),那和單進(jìn)程其實(shí)也沒有太大差別。所有我們在使用 Mongrel 來部署 Rails 應(yīng)用程序時(shí),一般是在后臺(tái)啟動(dòng)一個(gè) mongrel_cluster 來啟動(dòng)多個(gè) Mongrel 進(jìn)程,如我們在 mongrel_cluster.yml 中進(jìn)行如下配置可以在 8000~8009 端口啟動(dòng) 10 個(gè) Mongrel 進(jìn)程。
清單 1. Mongrel_cluster.yml 配置

 --- 
 cwd: /var/www/test_app 
 log_file: log/Mongrel.log 
 port: "8000"
 environment: production 
 debug: false 
 pid_file: log/mongrel.pid 
 servers: 10

這樣的部署方式實(shí)際上也限制了 Mongrel 處理大并發(fā)應(yīng)用的能力,在處理大數(shù)據(jù)量請(qǐng)求的時(shí)候,Mongrel 進(jìn)程經(jīng)常被掛過,但并發(fā)數(shù)一多,就會(huì)出現(xiàn)所有的 Mongrel 進(jìn)都會(huì)被掛過的情況,這樣前端的服務(wù)器便得不到返回,整個(gè) Web 應(yīng)用就陷入癱瘓。所以,Mongrel 并沒有被廣泛采用,很多網(wǎng)站寧愿堅(jiān)持使用最古老的 FastCGI 的部署方式也不使用 Mongrel 來部署應(yīng)用,而且 Mongrel 也停止更新很久,Mongrel 的開發(fā)者已完全不再進(jìn)行 Mongrel 的開發(fā)了。所以,Mongrel 并不是現(xiàn)在最推薦的 Rails 應(yīng)用服務(wù)器。

Passenger 是類似于 mod_php 的 Rails 運(yùn)行環(huán)境,而不是 Mongrel 那樣是獨(dú)立的 Http 服務(wù)器。Passenger 對(duì)目前主流的 apache 和 Nginx 兩大 Web 服務(wù)器都有支持。Passenger 使用起來極其方便,而且它具有較高的性能,從 Passenger 官方網(wǎng)站公布的測試結(jié)果來看,Passenger 的性能要優(yōu)于 Mongrel 服務(wù)器,目前來說,Passenger 無疑是最好的選擇。Passenger 繼承了 Rails"不重復(fù)自己"的慣例,通過 Passenger 部署應(yīng)用程序,你僅僅需要將 Rails 項(xiàng)目程序文件上傳到目標(biāo)服務(wù)器,甚至都不需要重啟服務(wù)器,非常簡單。

要在 Nginx 環(huán)境下安裝運(yùn)行 Passenger, 你僅僅需要如下操作:
清單 2. 安裝 Passenger

 gem install passenger 
 Passenger-install-nginx-module

下面的代碼展示了在 Nginx 上配置 Passenger:
清單 3. 在 Nginx 上配置 Passenger

 http { 
  ... 
  server { 
    listen 80; 
    server_name www.test.com; 
    root /var/www/test/public; 
    passenger_enabled on; 
  } 
  ... 
 }

通過 Nginx+Passenger 構(gòu)建 Ruby On Rails 的應(yīng)用服務(wù)器可以得到顯著的性能提升,同時(shí),還可以采用 Ruby Enterprise Edition 來提升 Ruby 本身的性能。這個(gè)版本也是由 Phusion 開發(fā)的,采用 copy-on-write 的垃圾回收策略,并使用 tcmalloc 來改善內(nèi)存分配,他們的網(wǎng)站公布的數(shù)據(jù),使用 Ruby Enterprise Edition 能比普通的 Ruby 版本減少 33% 的內(nèi)存消耗。

Nginx+Passenger 就部署在一臺(tái)機(jī)器上的應(yīng)用服務(wù)器,但并發(fā)過大時(shí),一臺(tái)機(jī)器并不足以來提供這樣的處理能力,這個(gè)時(shí)候,一般會(huì)做負(fù)載均衡,這和通常的負(fù)載均衡策略并無二異,Nginx 在使用反向代理來實(shí)現(xiàn)負(fù)載均衡的能力上要強(qiáng)于 Apache 的反向代理模塊,我們可以在多臺(tái) Nginx+Passenger 的前端可以再增加一臺(tái) Nginx 的 Web 服務(wù)器。甚至為了更強(qiáng)的處理能力,我們也可以采用 LVS 來進(jìn)行負(fù)載均衡。

使用 Starling 和 Workling 去異步執(zhí)行 Rails 后臺(tái)任務(wù)

在進(jìn)行 Web 應(yīng)用開發(fā)時(shí),每個(gè) Web 請(qǐng)求都需要迅速的得到返回,這時(shí)候有些計(jì)算量比較大的操作可以放在后臺(tái)去異步執(zhí)行,比如大量的數(shù)據(jù)更新操作,只需要在 Web 應(yīng)用中進(jìn)行觸發(fā),然后在后臺(tái)進(jìn)行執(zhí)行。而有些操作則需要定期去執(zhí)行,比如數(shù)據(jù)的備份,一些數(shù)據(jù)的統(tǒng)計(jì)分析,圖片的處理,郵件的發(fā)送等等。這些操作如果放在 Web 應(yīng)用中即時(shí)返回顯然是不合適的,而且也會(huì)帶來機(jī)器的負(fù)載很嚴(yán)重,對(duì)于 Rails 應(yīng)用程序來說,除了影響用戶體驗(yàn),這樣的操作還會(huì)阻塞 Rails 服務(wù)器實(shí)例,從而帶來整體性能的下降。對(duì)于這類操作,我們可以使用一個(gè)任務(wù)隊(duì)列,將需要執(zhí)行的操作依次入隊(duì),然后在后臺(tái)再啟動(dòng)進(jìn)程進(jìn)隊(duì)列中取出這些任務(wù),并執(zhí)行,隊(duì)列可以使用數(shù)據(jù)庫,Memcached, ActiveMQ 或者 Amazon SQS 來實(shí)現(xiàn),而后端進(jìn)程則可以使用 Rails 里面的 cronjob+script/runner 或者 BackgrounDRb 等等來操作。這里要介紹的解決方案則是采用 twitter 開發(fā)人員貢獻(xiàn)出來的采用 Memcache 協(xié)議的 Starling 消息隊(duì)列和 Workling 插件來進(jìn)行實(shí)現(xiàn)。

Starling 是 twitter 開發(fā)團(tuán)隊(duì)從 twitter 項(xiàng)目抽象出來開源的 Rails 插件,雖然說 Starling 并不完全就是 twitter 的線上版本所用的插件,但我們也可以足以相信 Starling 的性能和應(yīng)對(duì)高并發(fā)的處理能力。類似的插件還有 backgroundrb,background job, background_fu。backgroundrb 是使用 drb 實(shí)現(xiàn)隊(duì)列的消息傳遞,但它還有一個(gè)問題,更新隊(duì)列的時(shí)候,backgroundrb 使用的是悲觀鎖,在大訪問量的情況下,這種情況是不容允許的。 background job 和 background_fu 則是基于數(shù)據(jù)庫的消息隊(duì)列,在大負(fù)載量的情況下數(shù)據(jù)庫的性能也不容易得到保證。而 Starling 是基于 Memcached 協(xié)議的消息隊(duì)列,效率更高,也更容易伸縮,通常你可以在每臺(tái)應(yīng)用服務(wù)器上都運(yùn)行一個(gè) Starling 服務(wù)器,并在同一臺(tái)機(jī)器或者其它機(jī)器上去運(yùn)行后臺(tái)程序與之交互。

我們通過如下命令來安裝 Starling:
清單 4. 安裝 Starling

 gem sources -a http://gems.github.com/ 
 sudo gem install starling-starling 
 mkdir /var/spool/starling

在讀取 Starling Server 時(shí),我們需要 memcache-client,這個(gè) gem 的 1.5.0 版本有一些問題,在 fiveruns-memcache-client 得到修正,這個(gè) fiveruns-memcache-client gem 在 starling-starling gem 中是作為依賴項(xiàng)自動(dòng)安裝的。

安裝完 Starling 之后,使用 sudo Starling -d -p 15151 這個(gè)命令來啟動(dòng)它,啟動(dòng)時(shí)用 -p 參數(shù)來指定所要使用的端口,一般加 -d 參數(shù)使它以 daemon 方式在后臺(tái)運(yùn)行:

為了明白 Starling 的機(jī)制和 Starling 究竟做了哪些工作,在啟動(dòng)了 Starling 之后,我們可以使用我們打開 irb 下面的程序來進(jìn)行簡單的測試:

進(jìn)行簡單的測試
清單 5. 測試 Starling

 >> require 'starling'
 => true 
 >> Starling = Starling.new('127.0.0.1:15151) 
 => MemCache: 1 servers, ns: nil, ro: false 
 >> Starling.set('test_queue', 123) 
 => nil 
 >> loop { puts Starling.get('test_queue'); sleep 1 } 
 123 
 nil 
 nil 
 ...

這里我們可以看到確實(shí)啟動(dòng)了 Server,然后我們向這里插入數(shù)據(jù),我們用一個(gè)循環(huán)去訪問這個(gè)隊(duì)列,最后的輸出便是我們想要的結(jié)果。

接下來我們安裝 workling:
清單 6. 安裝 workling

 script/plugin install git://github.com/purzelrakete/workling.git

Workling 支持多種方式來進(jìn)行后臺(tái)任務(wù)操作,其中就包括上面已經(jīng)安裝的 Starling,安裝好 Starling 后,我們需要在 Rails 應(yīng)用程序中的 environment.rb 加上以下代碼來配置 Workling 使用 Starling:
清單 7. 使用 workling

 Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new

Workling 的配置文件在 workling.yml, 和其它 Rails 的配置文件類似,workling.yml 也可以針對(duì)不同產(chǎn)品模式進(jìn)行不同的模式,這里僅列出 production 的配置。
清單 8. Workling 配置

 production: 
   listens_on:localhost:15151, localhost:15152, localhost:15153 
   sleep_time: 2 
   reset_time: 30 
   memcache_options: 
    namespace: myapp

listens_on 參數(shù)即為 workling_client 去訪問的 Starling 啟動(dòng)的地址和端口,這里可以允許多個(gè) Starling 地址,這就意味著你啟動(dòng)多個(gè) Starling 服務(wù)器,而用一個(gè) workling_client 去調(diào)用。sleep_time 即為 workling_client 去隊(duì)列中取數(shù)據(jù)的等待時(shí)間,reset_time 則定義了如果出現(xiàn) memcache 錯(cuò)誤時(shí),workling_client 等待去重建和服務(wù)器連接的時(shí)間。 在 memcache_options 的 namespace 參數(shù)則定義了所使用的命名空間,這在同一臺(tái)服務(wù)器如果為不同的 Rails 應(yīng)用啟動(dòng)同一個(gè) Starling 服務(wù)器時(shí)是非常有用的。

用 script/workling_client start 腳本便可以啟動(dòng) workling_client 進(jìn)程,有時(shí)候我們覺得一個(gè) workling_client 不夠用,我們可以修改 script/workling_client start 來支持多個(gè) workling_client 實(shí)例,這樣每運(yùn)行 script/workling_client start 一次都會(huì)新啟動(dòng)一個(gè) workling_client 實(shí)例。
清單 9. 多 client 的 Workling 配置

 options = { 
 :app_name  => "workling", 
 :ARGV    => ARGV, 
 :dir_mode  => :normal, 
 :dir    => File.join(File.dirname(__FILE__), '..', 'log'), 
 :log_output => true, 
 :multiple  => true, 
 :backtrace => true, 
 :monitor  => true 
 }

使用 Memcached 和 cache-money 來緩存數(shù)據(jù)

Rails 自身提供四種緩存方式,即 Page Cache, Action Cache,F(xiàn)ragment Cache 和 ActiveRecord Cache 這三種緩存。Page Cache 是最高效的緩存機(jī)制,他把整個(gè)頁面以靜態(tài)頁面 HTML 的形式進(jìn)行緩存,這對(duì)于不會(huì)經(jīng)常發(fā)生變化的頁面是非常有效的。Action Cache 是對(duì)某個(gè) action 進(jìn)行緩存,與 Page Cache 的區(qū)別在于:HTTP 請(qǐng)求會(huì)經(jīng)過 Rails 應(yīng)用服務(wù)器,直到所有的 before filters 都被處理,這種緩存就能處理 Page Cache 無法處理的如需要登錄驗(yàn)證的頁面,可以所驗(yàn)證的步驟加入 before filter 中,F(xiàn)ragment Cache 則為了緩存頁面中的某一部分,同一個(gè)頁面中的不同部分還可以采用不同的過期策略。對(duì)于 Rails 本身的緩存機(jī)制,我們可以寫 sweeper 進(jìn)行過期和清除的處理。ActiveRecord Cache 則是較新版本 Rails 中新推出的對(duì) ActiveRecord 的緩存機(jī)制,使用 SQL 查詢緩存,對(duì)于同一 action 里面同一 SQL 語句的數(shù)據(jù)庫操作會(huì)使用緩存。

Rails 的緩存機(jī)制能非常有效的提升網(wǎng)站性能,Rails 默認(rèn)是將緩存存在于文件系統(tǒng)中,這并不是適合生產(chǎn)環(huán)境下的存儲(chǔ)方式,文件 IO 的效率有限,Rails 還支持在同一進(jìn)程的內(nèi)存中保存 Cache,但如果有多個(gè) Rails application,它們之間不能共享緩存。我們這里推薦的是以 MemCached 的方式進(jìn)行存儲(chǔ),這也是目前是流行的緩存存儲(chǔ)方式。

Memcached 是由 Danga Interactive 開發(fā),用于提升 LiveJournal.com 訪問速度的。LiveJournal.com 每秒有幾千次動(dòng)態(tài)頁面訪問量,用戶 700 萬。Memcached 是一個(gè)具有極高性能的分布式內(nèi)存對(duì)象緩存系統(tǒng) , 基于一個(gè)存儲(chǔ)鍵 / 值對(duì)的哈希表。其守護(hù)進(jìn)程(daemon)是用 C 寫的 , Memcached 將數(shù)據(jù)庫負(fù)載大幅度降低,更好的分配資源,更快速訪問。可以用各種其它語言去實(shí)現(xiàn)客戶端。上文的介紹中已經(jīng)安裝了 Rails 的 Memcached 客戶端,因?yàn)槲覀冎恍枰?Rails 應(yīng)用程序中做如下配置:
清單 10. Memcached 配置

 config.cache_store = :mem_cache_store, 'localhost:11211'

便可以進(jìn)行使用 MemCached 進(jìn)行緩存數(shù)據(jù)。除了 Rails 本身的緩存機(jī)制,我們還直接用 Rails.cache 操作 Memcached 進(jìn)行數(shù)據(jù)緩存,如,我們讀取所有 blog 的數(shù)量,可以如下使用緩存:
清單 11. 使用 Rails.cache

 blogs_count = Rails.cache.fetch("blogs_count") do 
  Blog.count 
 end

Rails 自身的 ActiveRecord 作用有限,只適用同一個(gè) action 中的 SQL 查詢語句進(jìn)行緩存,我們需要一個(gè)更強(qiáng)大的 ActiveRecord 緩存,而 cache-money 更是為了解決如此問題而推出的。當(dāng) twitter 網(wǎng)站變得越來越穩(wěn)定,逐漸擺脫被人拿來作為"Rails 無法擴(kuò)展的"典型例子的陰影時(shí),人們便期待 twitter 開發(fā)團(tuán)隊(duì)能向 Rails 社區(qū)有更多的貢獻(xiàn),cache-money 便是在 Starling 之后 twitter 團(tuán)隊(duì)貢獻(xiàn)出來的另一個(gè)插件。cache-money 和 Hibernate 的二級(jí)緩存類似,是一個(gè)讀寫式(write-through)緩存。在 ActiveRecord 對(duì)象更新的時(shí)候不是將緩存中的數(shù)據(jù)清除,而是直接將更新的內(nèi)容寫入到緩存中去。

cache-money 有許多很棒的特性,如:緩存自動(dòng)清除機(jī)制 ( 利用 after_save/after_destroy) ;支持事務(wù),由于 Rails 的 Active Record 沒有提供 after_commit 機(jī)制,目前常見的緩存插件在高并發(fā)下會(huì)出現(xiàn)緩存更新競爭沖突,而這個(gè)特性對(duì)于解決這個(gè)問題會(huì)很有幫助,可以通過 gem 來安裝 cache-money:
清單 12. 安裝 cache-money

 gem sources -a http://gems.github.com 
 sudo gem install nkallen-cache-money 
 require 'cache_money'

清單 13. 配置 config/memcached.yml

 production: 
 ttl: 604800 
 namespace: ... 
 sessions: false 
 debug: false 
 servers: localhost:11211 

 development: 
  ....

清單 14. 使用 config/initializers/cache_money.rb 來初始化

 config = YAML.load(IO.read(File.join(Rails_ROOT, "config", "Memcached.yml")))[Rails_ENV] 
 $memcache = MemCache.new(config) 
 $memcache.servers = config['servers'] 
 $local = Cash::Local.new($memcache) 
 $lock = Cash::Lock.new($memcache) 
 $cache = Cash::Transactional.new($local, $lock) 
 class ActiveRecord::Base 
 is_cached :repository => $cache 
 end

使用 cache-money 非常方便,不需要額外的操作,只需要在你的 Model 里面進(jìn)行簡單的配置,如:
清單 15. 配置 Model 來使用 cache_money

 class User  ActiveRecord::Base 
 index :name 
 end 
 class Post  ActiveRecord::Base 
 index [:title, :author] 
 end 
 class Article  ActiveRecord::Base 
 version 7 
 index ... 
 end

然后便可以跟以前一樣使用 Rails ActiveRecord 各種方法以及事務(wù)操作。如果你改變了數(shù)據(jù)庫的表結(jié)構(gòu),你可以改變 Model 的版本號(hào)來使以前的緩存失效,而不需要重啟 Memcached 服務(wù)器。

使用 Sphinx+LibMMSeg+Ultrasphinx 進(jìn)行全文搜索

很多應(yīng)用會(huì)有全文搜索的需求,當(dāng)然你可以直接集成 google 或者其它搜索引擎提供的搜索服務(wù),但如果你要更好的控制你的搜索結(jié)果,或者對(duì)你的搜索結(jié)果進(jìn)行再次利用,你恐怕必須得自己實(shí)現(xiàn)全文搜索了。在進(jìn)行中文全文搜索時(shí),一般要考慮兩個(gè)方面的問題,即所使用搜索工具的性能問題,以及中文分詞的準(zhǔn)備度。在 Java 的世界里,Lucene 是做全文搜索絕對(duì)的權(quán)威和首選,雖然它本身沒有對(duì)中文分詞很好的支持,但有很多第三方插件可以利用來提高中文分詞的準(zhǔn)備率和性能。Ferret 一度是最流行的 Rails 全文搜索插件,但本文推薦是效率更高的 Sphinx。Sphinx 是俄羅斯人 Andrew Aksyonoff 開發(fā)的,這個(gè)詞的意思“獅身人面”,它能在一兩分鐘的時(shí)間內(nèi)完成數(shù)百萬條記錄的索引,并在毫秒級(jí)的時(shí)間類返回搜索結(jié)果。 Sphinx 和數(shù)據(jù)庫集成良好,可以通過配置文件,直接用來對(duì)數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行索引,另外,Sphinx 開發(fā)了一個(gè) SphinxSE 數(shù)據(jù)庫引擎,可以在編譯 Mysql 的時(shí)候直接編譯到 Mysql 里面去來實(shí)現(xiàn)數(shù)據(jù)庫級(jí)別的高效能索引。在 Rails 中使用 Sphinx 可以通過 Ultrasphinx 插件,Rails 開發(fā)人員可以使用它來很方便地調(diào)用 Sphinx 的功能。

可以從這里 http://www.sphinxsearch.com/downloads.html 下載 Sphinx

在安裝好 Sphinx 后可以直接從 Rubyforge 上安裝 Ultrasphinx:
清單 16. 安裝 ultrasphinx

 Ruby script/plugin install svn://Rubyforge.org/var/svn/fauna/ultrasphinx/trunk

LibMMSeg 就是一個(gè)中文分詞程序,當(dāng)前最新版本是 0.7.3,采用 C++ 開發(fā),分詞算法采用的是“復(fù)雜最大匹配 (Complex maximum matching)”,同時(shí)支持 Linux 平臺(tái)和 Windows 平臺(tái),切分速度大約在 300K/s(PM-1.2G),LibMMSeg 從 0.7.2 版本開始,作者提供了 Ruby 調(diào)用的接口,所以我們可以直接在 Ruby 中用 LibMMSeg 進(jìn)行分詞,相當(dāng)方便。LibMMSeg 可以通過 http://www.coreseek.cn/opensource/mmseg/ 來下載安裝。

用戶可以通過修改詞典文件增加自己的自定義詞,以提高分詞法在某一具體領(lǐng)域的切分精度,系統(tǒng)默認(rèn)的詞典文件在 data/unigram.txt中。 然后通過 mmseg -u unigram.txt這個(gè)命令來產(chǎn)生一個(gè)名為 unigram.txt.uni的文件,將該文件改名為 uni.lib,完成詞典的構(gòu)造。需要注意的是,unigram.txt必須為 UTF-8 編碼。

LibMMSeg 的開發(fā)者為了更好的讓 Sphinx 使用 LibMMSeg 進(jìn)行中文分詞,為 Sphinx 開發(fā)了相關(guān)的補(bǔ)丁,從這里 http://www.coreseek.cn/opensource/Sphinx/ 下載兩個(gè)補(bǔ)丁文件:

http://www.coreseek.com/uploads/sources/sphinx-0.98rc2.zhcn-support.patch

http://www.coreseek.com/uploads/sources/fix-crash-in-excerpts.patch

然后打上補(bǔ)?。?br /> 清單 17. 安裝 Sphinx 補(bǔ)丁

 cd sphinx-0.9.8-rc2 
 patch -p1  ../sphinx-0.98rc2.zhcn-support.patch 
 patch -p1  ../fix-crash-in-excerpts.patch

安裝完這幾個(gè)插件和補(bǔ)丁之后,我們便可以進(jìn)行配置來讓 Rails 應(yīng)用程序來支持全文搜索了,

首先我們將 ultrasphinx 插件目錄下的 vendor/plugins/ultrasphinx/examples/default.base復(fù)制到:config/ultrasphinx/default.base,打開這個(gè)文件,將其中的:

charset_type = utf-8改為:charset_type = zh_cn.utf-8來支持中文字符的全文檢索, 并且在 charset_type 設(shè)置的下面加入一行:

charset_dictpath = /home/test/Search/lib,這個(gè)就是上文講到的 uni.lib 字典所在的路徑,然后刪除所有 charset_table 相關(guān)的設(shè)置。

在 Rails 應(yīng)用程序中的 Model 代碼,加入全文檢索支持:

如有一個(gè) Model 為 Article,其中有兩個(gè)屬性叫做 title,body,我希望對(duì)這兩個(gè)屬性做全文檢索,便可以在 article.rb 中加入一行:
清單 18. 使用 ultrasphinx

 is_indexed :fields => ['created_at','title', 'body']

進(jìn)行完這個(gè)配置后,我們可以使用 rake ultrasphinx:configure 這個(gè)命令來生成Sphinx 的配置文件,這條命令在 config/ultrasphinx 下創(chuàng)建了一個(gè) development.conf,這個(gè)文件就是 Sphinx 的配置文件。并用rake ultrasphinx:index 這個(gè)命令來創(chuàng)建索引。rake ultrasphinx:daemon:start 和 rake ultrasphinx:daemon:stop 則對(duì)應(yīng)著Sphinx 的searchd服務(wù)的啟動(dòng)和停止。searchd 會(huì)在 3313 端口啟動(dòng)一個(gè) searchd,搜索請(qǐng)求將會(huì)全部發(fā)送到這個(gè)端口來執(zhí)行。我們在控制臺(tái)中進(jìn)行簡單的測試:
清單 19. 測試全文索引

 search = Ultrasphinx::Search.new(:class_names => 'Article') 
 search.run 
 Search.results 

一切運(yùn)行正常后,我們便可以在 action 的代碼中進(jìn)行全文搜索了。

使用 Capistrano 進(jìn)行快速部署

在進(jìn)行 Rails 部署的時(shí)候你可以直接從 svn 或者 git 下面更新代碼,運(yùn)行 db:migrate 來進(jìn)行數(shù)據(jù)庫的更新,然后進(jìn)行這樣那樣的操作后,再啟動(dòng)服務(wù)器,便可進(jìn)行部署,即便你只有一臺(tái)機(jī)器,你也會(huì)覺得太麻煩,如果你需要多臺(tái)機(jī)器來運(yùn)行,那你可能就會(huì)覺得每次手工部署都是一場惡夢,你可以使用 shell 腳本來簡化部署的程序。在用 Rails 開發(fā)應(yīng)用時(shí),你可以使用 Capistrano 插件來進(jìn)行更簡單的部署工作。簡單來說,Capistrano 是一個(gè)通過 SSH 并行的在多臺(tái)機(jī)器上執(zhí)行相同命令的工具,使用用來安裝一整批機(jī)器。 它通過一個(gè)個(gè)已有的和用戶自定制的任務(wù)讓部署過程簡單化。
清單 20. 安裝 Capistrano

 gem sources -a http://gems.github.com/ 
 gem install Capistrano

然后在 config/deploy.rb 中配置要部署的服務(wù)器的地址,各種服務(wù)器的角色以及每個(gè)服務(wù)器統(tǒng)一的用戶名和密碼,如下面的樣例配置:
清單 21. 配置 Capistrano

 set :application, "test_app" # 應(yīng)用的名稱
 set :scm_username, "test"  # 資源庫的用戶名
 set :scm_password, 'test'  # 資源庫的密碼
 set :repository, Proc.new {"--username #{scm_username} 
 --password #{scm_password} svn://localhost/test_app/trunk"}  
 # 資源庫
 set :user, "test"  # 服務(wù)器 SSH 用戶名
 set :password, 'test' # 服務(wù)器 SSH 密碼
 set :deploy_to,    "/var/www/#{application} " 
 # 在服務(wù)器上的部署路徑,默認(rèn)的部署路徑是 /u/apps/#{application} 
 role :Web, 'Web.test_app.com' # 前端 Web 服務(wù)器
 role :app, 'app1.test_app.com', 'app2.test_app.com', 'app3.test_app.com' #Rails 應(yīng)用服務(wù)器
 role :db, 'app1.test_app.com', :primary => true 
 # 運(yùn)行 migrate 腳本的機(jī)器,通常為其中一臺(tái)應(yīng)用服務(wù)器。

在使用 Capistrano 進(jìn)行部署的時(shí)候,通常是這樣使用 cap sometask來運(yùn)行任務(wù)。你可以先用 cap -h查看所有的選項(xiàng),并用 cap -T查看現(xiàn)有的所有任務(wù)。如 cap migrate則在 role 為 db 的機(jī)器上執(zhí)行 rake db:migrate命令。使用 Capistrano 的更多資料可以參考 http://wiki.capify.org 這個(gè)網(wǎng)站。另外,Capistrano 還可以使用在非 Rails 環(huán)境下進(jìn)行自動(dòng)部署,在配置好 ruby 環(huán)境和 Capistrano 插件后,再安裝下面的插件即可:
清單 22. 非 Rails 環(huán)境使用 Capistrano

 gem sources -a http://gems.github.com/ 
 gem install leehambley-railsless-deploy

結(jié)束語

本文著重使用 Ruby On Rails 來開發(fā)和部署 Web 應(yīng)用時(shí)一些有用的具體實(shí)踐,沒有具體去介紹一些通常應(yīng)用程序都需要面對(duì)的普遍問題,如數(shù)據(jù)庫的優(yōu)化和分布式部署,這是一個(gè)大并發(fā)的 Web 應(yīng)用都需要面對(duì)和解決的問題,比如可以采用 master-slave 的方式去部署分布式的數(shù)據(jù)庫,或者采用分庫或者分表的方式對(duì)數(shù)據(jù)庫進(jìn)行拆分。另外,在運(yùn)行 Rails 服務(wù)器或者其它后臺(tái)應(yīng)用程序時(shí),通過還需要另外的進(jìn)程去進(jìn)行監(jiān)控,如用 God 去監(jiān)控 Rails 進(jìn)程也是一個(gè) Rails 應(yīng)用通常都會(huì)采用的策略。另外,很多時(shí)候,可以采用更敏捷更輕量級(jí)的 Rack 去代替 Rails 來進(jìn)行更高效的開發(fā)的提供服務(wù)。并且,Engineyard ,Joyent 以及 Heroku 等這類 Rails 網(wǎng)絡(luò)提供商的涌現(xiàn)也在相當(dāng)程度上堅(jiān)定了用 Rails 開發(fā)和部署大規(guī)模大并發(fā) Web 應(yīng)用的信心。雖然 Ruby On Rails 自身的缺陷不可避免, 但是開發(fā)可伸縮的高性能的應(yīng)用程序并不是不可能的。本文希望能夠幫助 Rails 開發(fā)人員快速掌握一些具體實(shí)踐,能夠編寫出并部署性能高伸縮性強(qiáng)的 Web 應(yīng)用程序。

您可能感興趣的文章:
  • 在Ruby on Rails中使用AJAX的教程
  • 使用Ruby on Rails快速開發(fā)web應(yīng)用的教程實(shí)例
  • 詳細(xì)解析Ruby中的變量

標(biāo)簽:公主嶺 永州 張家界 普洱 三沙 梧州 遼寧 荊門

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《提升Ruby on Rails性能的幾個(gè)解決方案》,本文關(guān)鍵詞  提升,Ruby,Rails,性能,的,幾個(gè),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《提升Ruby on Rails性能的幾個(gè)解決方案》相關(guān)的同類信息!
  • 本頁收集關(guān)于提升Ruby on Rails性能的幾個(gè)解決方案的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    亚洲成人中文在线| 污视频网站在线免费观看| 99精品女人在线观看免费视频| 在线观看一区欧美| 日本一区二区综合亚洲| 老司机99精品99| 国产日韩精品久久| 日韩欧美国产亚洲| 国外成人在线视频网站| 国产精品中文字幕一区二区三区| bdsm精品捆绑chinese| 四虎永久免费在线观看| 国产精品日韩在线播放| 制服视频三区第一页精品| 国产成人aa在线观看网站站| 日韩欧美国产中文字幕| 欧美性极品xxxx做受| 亚洲精品国产精品国自产网站| 欧美特黄aaaaaa| 日本学生初尝黑人巨免费视频| 高清在线观看免费韩剧| 国产极品一区二区| 亚洲精华国产精华精华液网站| 亚洲国产私拍精品国模在线观看| 国产精品不卡一区二区三区在线观看| 亚洲欧美日韩国产一区二区| 成人日韩在线电影| 91精品视频一区二区| 色偷偷亚洲男人天堂| 中文字幕在线看精品乱码| 精品国产乱码久久久久久88av| 粉嫩嫩av羞羞动漫久久久| 91蜜桃传媒精品久久久一区二区| 在线观看国产小视频| 扒开jk护士狂揉免费| 国产人妖一区| aaa免费看大片| 蜜桃传媒一区二区亚洲av| 国产福利在线看| 5g影院5g天天爽永久免费影院| 五月婷婷一区二区三区| аⅴ资源天堂资源库在线| 中文字幕色网站| 91久久精品视频| 先锋资源中文在线| 99久久精品国产色欲| 免费日本黄色网址| 在线看a视频| 91久久精品日日躁夜夜躁欧美| 成人在线播放网站| 日本a级片免费| 国产欧美最新羞羞视频在线观看| 波多野结衣精品| 亚洲剧情一区二区| 国产三级在线免费| 日日摸夜夜添一区| 亚洲男同gay网站| 欧美老女人性生活| 黄色在线一区| 久热综合在线亚洲精品| 一二三在线视频社区| 欧美v日韩v国产v| 不卡影院免费观看| 国产乱码精品一区二区三区av| 亚洲美女精品成人在线视频| 日日夜夜天天操| 999国产精品视频| 7878成人国产在线观看| 在线女人免费视频| 国产福利在线观看| 97人澡人人添人人爽欧美| 午夜精品影院在线观看| 亚洲高清不卡av| 久久国内精品一国内精品| 亚洲欧美日韩精品一区| www.欧美| 精品一区二区三区中文字幕老牛| 天天色天天爽| 欧美激情亚洲天堂| 9i看片成人免费看片| 色噜噜狠狠色综合欧洲selulu| av香蕉成人| 一二三四视频免费观看在线看| 99re8这里有精品热视频免费| 国产精品亚洲一区| 最近免费中文字幕mv视频| 九色视频九色自拍| 女同一区二区三区| 国产精品尤物福利片在线观看| 蜜臀av性久久久久蜜臀aⅴ四虎| 97精品资源在线观看| 国产中文在线播放| 天天天天天天操| 国产精品人人| 亚洲综合社区网| av网站免费在线看| 欧美精品激情在线观看| 好色先生视频污| 欧美国产中文字幕| 中文字幕免费一区二区三区| 欧美精品一区二区高清在线观看| 日韩中文字幕av电影| 国产日韩精品中文字无码| 精品视频—区二区三区免费| 色婷婷av一区二区三区丝袜美腿| 欧美激情视频播放| 欧洲一级毛片| 久久国产精品一区二区三区四区| 欧美黄色大片网站| 国产欧美日韩一区二区三区四区| 加勒比一区二区| 男女网站在线观看| 妞干网在线播放| 亚洲最大天堂网| 在线观看免费高清视频97| 丰满少妇一区二区三区| 在线中文字幕资源| 免费看成人吃奶视频在线| 国产精品视频| 一区二区三区四区精品视频| 成人性生活毛片| 亚洲欧美日韩在线综合| 18岁成年人网站| 亚洲伊人久久大香线蕉av| 久久视频免费看| 1区2区3区在线| 91精品国产综合久久久久久久久| 日本欧美色图| 久久人人爽av| 神马伦理电影| 亚洲黄色av女优在线观看| 天海翼中文字幕| 天天干天天做天天操| 国产一级精品aaaaa看| 一区二区三区黄| 成人超碰在线| 亚洲成人黄色在线| 你懂的视频在线播放| 亚洲一区精品在线| av亚洲一区二区三区| 国产精品久久久久久久久久精爆| 可以在线观看av的网站| 国产91在线精品| 亚洲三级一区| 欧美a极品极品欧美| 偷拍欧美精品| 红桃av永久久久| 2023国产精品| 一区二区三区在线视频111| 中文字幕色av一区二区三区| 久草福利在线观看| 伊人天天久久大香线蕉av色| rebdb初裸写真在线观看| 欧美gayvideo| 99riav一区二区三区| 亚洲精品国产精品乱码视色| 国模精品视频一区二区| 狠狠色综合色区| 在线免费观看av网| 高清日韩一区| 97精品国产97久久久久久| 亚洲女同女同女同女同女同69| 日韩欧美在线网址| 亚洲国产剧情在线观看| 免费a视频在线观看| h在线视频免费观看完整版| 亚洲高清资源综合久久精品| 91丨porny丨九色| 欧美日韩综合一区| 成码无人av片在线观看网站| 九九热在线免费| 亚洲最大色综合成人av| 亚洲日本中文字幕区| 91久久精品日日躁夜夜躁欧美| 久久久久999| 久久久国产精品一区二区中文| 久久久精品性| 欧美日韩亚洲精品内裤| 国产成人无码一区二区在线观看| 国产日韩在线一区二区三区| 色爱区成人综合网| 91精品在线免费视频| 欧美日韩国产免费观看| 日本电影中文字幕| 亚洲欧美成人一区二区三区| 国产在线欧美在线| 欧美激情在线免费观看| 蜜臀av性久久久久蜜臀aⅴ| 久久久成人av毛片免费观看| www.超碰在线观看| 黄色免费在线观看网站| 国产精品视频在线播放| 在线观看免费视频黄| 久久久激情视频| 午夜剧场日韩| 日韩有码一区| 欧美日韩国产成人在线| 国产不卡视频一区| 日韩免费在线看| 91黄色免费观看| 精品全国在线一区二区| 欧美美女18p| 色欧美在线观看| 亚洲第一导航| 欧美激情综合亚洲一二区| 在线免费看污| 蜜桃av噜噜一区二区三区麻豆| 黄动漫在线看| 亚洲人成绝费网站色ww| 清纯唯美激情亚洲| 91看片在线| 熟女性饥渴一区二区三区| 99久久夜色精品国产亚洲96| 奇米777在线视频| 人人澡人人添人人爽一区二区| 精品丰满少妇一区二区三区| 人人爽人人av| 日韩午夜小视频| 国产精品久久久久影院亚瑟| 秋霞午夜剧场| 欧美激情 一区| av国产精品| 婷婷在线播放| 欧美18一12sex性处hd| 日韩欧美在线中字| 国产一区在线播放| 成人一级片在线观看| 中文字幕第4页| 亚洲欧美日本精品| 中文字幕精品视频在线观看| 成人福利视频在| 97在线观看免费| 放荡的美妇在线播放| 手机在线免费毛片| 亚洲欧美日韩中文字幕在线观看| 亚洲视频日韩精品| 免费不卡在线观看av| www..com久久爱| 久久国产劲爆∧v内射| 国产一区二区伦理| 国产精品欧美日韩| 免费污网站在线观看| 日本免费一区二区三区视频| 精品免费国产一区二区| 在线视频日韩一区| 精品久久久久久最新网址| 亚洲精品国产精华液| 午夜免费精品视频| 超碰成人在线播放| 成人免费播放视频| 中文字幕 人妻熟女| 一区二区 亚洲| 成人高清视频观看www| 色婷婷激情五月| 无人区乱码一区二区三区| 九九精品九九| 欧美精品色网| 黄网址在线播放免费| av在线你懂的| 曰韩精品一区二区| 一二三区视频在线观看| 日本中文字幕免费| 亚洲男人天堂2023| 中文字幕亚洲欧美一区二区三区| 欧美日韩高清一区二区| 丰满大乳国产精品| 亚洲色图另类专区| 蜜桃视频动漫在线播放| 成人精品视频一区二区三区尤物| 最近中文字幕无免费| 日韩中文字幕在线观看| 国产精品久线在线观看| 亚洲一二三四久久| 99精品国产高清在线观看| 伊人免费在线| 在线视频国产三级| 欧美三级小说| 不卡一区2区| 精品亚洲免a| 中文字幕一精品亚洲无线一区| 日韩成人视屏| 亚洲成人第一| 欧美在线观看www| 欧美一级大片在线观看| 九九视频免费观看视频精品| 国产视频你懂的| 婷婷色播视频| 黄色av一区二区| 久久国产天堂福利天堂| 在线电影中文字幕| 欧美精品久久久久久久小说| 最新一本之道波多野结衣| 操女生的网站| 成人啪啪免费看| 国产有色视频色综合| 亚洲一区二区日本| 国产极品人妖在线观看| 天堂资源在线中文| 日韩黄色在线免费观看| 成人免费看的视频| 天天干天天舔天天射| 一区二区成人精品| 欧美国产禁国产网站cc| 午夜欧洲一区| 成人小视频在线播放| 欧美激情亚洲一区| 国产99久久精品一区二区| 欧美日韩国产第一页| 亚洲欧美高清在线| 日韩三级中文字幕| 午夜在线观看视频| 午夜在线观看视频网站| 欧美大奶子在线| 超碰中文字幕在线观看| 九九久久精品这里久久网| 欧美aaaaaa午夜精品| 免费电影网站在线观看| 在线看国产一区| 在线视频亚洲欧美| 2019国产精品自在线拍国产不卡| 狠狠一区二区三区| 激情五月激情综合| 亚洲小说欧美另类婷婷| 国产成人精品网站| 天堂在线观看一卡二卡三卡四卡| 亚洲mv大片欧洲mv大片| 亚洲男人7777| 欧美日韩性视频一区二区三区|