亚洲成人一区在线观看_天堂网www_国产精品久久9_中文在线播放_伊人天天_久久精品久久久精品美女

當前位置:首頁 > 網站舊欄目 > 學習園地 > 設計軟件教程 > 如何寫超強伸縮性的多游戲玩家服務器

如何寫超強伸縮性的多游戲玩家服務器
2010-01-13 23:14:35  作者:  來源:
介紹
本文以我的OpenPoker項目為例子,講述了一個構建超強伸縮性的在線多游戲玩家系統。
OpenPoker是一個超強多玩家紙牌服務器,具有容錯、負載均衡和無限伸縮性等特性。
源代碼位于我的個人站點上,大概10,000行代碼,其中1/3是測試代碼。

在OpenPoker最終版本敲定之前我做了大量調研,我嘗試了Delphi、Python、C#、C/C++和Scheme。我還用Common Lisp寫了紙牌引擎。
雖然我花費了9個月的時間研究原型,但是最終重寫時只花了6個星期的時間。
我認為我所節約的大部分時間都得益于選擇Erlang作為平臺。

相比之下,舊版本的OpenPoker花費了一個4~5人的團隊9個月時間。

Erlang是什么東東?
我建議你在繼續閱讀本文之前瀏覽下Erlang FAQ,這里我給你一個簡單的總結...

Erlang是一個函數式動態類型編程語言并自帶并發支持。它是由Ericsson特別為控制開關、轉換協議等電信應用設計的。
Erlang十分適合構建分布式、軟實時的并發系統。

由Erlang所寫的程序通常由成百上千的輕量級進程組成,這些進程通過消息傳遞來通訊。
Erlang進程間的上下文切換通常比C程序線程的上下文切換要廉價一到兩個數量級。

使用Erlang寫分布式程序很簡單,因為它的分布式機制是透明的:程序不需要了解它們是否分布。

Erlang運行時環境是一個虛擬機,類似于Java虛擬機。這意味著在一個價格上編譯的代碼可以在任何地方運行。
運行時系統也允許在一個運行著的系統上不間斷的更新代碼。
如果你需要額外的性能提升,字節碼也可以編譯成本地代碼。

請移步Erlang site,參考Getting started、Documentation和Exampes章節等資源。

為何選擇Erlang?
構建在Erlang骨子里的并發模型特別適合寫在線多玩家服務器。

一個超強伸縮性的多玩家Erlang后端構建為擁有不同“節點”的“集群”,不同節點做不同的任務。
一個Erlang節點是一個Erlang VM實例,你可以在你的桌面、筆記本電腦或服務器上上運行多個Erlang節點/VM。
推薦一個CPU一個節點。

Erlang節點會追蹤所有其他和它相連的節點。向集群里添加一個新節點所需要的只是將該新節點指向一個已有的節點。
一旦這兩個節點建立連接,集群里所有其他的節點都會知曉這個新節點。

Erlang進程使用一個進程id來相互發消息,進程id包含了節點在哪里運行的信息。進程不需要知道其他進程在哪里就可以通訊。
連接在一起的Erlang節點集可以看作一個網格或者超級計算設備。

超多玩家游戲里玩家、NPC和其他實體最好建模為并行運行的進程,但是并行很難搞是眾所皆知的。Erlang讓并行變得簡單。

Erlang的位語法∞讓它在處理結構封裝/拆解的能力上比Perl和Python都要強大。這讓Erlang特別適合處理二進制網絡協議。

OpenPoker架構
OpenPoker里的任何東西都是進程。玩家、機器人、游戲等等多是進程。
對于每個連接到OpenPoker的客戶端都有一個玩家“代理”來處理網絡消息。
根據玩家是否登錄來決定部分消息忽略,而另一部分消息則發送給處理紙牌游戲邏輯的進程。

紙牌游戲進程是一個狀態機,包含了游戲每一階段的狀態。
這可以讓我們將紙牌游戲邏輯當作堆積木,只需將狀態機構建塊放在一起就可以添加新的紙牌游戲。
如果你想了解更多的話可以看看cardgame.erl的start方法。

紙牌游戲狀態機根據游戲狀態來決定不同的消息是否通過。
同時也使用一個單獨的游戲進程來處理所有游戲共有的一些東西,如跟蹤玩家、pot和限制等等。
當在我的筆記本電腦上模擬27,000個紙牌游戲時我發現我擁有大約136,000個玩家以及總共接近800,000個進程。

下面我將以OpenPoker為例子,專注于講述怎樣基于Erlang讓實現伸縮性、容錯和負載均衡變簡單。
我的方式不是特別針對紙牌游戲。同樣的方式可以用在其他地方。

伸縮性
我通過多層架構來實現伸縮性和負載均衡。
第一層是網關節點。
游戲服務器節點組成第二層。
Mnesia“master”節點可以認為是第三層。

