国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 編程 > Ruby > 正文

幾個加速Ruby on Rails的編程技巧

2020-10-29 19:41:05
字體:
供稿:網(wǎng)友

Ruby 語言常以其靈活性為人所稱道。正如 Dick Sites 所言,您可以 “為了編程而編程”。Ruby on Rails 擴展了核心 Ruby 語言,但正是 Ruby 本身使得這種擴展成為了可能。Ruby on Rails 使用了該語言的靈活性,這樣一來,無需太多樣板或額外的代碼就可以輕松編寫高度結(jié)構(gòu)化的程序:無需額外工作,就可以獲得大量標準的行為。雖然這種輕松自由的行為并不總是完美的,但畢竟您可以無需太多工作就可以獲得很多好的架構(gòu)。

例如,Ruby on Rails 基于模型-視圖-控制器(Model-View-Controller,MVC)模式,這意味著大多數(shù) Rails 應(yīng)用程序都可以清晰地分成三個部分。模型部分包含了管理應(yīng)用程序數(shù)據(jù)所需的行為。通常,在一個 Ruby on Rails 應(yīng)用程序中,模型和數(shù)據(jù)庫表之間的關(guān)系是 1:1;Ruby on Rails 默認使用的對象關(guān)系映射(ORM)ActiveRecord 負責管理模型與數(shù)據(jù)庫的交互,這意味著 Ruby on Rails 程序通常都具有(如果有的話)很少量的 SQL 代碼。第二個部分是視圖,它包含創(chuàng)建發(fā)送至用戶的輸出所需要的代碼;它通常由 HTML、JavaScript 等組成。最后的一個部分是控制器,它將來自用戶的輸入轉(zhuǎn)變?yōu)檎_的模型,然后使用適當?shù)囊晥D呈現(xiàn)響應(yīng)。

Rails 的倡導者通常都樂于將其易用性方面的提高歸功于 MVC 范型 ― 以及 Ruby 和 Rails 二者的其他一些特性,并稱很少有程序員能夠在較短的時間內(nèi)創(chuàng)建更多的功能。當然,這意味著投入到軟件開發(fā)的成本將能夠產(chǎn)生更多的商業(yè)價值,因此 Ruby on Rails 開發(fā)愈發(fā)流行。

不過,最初的開發(fā)成本并不是事情的全部,還有其他的后續(xù)成本需要考慮,比如應(yīng)用程序運行的維護成本和硬件成本。Ruby on Rails 開發(fā)人員通常會使用測試和其他的敏捷開發(fā)技術(shù)來降低維護成本,但是這樣一來,很容易忽視具有大量數(shù)據(jù)的 Rails 應(yīng)用程序的有效運行。雖然 Rails 能夠簡化對數(shù)據(jù)庫的訪問,但它并不總是能夠如此有效。
Rails 應(yīng)用程序為何運行緩慢?

Rails 應(yīng)用程序之所以運行緩慢,其中有幾個很基本的原因。第一個原因很簡單:Rails 總是會做一些假設(shè)為您加速開發(fā)。通常,這種假設(shè)是正確而有幫助的。不過,它們并不總能有益于性能,并且還會導致資源使用的效率低下 ― 尤其是數(shù)據(jù)庫資源。

例如,使用等同于 SELECT * 的一個 SQL 語句,ActiveRecord 會默認選擇查詢上的所有字段。在具有為數(shù)眾多的列的情況下 ― 尤其是當有些字段是巨大的 VARCHAR 或 BLOB 字段時 ― 就內(nèi)存使用和性能而言這種行為很有問題。

另一個顯著的挑戰(zhàn)是 N+1 問題,本文將對此進行詳細的探討。這會導致很多小查詢的執(zhí)行,而不是一個單一的大查詢。例如,ActiveRecord 無從知道一組父記錄中的哪一個會請求一個子記錄,所以它會為每個父記錄生成一個子記錄查詢。由于每查詢的負荷,這種行為將導致明顯的性能問題。