Mnesia是Erlang實時分布式數據庫。Mnesia FAQ有一個很詳細的解釋。Mnesia基本上是一個快速的、可備份的、位于內存中的數據庫。
Erlang里沒有對象,但是Mnesia可以認為是面向對象的,因為它可以存儲任何Erlang數據。

有兩種類型的Mnesia節點:寫到硬盤的節點和不寫到硬盤的節點。除了這些節點,所有其他的Mnesia節點將數據保存在內存中。
在OpenPoker里Mnesia master節點會將數據寫入硬盤。網關和游戲服務器從Mnesia master節點獲得數據庫并啟動,它們只是內存節點。

當啟動Mnesia時,你可以給Erlang VM和解釋器一些命令行參數來告訴Mnesia master數據庫在哪里。
當一個新的本地Mnesia節點與master Mnesia節點建立連接之后,新節點變成master節點集群的一部分。

假設master節點位于apple和orange節點上,添加一個新的網關、游戲服務器等等。OpenPoker集群簡單的如下所示:
Java代碼 復制代碼
  1. erl -mnesia extra_db_nodes \['db@apple','db@orange'\] -s mnesia start  

-s mnesia start相當于這樣在erlang shell里啟動Mnedia:
Java代碼 復制代碼
  1. erl -mnesia extra_db_nodes \['db@apple','db@orange'\]   
  2. Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0]   
  3.   
  4. Eshell V5.4.8 (abort with ^G)   
  5. 1> mnesia:start().   
  6. ok  

OpenPoker在Mnesia表里保存配置信息,并且這些信息在Mnesia啟動后立即自動被新的節點下載。零配置!

容錯
通過添加廉價的Linux機器到我的服務器集群,OpenPoker讓我隨心所欲的變大。
將幾架1U的服務器放在一起,這樣你就可以輕易的處理500,000甚至1,000,000的在線玩家。這對MMORPG也是一樣。

我讓一些機器運行網關節點,另一些運行數據庫master來寫數據庫事務到硬盤,讓其他的機器運行游戲服務器。
我限制游戲服務器接受最多5000個并發的玩家,這樣當游戲服務器崩潰時最多影響5000個玩家。

值得注意的是,當游戲服務器崩潰時沒有任何信息丟失,因為所有的Mnesia數據庫事務都是實時備份到其他運行Mnesia以及游戲服務器的節點上的。

為了預防出錯,游戲客戶端必須提供一些援助來平穩的重連接OpenPoker集群。
一旦客戶端發現一個網絡錯誤,它應該連接網關,接受一個新的游戲服務器地址,然后重新連接新的游戲服務器。
下面發生的事情需要一定技巧,因為不同類型的重連接場景需要不同的處理。

OpenPoker會處理如下幾種重連接的場景:
1,游戲服務器崩潰
2,客戶端崩潰或者由于網絡原因超時
3,玩家在線并且在一個不同的連接上
4,玩家在線并且在一個不同的連接上并在一個游戲中

最常見的場景是一個客戶端由于網絡出錯而重新連接。
比較少見但仍然可能的場景是客戶端已經在一臺機器上玩游戲,而此時從另一臺機器上重連接。

每個發送給玩家的OpenPoker游戲緩沖包和每個重連接的客戶端將首先接受所有的游戲包,因為游戲不是像通常那樣正常啟動然后接受包。
OpenPoker使用TCP連接,這樣我不需要擔心包的順序——包會按正確的順序到達。

每個客戶端連接由兩個OpenPoker進程來表現:socket進程和真正的玩家進程。
先使用一個功能受限的visitor進程,直到玩家登錄。例如visitor不能參加游戲。
在客戶端斷開連接后,socket進程死掉,而玩家進程仍然活著。

當玩家進程嘗試發送一個游戲包時可以通知一個死掉的socket,并讓它自己進入auto-play模式或者掛起。
在重新連接時登錄代碼將檢查死掉的socket和活著的玩家進程的結合。代碼如下:
Java代碼 復制代碼
  1. login({atomic, [Player]}, [_Nick, Pass|_] = Args)   
  2.   when is_record(Player, player) ->   
  3.     Player1 = Player#player {   
  4.       socket = fix_pid(Player#player.socket),   
  5.       pid = fix_pid(Player#player.pid)   
  6.     },   
  7.     Condition = check_player(Player1, [Pass],   
  8.       [   
  9.         fun is_account_disabled/2,   
  10.         fun is_bad_password/2,   
  11.         fun is_player_busy/2,   
  12.         fun is_player_online/2,   
  13.         fun is_client_down/2,   
  14.         fun is_offline/2  
  15.       ]),   
  16.     ...  

condition本身由如下代碼決定:
Java代碼 復制代碼
  1. is_player_busy(Player, _) ->   
  2.   {Online, _} = is_player_online(Player, []),   
  3.   Playing = Player#player.game /= none,   
  4.   {Online and Playing, player_busy}.   
  5.   
  6. is_player_online(Player, _) ->   
  7.   SocketAlive = Player#player.socket /= none,   
  8.   PlayerAlive = Player#player.pid /= none,   
  9.   {SocketAlive and PlayerAlive, player_online}.   
  10.   
  11. is_client_down(Player, _) ->   
  12.   SocketDown = Player#player.socket == none,   
  13.   PlayerAlive = Player#player.pid /= none,   
  14.   {SocketDown and PlayerAlive, client_down}.   
  15.   
  16. is_offline(Player, _) ->   
  17.   SocketDown = Player#player.socket == none,   
  18.   PlayerDown = Player#player.pid == none,   
  19.   {SocketDown and PlayerDown, player_offline}.  

注意login方法的第一件事是修復死掉的進程id:
Java代碼 復制代碼
  1. fix_pid(Pid)   
  2.   when is_pid(Pid) ->   
  3.     case util:is_process_alive(Pid) of   
  4.     true ->   
  5.       Pid;   
  6.     _->   
  7.       none   
  8.     end;   
  9.   
  10. fix_pid(Pid) ->   
  11.     Pid.  

以及:
Java代碼 復制代碼
  1. -module(util).   
  2.   
  3. -export([is_process_alive/1]).   
  4.   
  5. is_process_alive(Pid)   
  6.   when is_pid(Pid) ->   
  7.     rpc:call(node(Pid), erlang, is_process_alive, [Pid]).  

Erlang里一個進程id包括正在運行的進程的節點的id。
is_pid(Pid)告訴我它的參數是否是一個進程id(pid),但是不能告訴我進程是活著還是死了。
Erlang自帶的erlang:is_process_alive(Pid)告訴我一個本地進程(運行在同一節點上)是活著還是死了,但沒有檢查遠程節點是或者還是死了的is_process_alive變種。

還好,我可以使用Erlang rpc工具和node(pid)來在遠程節點上調用is_process_alive()。
事實上,這跟在本地節點上一樣工作,這樣上面的代碼就可以作為全局分布式進程檢查器。

剩下的唯一的事情是在不同的登錄條件上活動。
最簡單的情況是玩家離線,我期待一個玩家進程,連接玩家到socket并更新player record。
Java代碼 復制代碼
  1. login(Player, player_offline, [Nick, _, Socket]) ->   
  2.   {ok, Pid} = player:start(Nick),   
  3.   OID = gen_server:call(Pid, 'ID'),   
  4.   gen_server:cast(Pid, {'SOCKET', Socket}),   
  5.   Player1 = Player#player {   
  6.     oid = OID,   
  7.     pid = Pid,   
  8.     socket = Socket   
  9.   },   
  10.   {Player1, {ok, Pid}}.  

假如玩家登陸信息不匹配,我可以返回一個錯誤并增加錯誤登錄次數。如果次數超過一個預定義的最大值,我就禁止該帳號:
Java代碼 復制代碼
  1. login(Player, bad_password, _) ->   
  2.   N = Player#player.login_errors + 1,   
  3.   {atomic, MaxLoginErrors} =   
  4.   db:get(cluster_config, 0, max_login_errors),   
  5.   if  
  6.   N > MaxLoginErrors ->   
  7.     Player1 = Player#player {   
  8.       disabled = true  
  9.     },   
  10.     {Player1, {error, ?ERR_ACCOUNT_DISABLED}};   
  11.   true ->   
  12.     Player1 = Player#player {   
  13.       login_errors =N   
  14.     },   
  15.     {Player1, {error, ?ERR_BAD_LOGIN}}   
  16.   end;   
  17.   
  18. login(Player, account_disabled, _) ->   
  19.     {Player, {error, ?ERR_ACCOUNT_DISABLED}};  