其他的挑戰(zhàn)則更多地與 Ruby on Rails 開發(fā)人員的開發(fā)習慣和態(tài)度相關(guān)。由于 ActiveRecord 能夠讓如此眾多的任務(wù)變得輕而易舉,Rails 開發(fā)人員常常會形成 “SQL 不怎樣” 的一種態(tài)度,即便在更適合使用 SQL 的時候,也會避免 SQL。創(chuàng)建和處理數(shù)量巨大的 ActiveRecord 對象的速度會非常緩慢,所以在有些情況下,直接編寫一個無需實例化任何對象的 SQL 查詢會更快些。

由于 Ruby on Rails 常被用來降低開發(fā)團隊的規(guī)模,又由于 Ruby on Rails 開發(fā)人員通常都會執(zhí)行部署和維護生產(chǎn)中的應(yīng)用程序所需的一些系統(tǒng)管理任務(wù),因此若對應(yīng)用程序的環(huán)境知之甚少,就很可能出問題。操作系統(tǒng)和數(shù)據(jù)庫有可能未被正確設(shè)置。比如,雖然并不最優(yōu),MySQL my.cnf 設(shè)置常常在 Ruby on Rails 部署內(nèi)保留它們的默認設(shè)置。此外,可能還會缺少足夠的監(jiān)控和基準測試工具來提供性能的長期狀況。當然,這并不是在責怪 Ruby on Rails 開發(fā)人員;這是非專業(yè)化導致的后果;在有些情況下,Rails 開發(fā)人員有可能是這兩個領(lǐng)域的專家。

最后一個問題是 Ruby on Rails 鼓勵開發(fā)人員在本地環(huán)境中進行開發(fā)。這么做有幾個好處 ― 比如,開發(fā)延遲的減少和分布性的提高 ― 但它并不意味著您可以因為工作站規(guī)模的減少而只處理有限的數(shù)據(jù)集。他們?nèi)绾伍_發(fā)以及代碼將被部署于何處之間的差異可能會是一個大問題。即便您在一個性能良好的輕載本地服務(wù)器上處理小規(guī)模的數(shù)據(jù)已經(jīng)很長一段時間,也會發(fā)現(xiàn)對于擁塞的服務(wù)器上的大型數(shù)據(jù)此應(yīng)用程序會有很明顯的性能問題。

當然,Rails 應(yīng)用程序具有性能問題的原因可能有很多。查出 Rails 應(yīng)用程序有何潛在性能問題的最佳方法是,利用能為您提供可重復、準確度量的診斷工具。

檢測性能問題

最好的工具之一是 Rails 開發(fā)日志,它通常位于每個開發(fā)機器上的 log/development.log 文件內(nèi)。它具有各種綜合指標:響應(yīng)請求所花費的總時間、花費在數(shù)據(jù)庫內(nèi)的時間所占的百分比、生成視圖所花時間的百分比等。此外,還有一些工具可用來分析此日志文件,比如 development-log-analyzer。

在生產(chǎn)期間,通過查看 mysql_slow_log 可以找到很多有價值的信息。更為全面的介紹超出了本文的討論范圍,更多信息可以在 參考資料 部分找到。

其中一個最強大也是最為有用的工具是 query_reviewer 插件(參見 參考資料)。這個插件可顯示在頁面上有多少查詢在執(zhí)行以及頁面生成需要多長時間。并且它還會自動分析 ActiveRecord 生成的 SQL 代碼以便發(fā)現(xiàn)潛在問題。例如,它能找到不使用 MySQL 索引的查詢,所以如果您忘記了索引一個重要的列并由此造成了性能問題,那么您將能很容易地找到這個列(有關(guān) MySQL 索引的更多信息,參見 參考資料)。此插件在一個彈出的 <div>(只在開發(fā)模式下可見)中顯示了所有這類信息。