注銷玩家包括使用Object ID(只是一個數字)找到玩家進程id,停止玩家進程,然后在數據庫更新玩家record:
Java代碼 復制代碼
  1. logout(OID) ->   
  2.   case db:find(player, OID) of   
  3.   {atomic, [Player]} ->   
  4.     player:stop(Player#player.pid),   
  5.     {atomic, ok} = db:set(player, OID,   
  6.       [{pid, none},   
  7.       {socket, none}];   
  8.   _->   
  9.     oops   
  10.   end.  

這樣我就可以完成多種重連接condition,例如從不同的機器重連接,我只需先注銷再登錄:
Java代碼 復制代碼
  1. login(Player, player_online, Args) ->   
  2.   logout(Player#player.oid),   
  3.   login(Player, player_offline, Args);  

如果玩家空閑時客戶端重連接,我所需要做的只是在玩家record里替換socket進程id然后告訴玩家進程新的socket:
Java代碼 復制代碼
  1. login(Player, client_down, [_, _, SOcket]) ->   
  2.   gen_server:cast(Player#player.pid, {'SOCKET', Socket}),   
  3.   Player1 = Player#player {   
  4.     socket = Socket   
  5.   },   
  6.   {Player1, {ok, Player#player.pid}};  

如果玩家在游戲中,這是我們運行上面的代碼,然后告訴游戲重新發送時間歷史:
Java代碼 復制代碼
  1. login(Player, player_busy, Args) ->   
  2.   Temp = login(Player, client_down, Args),   
  3.   cardgame:cast(Player#player.game,   
  4.     {'RESEND UPDATES', Player#player.pid}),   
  5.   Temp;  

總體來說,一個實時備份數據庫,一個知道重新建立連接到不同的游戲服務器的客戶端和一些有技巧的登錄代碼運行我提供一個高級容錯系統并且對玩家透明。

負載均衡
我可以構建自己的OpenPoker集群,游戲服務器數量大小隨心所欲。
我希望每臺游戲服務器分配5000個玩家,然后在集群的活動游戲服務器間分散負載。
我可以在任何時間添加一個新的游戲服務器,并且它們將自動賦予自己接受新玩家的能力。

網關節點分散玩家負載到OpenPoker集群里活動的游戲服務器。
網關節點的工作是選擇一個隨機的游戲服務器,詢問它所連接的玩家數量和它的地址、主機和端口號。
一旦網關找到一個游戲服務器并且連接的玩家數量少于最大值,它將返回該游戲服務器的地址到連接的客戶端,然后關閉連接。

網關上絕對沒有壓力,網關的連接都非常短。你可以使用非常廉價的機器來做網關節點。

節點一般都成雙成對出現,這樣一個節點崩潰后還有另一個繼續工作。你可能需要一個類似于Round-robin DNS的機制來保證不只一個單獨的網關節點。

網關怎么知曉游戲服務器?

OpenPoker使用Erlang Distirbuted Named Process Groups工具來為游戲服務器分組。
該組自動對所有的節點全局可見。
新的游戲服務器進入游戲服務器后,當一個游戲服務器節點崩潰時它被自動刪除。

這是尋找容量最大為MaxPlayers的游戲服務器的代碼:
Java代碼 復制代碼
  1. find_server(MaxPlayers) ->   
  2.   case pg2:get_closest_pid(?GAME_SERVER) of   
  3.   Pid when is_pid(Pid) ->   
  4.     {Time, {Host, Port}} = timer:tc(gen_server, call, [Pid, 'WHERE']),   
  5.     Coutn = gen_server:call(Pid, 'USER COUNT'),   
  6.     if  
  7.       Count < MaxPlayers ->   
  8.         io:format("~s:~w ~w players~n", [Host, Port, Count]),   
  9.         {Host, Port};   
  10.       true ->   
  11.         io:format("~s:~w is full...~n", [Host, Port]),   
  12.         find_server(MaxPlayers)   
  13.     end;   
  14.   Any ->   
  15.     Any   
  16.   end.  

pg2:get_closest_pid()返回一個隨機的游戲服務器進程id,因為網關節點上不允許跑任何游戲服務器。
如果一個游戲服務器進程id返回,我詢問游戲服務器的地址(host和port)和連接的玩家數量。
只要連接的玩家數量少于最大值,我返回游戲服務器地址給調用者,否則繼續查找。

多出口電源插座中間件
OpenPoker是一個開源軟件,我最近在將它推銷給多個紙牌游戲廠商。
所有的廠商都有同樣的伸縮性和容錯的問題,即使做了多年開發。
有的最近剛剛完成服務器軟件重寫,而有的剛剛開始。
所有的廠商都嚴重依賴于它們的Java基礎架構,可以理解,它們不想換Erlang。

看來有一個需求必須滿足。我思考的越多,發現Erlang越適合提供高效的解決方案。
我把這個解決方案看作一個多出口電源插座。

你可以像寫一個使用數據庫后端的基于socket的服務器一樣來寫游戲服務器。
事實上,目前游戲服務器就是這樣寫的。
游戲服務器是標準的電源插頭,游戲服務器的多個實例插入到電源插座中,而玩家從另一端流過。

你提供游戲服務器,而我提供伸縮性、負載均衡和容錯。
我讓玩家連接到電源插座并監控你的游戲服務器,必要時重啟它們。
當一個游戲服務器崩潰時我將玩家切換到另一臺游戲服務器,你可以往插座里插入任意多的游戲服務器。

電源插座中間件是一個黑盒子,它位于你的玩家和你的服務器之間,很可能不需要你改動任何代碼。
你會得到伸縮性、負載均衡、容錯等諸多益處而只需改動極少的一部分現有架構。

今天你就可以用Erlang寫這個中間件,然后運行在一個內核調優過以支持大量TCP連接的Linux機器上,而將你的服務器放在一個防火墻后面。
即使你不這樣做,我建議你馬上仔細看看Erlang,想想如何使用它來簡化你的超強多玩家服務器架構。而我會在這兒幫助你!

安徽新華電腦學校專業職業規劃師為你提供更多幫助【在線咨詢
主站蜘蛛池模板: 日韩精品一区二区三区在线 | 一区二区三区四区在线 | 在线成人av | 欧美一级艳情片免费观看 | 精品国产一区二区三区久久久 | 综合一区 | 久久久精品网站 | 日韩不卡中文字幕 | 日韩激情综合网 | 亚洲伊人成人 | 亚洲色图偷拍视频 | 国产精品久久免费视频 | 久久99这里只有精品 | 国产黄色在线免费看 | 真实国产露脸乱 | 日韩第一区 | 久久久日本 | 天天干狠狠操 | 亚洲va欧美va天堂v国产综合 | 中文字幕成人在线 | 国产精品无码永久免费888 | 免费av电影在线观看 | 欧美成人久久 | 久在线视频 | 日本在线视频一区二区 | 成人久久久精品国产乱码一区二区 | 玖玖综合网 | 成人免费在线播放 | 久草成人| 一区二区国产精品 | 亚洲一区二区在线视频 | 久久久久久黄 | 成人v片 | 成人av电影网址 | 亚洲一区二区三区久久久 | 精品国产乱码久久久久久影片 | av影音资源 | 欧美日韩黄 | 欧美精品一区在线发布 | 伊人久久国产 | 精品成人在线 | 中文字幕av一区二区 | 国产中文字幕在线播放 | 日韩在线免费观看av | 97在线视频免费 | 天天影视色香欲 | 欧美日韩视频在线 | 九九热欧美| 精品视频久久 | 欧美性网 | 国产a一三三四区电影 | 亚洲免费视频在线 | 日韩欧美h| 精品久久一级片 | 欧美成人精品 | 香港三级日本三级a视频 | 中国电影黄色一级片免费观看 | 在线观看你懂的视频 | 久久国产电影 | 久久黄视频 | 日韩视频中文字幕 | 国产午夜一区二区三区 | 夜夜爽99久久国产综合精品女不卡 | 久久天堂 | 欧美黄色一区 | 激情91| 久久精品视频在线播放 | 久久久国产精品 | 91亚洲免费| www.色综合| jav成人av免费播放 | 成人欧美一区二区三区黑人孕妇 | 日韩中文字幕av | 久久久夜夜夜 | 伊人久久国产 | 天天干天天草 | 亚洲精品久久久久久久久久久 | 国产精品毛片久久久久久久 | 国产精品自产拍在线观看 | 亚洲精品中文字幕乱码无线 | 成人小视频在线观看 | 国产精品一区二区三区免费 | 国产精品99久久久久久久久久久久 | 九九在线视频 | 亚洲成人一二区 | 欧美日韩在线观看中文字幕 | 日韩视频在线视频 | 成人久久18免费观看 | 91秦先生艺校小琴 | 欧美黄色一区二区 | 99精品欧美一区二区三区 | 中文字幕免费看 | 大桥未久亚洲精品久久久强制中出 | 国产精品日韩在线观看 | 国产精品成人在线 | 美日一级毛片 | 蜜桃视频一区二区三区 | www.久久久.com | 一本大道久久a久久精二百 国产精品片aa在线观看 | 一区二区免费在线 | 国产日韩高清在线 | 精品国产欧美一区二区 | 成年网站视频 | 久热九九 | 免费一区 | 亚洲精品二区 | 亚洲中字幕| 国产精品99久久免费观看 | av网站推荐 | 九九99| 亚洲成人日韩 | 蜜桃视频精品 | 亚洲三区视频 | 国产成人一区二区 | 天堂成人国产精品一区 | 久久国产精品一区二区三区 | 亚洲第一天堂无码专区 | 国产精品久久久久久久久久免费看 | 日韩一区二区在线电影 | 亚洲精品影院 | 日韩三级视频 | 成人精品一区二区三区中文字幕 | 日本一区二区中文字幕 | 久久国 | 日本男人的天堂 | 欧洲亚洲一区 | 国产做a| 成人久久久久 | 91啪影院 | 一级毛片免费观看 | 久操视频在线观看 | 国产拍拍视频 | 国产欧美综合在线 | 日日干天天操 | 亚洲精品一区在线观看 | 精品欧美乱码久久久久久 | 国产精品久久嫩一区二区免费 | 久久免费看| 有码在线| 久久久99国产精品免费 | 激情久久久| 国产精品久久久久久一区二区三区 | 欧美一区二区三区视频 | 91成人区 | 久久久久久国产视频 | 色玖玖 | 国产亚洲视频在线观看 | 欧美久久久久久久久久伊人 | 视频精品一区二区三区 | 国产一区二区视频在线观看 | 国产精品网站在线看 | 欧美日韩一区二区在线播放 | 狠狠色丁香婷婷综合 | 成人精品久久久 | 亚洲国产成人精品女人久久久 | 欧美一区二区三区在线观看 | 亚洲成人av在线 | 一级片网 | 亚洲一区二区三区免费视频 | 欧美v片| 亚洲高清视频在线 | www.国产精品 | 成人免费视频网站 | 狠狠色狠狠色综合网 | 精品视频免费观看 | 懂色一区二区三区免费观看 | 国产黄色在线观看 | 不卡成人| 亚洲精品天堂 | 日本精品免费 | 黑人巨大精品欧美一区二区免费 | 午夜精品久久久久久久久 | 国产精品久久久久久妇女6080 | 黄视频网站免费观看 | 午夜视频在线观看网址 | 四虎永久在线观看 | 久久精品一区二区三区四区 | 欧美亚洲一区二区三区 | av先锋资源| 欧美日韩亚洲一区二区 | 精品国产91亚洲一区二区三区www | 精品国产区 | 在线免费成人 | 久久www免费视频 | 国产一区二区三区在线 | 久久精品中文字幕一区 | 91精品国产高清一区二区三区 | 777xacom | 91精品国产综合久久久亚洲 | 中文成人无字幕乱码精品 | 日韩成人av在线 | 久久久精品一区二区三区 | 中文字幕av一区二区 | 91精品久久久久 | 91亚洲国产成人久久精品网站 | 中文字幕avav| 日韩欧美精品一区 | 91麻豆精品国产91久久久更新资源速度超快 | 中文字幕久久久 | 亚洲免费观看视频 | 91精品国产欧美一区二区成人 | 在线一区二区三区做爰视频网站 | 亚洲精品乱码久久久久久花季 | 亚洲综合社区 | 最近日韩中文字幕 | 亚洲毛片在线 | 亚洲美女网址 | 国产一区二区三区四区在线观看 | 91短视频版在线观看免费大全 | 亚洲精品日韩综合观看成人91 | 中文字幕一区二区三区乱码图片 | 精品视频一区二区在线 | 91精品国产乱码久久久久久久久 | 亚洲美女一区二区三区 | 一区二区三区视频免费在线观看 | 久草视频在线看 | 国产精品高清在线 | 91色在线观看| 欧美2区 | 精品日韩一区二区三区 | 亚洲第1页 | 国产一级特黄aaa大片评分 | 国产高清久久久 | 日韩一区二区在线观看视频 | 亚洲美女视频 | 成人精品久久 | 国产精品视频不卡 | 黄色在线免费 | 每日更新av| 二区视频 | 中文字幕第33页 | 天天操夜夜爽 | 亚洲一区二区三区四区在线观看 | 羞羞视频网站 | 精品久久久久久久久久久久久久 | 日本黄色免费播放 | 亚洲视频在线播放 | 国产成人综合一区二区三区 | 亚洲免费综合 | 久久国产精品久久 | 激情网站免费 | 国产成人61精品免费看片 | 精品99免费| 国产精品久久久久久久久久久不卡 | 亚洲日日操 | 性高湖久久久久久久久 | 亚洲一区二区三区四区在线观看 | 婷婷综合五月天 | 日韩在线免费 | 中文字幕亚洲综合 | 中文字幕在线观看 | 亚洲综合无码一区二区 | 色乱码一区二区三区网站 | 国产区区 | 日韩中文字幕在线 | 91嫩草在线| 天天艹逼 | 妞干网国产 | 国产成人午夜精品影院游乐网 | 天天操狠狠操网站 | 日韩福利在线 | 国产精品天天干 | 欧美a级成人淫片免费看 | 伊人无码高清 | 暖暖视频日韩欧美在线观看 | 日韩欧美一级精品久久 | 一区二区三区四区在线 | 日本在线观看 | 欧美精品免费在线观看 | 99久久久国产精品 | 九色91视频 | 亚洲国产青草 | 日本亚洲最大的色成网站www | 韩日精品视频 | 欧洲精品在线视频 | 国产精品久久综合 | 免费成人精品 | 天天干天天添 | 日韩在线观看中文字幕 | 亚洲激情视频在线观看 | 一级黄色国产 | 国产91福利视频 | 成人男女激情免费视频 | 人人艹人人爽 | 欧美日韩成人在线观看 | 日本a在线| 国产人免费人成免费视频 | 亚洲伊人久久网 | 露娜同人18av黄漫网站 | 国产精品久久久久久久久久久久久 | 91在线免费视频 | 久久99久久99精品免观看粉嫩 | 日韩中文字幕在线观看 | 91电影在线| 亚洲精品国产一区 | 日韩精品一区二区三区中文字幕 | 国产精品久久九九 | 欧美日韩在线成人 | 福利片在线观看 | 欧美一级片免费在线观看 | www.亚洲区 | 91亚洲国产成人久久精品网站 | 久久成人一区二区 | 99久久99| 国产91对白叫床清晰播放 | 精品美女在线 | 国产一级一级国产 | 日韩欧美在线看 | 成人免费观看视频 | 一级黄色大片免费观看 | 日韩av免费在线观看 | 综合自拍偷拍 | 九九av| 久久久久久网站 | 图片区 国产 欧美 另类 在线 | 欧美成人精品一区二区男人看 | 久草视频在线播放 | 日韩欧美精品一区 | av一区二区在线观看 | 日日摸天天做天天添天天欢 | 欧美人人 | 黄色免费成人 | 中文字幕在线视频观看 | h免费观看 | 国产精品亚洲一区 | 久草新视频在线观看 | 一二三区不卡视频 | www.操.com| 成人a级网站 | 狠狠综合久久 | 亚洲一区二区三区在线免费观看 | 国产精品久久久久久久久久东京 | 日本在线播放 | 人妖天堂狠狠ts人妖天堂狠狠 | 美女一级 | 国产免费自拍 | jizz欧美最大| 成人免费视频一区二区 | 日韩成人影院在线观看 | 国产精品视频入口 | 99re在线视频 | 日本在线视频不卡 | 17c一起操| 国产精品免费一区 | 日本理伦片午夜理伦片 | 亚洲精品一区二区三区在线播放 | 精品免费国产一区二区三区四区 | 91麻豆精品国产91久久久久久久久 | 亚洲精品视频在线免费 | 成人黄色短视频在线观看 | se在线播放 | 色欧美综合| 四虎欧美 | 日韩在线观看视频一区二区 | 欧美亚洲综合久久 | 毛片网站在线观看 | 国产精品成人国产乱一区 | 黄色片免费看. | 日韩一级二级三级 | 97在线观看 | av国产精品 | 成年人黄色一级毛片 | 日韩欧美国产一区二区 | 精品一区视频 | 国产成人精品一区二区 | 色www精品视频在线观看 | 国产一级纯肉体一级毛片 | 亚洲人成人一区二区在线观看 | 日韩伦理一区二区 | 91九色视频在线 | 欧美精品欧美精品系列 | 一区二区三区视频 | 天天想天天干 | 成人激情视频在线观看 | 在线免费色视频 | 视频在线一区 | 国产在线视频网 | 国产精品99精品久久免费 | 成人免费在线网址 | 奇米亚洲午夜久久精品 | 中文字幕一区二区三区四区 | 久久成人毛片 | 欧美精品成人 | 亚洲欧美中文日韩在线v日本 | 中文字幕av一区 | 天天干狠狠 | av网站免费在线观看 | 国产亚洲欧美在线 | 日本天天操 | 国产区视频 | 看片wwwwwwwwwww| 男女免费在线观看 | 精品www| 日本免费三片免费观看 | 久久精品视频亚洲 | 九色av | 欧日韩不卡在线视频 | 91在线免费观看 | 天天操天天干视频 | 美女久久 | 亚洲在线播放 | 91精品久久久久久久 | 天天干天天搞天天射 | 中文在线一区 | 成人av影片在线观看 | 日韩在线不卡 | 亚洲第一成年免费网站 | 奇米一区二区 | 久久久久亚洲美女啪啪 | 91在线精品秘密一区二区 | 日韩综合一区 | 激情91| 成年人网站在线免费观看 | 人人爽在线 | 欧美在线观看免费观看视频 | 精品在线一区 | 在线观看日韩av | 久草网站 | 国产精品www | 欧美九九九 | 欧美精品成人一区二区三区四区 | 91av视频在线 | 欧美精品网站 | 在线观看中文字幕 | 日韩在线免费观看网站 | 99爱免费观看国语 | 久久久久久久久久久亚洲 | 麻豆国产一区二区三区四区 | 亚洲福利av | 黄色毛片免费看 | 热久久影院 | 美女一区二区三区四区 | 中文字幕免费中文 | av在线免费观看网址 | 在线一区二区免费 | 欧美一区二区三区精品 | 91免费版在线看 | 免费黄色电影在线观看 | 精品国产18久久久久久二百 | 欧美成人精品一区二区 | 久久久一区二区 | 国产精品成人一区二区三区夜夜夜 | 色十八 | 亚洲国产成人久久综合一区,久久久国产99 | 久久久精品网站 | 亚洲免费婷婷 | 亚洲欧美日韩精品久久奇米色影视 | 中文字幕在线免费 | www.久草| av一级在线观看 | 国产精品久久久久久久久久免费看 | 欧美在线播放 | 亚洲视频在线观看网站 | 亚洲日本国产 | 午夜高清视频 | 蜜桃色网| 亚洲一区| 亚洲xxxx3d| 91看片网 | 亚洲精品四区 | 国产精品二区三区 | 午夜小视频免费 | 91久草视频 | 精品久久久久久久久久久 | 成人免费视频播放 | 免费久久网站 | www夜夜操com| 日韩欧美在线中文字幕 | 亚洲国产高清视频 | 91久久精品日日躁夜夜躁国产 | 资源av| 龙珠z国语291集普通话 | 中文字幕久久精品 | 97精品国产97久久久久久粉红 | 成人av片在线观看 | 狠狠操操操 | 在线观看成人 | 在线国产一区 | 色综合天天综合网国产成人网 | 久久久久久亚洲精品 | 中文久久 | 亚洲国产精品久久久男人的天堂 | 欧美色欧美亚洲另类七区 | 色猫猫国产区一区二在线视频 | 久久精品久久久 | 美女高潮久久久 | 欧美一级片在线 | 国产精品色综合 | 成人免费小视频 | 美女黄网 | 日韩精品第一页 | 91精品国产成人 | 天堂中文视频在线观看 | 国产欧美综合一区二区三区 | 亚洲三区电影 | 男女羞羞视频免费观看 | 国产精品视频一二三区 | 国产精品久久久久不卡 | 亚洲三级视频 | 天天射日日操 | 亚洲免费观看 | 中文字幕视频在线观看 | 一区综合 | 免费av电影在线观看 | 国产精品精品视频一区二区三区 | 日韩不卡一区二区 | 亚洲午夜精品片久久www慈禧 | 日韩三级视频 | 国产成人一区二区 | jizz中国zz女人18高潮 | 久久国产精品久久久久久 | 国产在线一区二区 | 亚洲视频一区在线 | 一区二区三区免费在线观看 | 99亚洲精品 | 久久久人成影片一区二区三区 | 免费成人在线观看 | 久热在线视频 | 91免费看网站 | 岛国av一区 | 中字一区 | 在线成人亚洲 | 欧美一区二区三区精品 | 国产精品成人在线 | 国产精品久久久久久久久久大牛 | 国产精品99久久久久久动医院 | 99久久精品免费 | 第一色在线 | 国产高清一区二区 | 午夜天堂精品久久久久 | 超碰日韩在线 | 成人午夜 | 午夜小视频免费 | 国产精品久久久久久一区二区三区 | 欧美成人综合 | 91佛爷在线观看 | 91精品国产91久久久久久蜜臀 | 精品免费国产 | 99视频免费| 日韩高清在线 | www.久久精品 | 日韩精品在线观看一区 | 2020国产在线 | www.久久| 狠狠操操| 色九九九| 在线看av网址 | 国产免费av网站 | 亚洲成av人片在线观看无码 | 在线观看成人小视频 | 精品成人一区 | 成人超碰 | 大桥未久亚洲精品久久久强制中出 | 日韩精品观看 | 亚洲伊人精品酒店 | 久久久国产精品 | 欧美日韩一区二区视频在线观看 | 日韩在线播放一区二区 | 久色视频在线观看 | 亚洲精品毛片一区二区 | 97综合色 | 视频一区二区中文字幕 | 高清国产一区 | 毛片网站在线观看 | 国产高清精品在线 | 久久一区| 超碰人人插 | 久久久久久黄 | 国产福利网站 | 国产精品美女在线观看 | 情五月 | 9久久婷婷国产综合精品性色 | 国产精品99一区二区三区 | 日韩精品一区在线 | 91久久久久久久久 | 日本中文字幕在线观看 | 欧美国产精品一区二区 | 亚洲网在线 | 久久国产一区 | 日韩午夜在线 | 亚洲精品国产a久久久久久 国产毛片毛片 | 99精品视频在线免费观看 | 欧美free性丝袜xxxxhd | 亚洲一区二区三区视频 | 亚洲一区二区三区国产 | 在线免费av观看 | 五月婷婷导航 | 成人国产精品久久久 | 午夜视频免费 | 91精彩视频在线观看 | 久久久www成人免费精品 | 亚洲精品一区二区在线观看 | 中文字幕乱码一区二区三区 | 国产高清在线精品一区二区三区 | 日韩中文一区二区三区 | 日韩欧美一区二区三区四区 | 免费在线黄 | 色999国产 | 欧洲一区二区在线观看 | 亚洲乱码国产乱码精品精98午夜 | 新91在线视频 | 欧美福利| 日韩欧美国产一区二区 | 国产视频导航 | 国产精品美女 | 成人欧美一区二区三区黑人孕妇 | 国产一区二区三区四区 | 亚洲国产成人av好男人在线观看 | 99国内精品久久久久久久 | 国产综合精品一区二区三区 | 亚洲福利 | 久久久亚洲综合 | 日韩精品成人 | 一区二区不卡 | 精品欧美一区二区三区久久久 |