最后,不要忘記使用類似 Firebug、yslow、Ping 和 tracert 這樣的工具來檢測性能問題是來自于網(wǎng)絡(luò)還是資源加載問題。

接下來,讓我們來看具體的一些 Rails 性能問題及其解決方案。

N+1 查詢問題

N+1 查詢問題是 Rails 應(yīng)用程序最大的問題之一。例如,清單 1 內(nèi)的代碼能生成多少查詢?此代碼是一個簡單的循環(huán),遍歷了一個假想的 post 表內(nèi)的所有 post,并顯示 post 的類別和它的主體。
清單 1. 未優(yōu)化的 Post.all 代碼

<%@posts = Post.all(@posts).each do |p|%>  <h1><%=p.category.name%></h1> <p><%=p.body%></p><%end%> 

答案:上述代碼生成了一個查詢外加 @posts 內(nèi)的每行一個查詢。由于每查詢的負荷,這可能會成為一個很大的挑戰(zhàn)。罪魁禍首是對 p.category.name 的調(diào)用。這個調(diào)用只應(yīng)用于該特定的 post 對象,而不是整個 @posts 數(shù)組。幸好,通過使用立即加載,我們可以修復這個問題。

立即加載 意味著 Rails 將自動執(zhí)行所需的查詢來加載任何特定子對象的對象。Rails 將使用一個 JOIN SQL 語句或一個執(zhí)行多個查詢的策略。不過,假設(shè)指定了將要使用的所有子對象,那么將永遠不會導致 N+1 的情形,在 N+1 情形下,一個循環(huán)的每個迭代都會生成額外的一個查詢。清單 2 是對 清單 1 內(nèi)代碼的修訂,它使用了立即加載來避免 N+1 問題。
清單 2. 用立即加載優(yōu)化后的 Post.all 代碼

<%@posts = Post.find(:all, :include=>[:category] @posts.each do |p|%>  <h1><%=p.category.name%></h1> <p><%=p.body%></p><%end%>

該代碼最多生成兩個查詢,而不管在此 posts 表內(nèi)有多少行。

當然,并不是所有情況都如此簡單。處理復雜的 N+1 查詢情況需要更多的工作。那么做這么多努力值得么?讓我們來做一些快速的測試。

測試 N+1

使用清單 3 內(nèi)的腳本,可以發(fā)現(xiàn)查詢可以達到 ― 多慢 ― 或多快。 清單 3 展示了如何在一個獨立腳本中使用 ActiveRecord 來建立一個數(shù)據(jù)庫連接、定義表并加載數(shù)據(jù)。然后,可以使用 Ruby 的內(nèi)置基準測試庫來查看哪種方式更快,快多少。
清單 3. 立即加載基準測試腳本

require 'rubygems'require 'faker'require 'active_record'require 'benchmark'# This call creates a connection to our database.ActiveRecord::Base.establish_connection( :adapter => "mysql", :host   => "127.0.0.1", :username => "root", # Note that while this is the default setting for MySQL, :password => "",   # a properly secured system will have a different MySQL              # username and password, and if so, you'll need to              # change these settings. :database => "test")# First, set up our database... class Category < ActiveRecord::Baseendunless Category.table_exists? ActiveRecord::Schema.define do create_table :categories do |t|  t.column :name, :string end end endCategory.create(:name=>'Sara Campbell/'s Stuff')Category.create(:name=>'Jake Moran/'s Possessions')Category.create(:name=>'Josh/'s Items')number_of_categories = Category.countclass Item < ActiveRecord::Base  belongs_to :category end# If the table doesn't exist, we'll create it.unless Item.table_exists? ActiveRecord::Schema.define do create_table :items do |t|  t.column :name, :string  t.column :category_id, :integer  end end endputs "Loading data..."item_count = Item.countitem_table_size = 10000if item_count < item_table_size (item_table_size - item_count).times do Item.create!(:name=>Faker.name,          :category_id=>(1+rand(number_of_categories.to_i))) endendputs "Running tests..."Benchmark.bm do |x|  [100,1000,10000].each do |size|  x.report "size:#{size}, with n+1 problem" do   @items=Item.find(:all, :limit=>size)  @items.each do |i|   i.category  end  end  x.report "size:#{size}, with :include" do   @items=Item.find(:all, :include=>:category, :limit=>size)  @items.each do |i|   i.category  end  end  end end

這個腳本使用 :include 子句測試在有和沒有立即加載的情況下對 100、1,000 和 10,000 個對象進行循環(huán)操作的速度如何。為了運行此腳本,您可能需要用適合于您的本地環(huán)境的參數(shù)替換此腳本頂部的這些數(shù)據(jù)庫連接參數(shù)。此外,需要創(chuàng)建一個名為 test 的 MySQL 數(shù)據(jù)庫。最后,您還需要 ActiveRecord 和 faker 這兩個 gem,二者可通過運行 gem install activerecord faker 獲得。

在我的機器上運行此腳本生成的結(jié)果如清單 4 所示。
清單 4. 立即加載的基準測試腳本輸出

-- create_table(:categories) -> 0.1327s-- create_table(:items) -> 0.1215sLoading data...Running tests...  user   system   total    realsize:100, with n+1 problem 0.030000  0.000000  0.030000 ( 0.045996)size:100, with :include 0.010000  0.000000  0.010000 ( 0.009164)size:1000, with n+1 problem 0.260000  0.040000  0.300000 ( 0.346721)size:1000, with :include 0.060000  0.010000  0.070000 ( 0.076739)size:10000, with n+1 problem 3.110000  0.380000  3.490000 ( 3.935518)size:10000, with :include 0.470000  0.080000  0.550000 ( 0.573861)

在所有情況下,使用 :include 的測試總是更為迅速 ― 分別快 5.02、4.52 和 6.86 倍。當然,具體的輸出取決于您的特定情況,但立即加載可明顯導致顯著的性能改善。

嵌套的立即加載

如果您想要引用一個嵌套的關(guān)系 ― 關(guān)系的關(guān)系,又該如何呢? 清單 5 展示了這樣一個常見的情形:循環(huán)遍歷所有的 post 并顯示作者的圖像,其中 Author 與 Image 是 belongs_to 的關(guān)系。
清單 5. 嵌套的立即加載用例

@posts = Post.all @posts.each do |p|  <h1><%=p.category.name%></h1> <%=image_tag p.author.image.public_filename %>  <p><%=p.body%>  <%end%>

此代碼與之前一樣亦遭遇了相同的 N+1 問題,但修復的語法卻沒有那么明顯,因為這里所使用的是關(guān)系的關(guān)系。那么如何才能立即加載嵌套關(guān)系呢?

正確的答案是使用 :include 子句的哈希語法。清單 6 給出了使用哈希語法的一個嵌套的立即加載。
清單 6. 嵌套的立即加載解決方案

@posts = Post.find(:all, :include=>{ :category=>[],                    :author=>{ :image=>[]}} )@posts.each do |p|  <h1><%=p.category.name%></h1> <%=image_tag p.author.image.public_filename %>  <p><%=p.body%>  <%end%>

正如您所見,您可以嵌套哈希和數(shù)組實量(literal)。請注意在本例中哈希和數(shù)組之間的惟一區(qū)別是哈希可以含有嵌套的子條目,而數(shù)組則不能。否則,二者是等效的。

間接的立即加載

并非所有的 N+1 問題都能很容易地察覺到。例如,清單 7 能生成多少查詢?
清單 7. 間接的立即加載示例用例

 <%@user = User.find(5)  @user.posts.each do |p|%>     <%=render :partial=>'posts/summary', :locals=>:post=>p   %> <%end%>

當然,決定查詢的數(shù)量需要對 posts/summary partial 有所了解。清單 8 中顯示了這個 partial。
清單 8. 間接立即加載 partial: posts/_summary.html.erb

 <h1><%=post.user.name%></h1>

不幸的是,答案是 清單 7 和 清單 8 在 post 內(nèi)每行生成一個額外查詢,查找用戶的名字 ― 即便 post 對象由 ActiveRecord 從一個已在內(nèi)存中的 User 對象自動生成。簡言之,Rails 并不能關(guān)聯(lián)子記錄與其父記錄。

修復方法是使用自引用的立即加載。基本上,由于 Rails 重載由父記錄生成的子記錄,所以需要立即加載這些父記錄,就如同父與子記錄之間是完全分開的關(guān)系一樣。代碼如清單 9 所示。
清單 9. 間接的立即加載解決方案

 <%@user = User.find(5, :include=>{:posts=>[:user]}) ...snip...

雖然有悖于直覺,但這種技術(shù)與上述技術(shù)的工作原理大致相似。但是,很容易使用這種技術(shù)進行過多的嵌套,尤其是在體系結(jié)構(gòu)復雜的情況下。簡單的用例還好,比如 清單 9 內(nèi)所示的,但繁復的嵌套也會出問題。在一些情況下,過多地加載 Ruby 對象有可能會比處理 N+1 問題還要緩慢 ― 尤其是當每個對象并沒有被整個樹遍歷時。在該種情況下,N+1 問題的其他解決方案可能更為適合。

一種方式是使用緩存技術(shù)。Rails V2.1 內(nèi)置了簡單的緩存訪問。使用 Rails.cache.read、 Rails.cache.write 及相關(guān)方法,可以輕松創(chuàng)建自己的簡單緩存機制,并且后端可以是一個簡單的內(nèi)存后端、一個基于文件的后端或一個分布式緩存服務(wù)器。在 參考資料 部分可以找到有關(guān) Rails 內(nèi)置緩存支持的更多信息。但您無需創(chuàng)建自己的緩存解決方案;您可以使用一個預置的 Rails 插件,比如 Nick Kallen 的 cache money 插件。這個插件提供了 write-through 緩存并以 Twitter 上使用的代碼為基礎(chǔ)。更多信息參見 參考資料。

當然,并不是所有的 Rails 問題都與查詢的數(shù)量有關(guān)。

Rails 分組和聚合計算

您可能遇到的一個問題是在 Ruby 所做的工作本應(yīng)由數(shù)據(jù)庫完成。這考驗了 Ruby 的強大程度。很難想象在沒有任何重大激勵的情況下人們會自愿在 C 中重新實現(xiàn)其數(shù)據(jù)庫代碼的各個部分,但很容易在 Rails 內(nèi)對 ActiveRecord 對象組進行類似的計算。但是,Ruby 總是要比數(shù)據(jù)庫代碼慢。所以請不要使用純 Ruby 的方式執(zhí)行計算,如清單 10 所示。
清單 10. 執(zhí)行分組計算的不正確方式

 all_ages = Person.find(:all).group_by(&:age).keys.uniq oldest_age = Person.find(:all).max

相反,Rails 提供了一系列的分組和聚合函數(shù)。可以像清單 11 所示的那樣使用它們。
清單 11. 執(zhí)行分組計算的正確方式

 all_ages = Person.find(:all, :group=>[:age])  oldest_age = Person.calcuate(:max, :age)

ActiveRecord::Base#find 有大量選項可用于模仿 SQL。更多信息可以在 Rails 文檔內(nèi)找到。注意,calculate 方法可適用于受數(shù)據(jù)庫支持的任何有效的聚合函數(shù),比如 :min、:sum 和 :avg。此外,calculate 能夠接受若干實參,比如 :conditions。查閱 Rails 文檔以獲得更詳細的信息。

不過,并不是在 SQL 內(nèi)能做的所有事情在 Rails 內(nèi)也能做。如果插件不夠,可以使用定制 SQL。

用 Rails 定制 SQL

假設(shè)有這樣一個表,內(nèi)含人的職業(yè)、年齡以及在過去一年中涉及到他們的事故的數(shù)量。可以使用一個定制 SQL 語句來檢索此信息,如清單 12 所示。
清單 12. 用 ActiveRecord 定制 SQL 的例子

sql = "SELECT profession,       AVG(age) as average_age,        AVG(accident_count)      FROM persons     GROUP       BY profession"Person.find_by_sql(sql).each do |row|   puts "#{row.profession}, " <<    "avg. age: #{row.average_age}, " <<    "avg. accidents: #{row.average_accident_count}"end

這個腳本應(yīng)該能生成清單 13 所示的結(jié)果。
清單 13. 用 ActiveRecord 定制 SQL 的輸出

 Programmer, avg. age: 18.010, avg. accidents: 9 System Administrator, avg. age: 22.720, avg. accidents: 8

當然,這是最簡單的例子。您可以自己想象一下如何能將此例中的 SQL 擴展成一個有些復雜性的 SQL 語句。您還可以使用 ActiveRecord::Base.connection.execute 方法運行其他類型的 SQL 語句,比如 ALTER TABLE 語句,如清單 14 所示。
清單 14. 用 ActiveRecord 定制非查找型 SQL

 ActiveRecord::Base.connection.execute "ALTER TABLE some_table CHANGE COLUMN..."

大多數(shù)的模式操作,比如添加和刪除列,都可以使用 Rails 的內(nèi)置方法完成。但如果需要,也可以使用執(zhí)行任意 SQL 代碼的能力。

結(jié)束語

與所有的框架一樣,如果不多加小心和注意,Ruby on Rails 也會遭遇性能問題。所幸的是,監(jiān)控和修復這些問題的技術(shù)相對簡單且易學,而且即便是復雜的問題,只要有耐心并對性能問題的源頭有所了解,也是可以解決的。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
国产高清免费av在线| 国产极品视频| 男人天堂99| 九九热免费视频| 国产麻豆精品视频一区二区| 天天操天天射天天插| 国产桃色电影在线播放| 国产精品黄页网站在线播放免费| 午夜av电影| av网址在线播放| 国产美女av在线| 国产丝袜精品丝袜| 亚洲精品xxxxx| 国产精品一区二区三区四区色| 国产一级大片| а天堂8中文最新版在线官网| 九九在线观看免费视频| 国产香蕉视频在线看| 亚洲精品自拍区在线观看| 久久国产情侣| 精品美女调教视频| 自拍亚洲国产| 黄色免费av| 日本久久网站| av免费在线播放| 国产天堂资源| 欧美日韩在线视频免费观看| 国产成+人+亚洲+欧美+综合| 国产九色porn网址| 狠狠干天天爱| 牛牛在线精品视频| av在线不卡播放| 在线观看精品视频一区二区三区| 国产亚洲精品久久久久久移动网络 | 国产精品亚洲色图| 999精品网| 影音先锋在线中文字幕| www.xxx黄| 国产成人综合美国十次| 国产一级免费在线观看| 黄色国产网站在线观看| 青青草在线视频免费观看| 国产99re| 91视频久色| 五月天天在线| 午夜视频在线观看网站午夜视频在线 | 日本中文字幕在线观看| 香蕉视频网站在线观看| av网站在线播放| 亚洲欧美小说国产图片| 亚洲精品久久久成人| 啪啪免费视频一区| 高清av中文在线字幕观看1| 欧美成人久久电影香蕉| 黄色片视频在线观看| 91超碰免费在线| 国产一级网站视频在线| 国产高清av在线| 在线āv视频| 欧美精品小视频| 国产午夜电影| 精品国产99久久久久久| 麻豆电影传媒二区| 国产区高清在线| 日本免费黄色| 国产精品18久久久久久久久久| 国产福利在线免费观看| 开心婷婷激情五月| 91九色在线看| 国产中文第一页| 国产精品麻豆一区二区三区| 亚洲精品在线播放视频| 99热在线免费观看| 亚洲妇熟xxxx妇色黄| 国产一级黄色| 国产中文字幕在线播放| 国产福利在线播放| 久久久久国产精品嫩草影院| 69堂视频在线观看国产| 国产在线高清| 青青草在线视频免费观看| 国产黄色免费在线观看| 国产嫩草在线视频| 超碰免费在线播放| 在线国产小视频| 精品一区二区三区免费站| 国产美女在线播放| 国产在线高清| 久久国产情侣| www.色五月| 亚洲欧美自拍另类| 国产视频一二| 成在线人视频免费视频| 日p在线观看| www.色五月| www.av在线视频| 四虎在线免费视频| 日本久久国产| 超碰在线免费播放| 九七电影韩国女主播在线观看| 亚洲人在线播放| 天堂中文在线观看| 四虎免费播放| 超碰人人在线| 日本中文字幕在线观看| 日本中文字幕在线看| 欧美精品久久久久久久小说| 天天插天天射| 久精品在线观看| 国产剧情av在线| 国产女主播在线观看| 国产激情视频一区二区| 国产9色视频| 亚洲精品视频在线免费| 欧美啪啪精品| √天堂8资源中文在线| 国产精品国产国产aⅴ| 91社区在线观看| eeuss影院在线观看第一页| аⅴ成人天堂中文在线| 久久久久久77777| 国产乱妇乱子| 国产精品jvid在线观看| 亚洲妇熟xxxx妇色黄| 久久精品视频免费看| 国产精品视频福利一区二区 | 尤物网站在线| av福利在线播放| 好吊日视频在线观看| 2018狠狠干| 国产免费av高清在线| av天天在线| 尤物网在线观看| www.操操| 在线天堂av| 国产麻豆综合视频在线观看| 国产porny蝌蚪视频| 玖玖在线视频| 天天插天天干| 91九色在线看| 国产视频青青| 中文字幕人成高视频| 嫩草在线播放| 亚洲欧美精选| 永久免费av片在线观看全网站| 国产中文字幕在线播放| h网站免费在线观看| 国产对白在线| √天堂资源地址在线官网| 亚洲大香人伊一本线| 国产日韩精品在线看| 国产蜜臀在线| 免费观看一二区视频网站| 四虎一区二区三区| av在线天堂| av网址在线看| 天堂√中文在线| 人人在线视频| 久久精品无码一区二区日韩av| 亚洲综合色视频在线观看 | av亚洲在线| 永久免费av片在线观看全网站| 国产美女在线观看| 天堂资源在线中文| 国产小黄视频| 国产福利在线视频| 在线激情网站| 国产永久免费| 国产一卡2卡3卡4卡网站免费| 国产精品自拍亚洲| 国产精品美女一区二区视频| 国产对白国语对白| 在线播放国产区| 欧美日韩不卡中文字幕在线| 欧美啪啪精品| 国产一二三在线观看| 国产福利在线视频| 精品视频麻豆入口| www.色五月| 国产网站免费观看| 精品176二区| 久久av少妇| 精品国产一区二区三区四区阿崩 | 最新中文字幕在线| 国产对白在线| 亚洲精品天堂在线观看| 国内a∨免费播放| 国产91在线视频蝌蚪| 久久精品蜜桃| 永久免费在线观看| 日本最新在线视频| 天天草天天草| 国产日产一区二区| 国产尤物视频| 亚洲夜夜综合| 国产区在线视频| 国产免费a∨片在线观看不卡| 在线免费观看你懂的| 国产一区精品| 激情视频国产|