精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

寫給Go開發者的gRPC教程-服務發現與負載均衡

開發 前端
用通俗易懂的方式來解釋下什么是服務發現。通常情況下客戶端需要知道服務端的IP+端口號才能建立連接,但服務端的IP和端口號并不是那么容易記憶。還有更重要的,在云部署的環境中,服務端的IP和端口可能隨時會發生變化。

對于一個客戶端創建請求的過程

conn, err := grpc.Dial("example:8009", grpc.WithInsecure())
if err != nil {
  panic(err)
}
  1. gRPC客戶端通過服務發現解析請求,將名稱解析為一個或多個IP地址,以及服務配置
  2. 客戶端使用上一步的服務配置、ip列表、實例化負載均衡策略
  3. 負載均衡策略為每個服務器地址創建一個子通道(channel),并監測每一個子通道狀態
  4. 當有rpc請求時,負載均衡策略決定那個子通道即gRPC服務器將接收請求,當可用服務器為空時客戶端的請求將被阻塞

gRPC官方提供了基本的服務發現和負載均衡邏輯,并提供了接口供擴展用于開發自定義的服務發現與負載均衡

服務發現

用通俗易懂的方式來解釋下什么是服務發現。通常情況下客戶端需要知道服務端的IP+端口號才能建立連接,但服務端的IP和端口號并不是那么容易記憶。還有更重要的,在云部署的環境中,服務端的IP和端口可能隨時會發生變化。

所以我們可以給某一個服務起一個名字,客戶端通過名字創建與服務端的連接,客戶端底層使用服務發現系統,解析這個名字來獲取真正的IP和端口,并在服務端的IP和端口發生變化時,重新建立連接。這樣的系統通常也會被叫做name-system(名字服務)

gRPC 中的默認name-system是 DNS,同時在客戶端以插件形式提供了自定義name-system的機制。

名字格式

gRPC采用的名字格式遵循的RFC 3986中定義的URI語法

scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]

例如

URI示例URI示例

gRPC關注其中兩部分

  • URI scheme:第一個:前面的標識。對于gRPC客戶端來說,它指示要使用的服務發現解析器,如果未指定前綴或方案未知,則默認使用DNS方案
  • URI path:指示要解析的名字

大部分gRPC實現默認支持以下的URI schemes

  • dns:[//authority/]host[:port] -- DNS (default)
  • unix:path, unix://absolute_path -- Unix domain sockets (Unix systems only)
  • unix-abstract:abstract_path -- Unix domain socket in abstract namespace (Unix systems only)

服務的服務注冊

如果gRPC服務端的地址是靜態的,可以在客戶端服務發現時直接解析為靜態的地址

如果gRPC服務端的地址是動態的,可以有兩種選擇

  • 自注冊:當gRPC的服務啟動后,向一個集中的注冊中心進行注冊
  • 平臺的服務發現:使用k8s平臺時,平臺會感知gPRC實例的變化

關于服務注冊這里不在做更多介紹了

客戶端的服務發現

自定義服務發現需要在客戶端啟動前,注冊一個服務解析器(Resolve)

Golang中使用google.golang.org/grpc/resolver.Register(resolver.Builder)注冊,這個函數不是直接接收一個解析器,而是使用工廠模式接收一個解析器的構造器

type Builder interface {
 // Build creates a new resolver for the given target.
 //
 // gRPC dial calls Build synchronously, and fails if the returned error is
 // not nil.
 Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error)
 // Scheme returns the scheme supported by this resolver.
 // Scheme is defined at https://github.com/grpc/grpc/blob/master/doc/naming.md.
 Scheme() string
}

? Scheme()需要返回的就是名字格式中提到的URI scheme

? Build(...)需要返回一個服務發現解析器google.golang.org/grpc/resolver.Resolver

??cc ClientConn代表客戶端與服務端的連接,其擁有的cc.UpdateState(State) error可以讓我們更新鏈接的狀態

type Resolver interface {
 // ResolveNow will be called by gRPC to try to resolve the target name
 // again. It's just a hint, resolver can ignore this if it's not necessary.
 //
 // It could be called multiple times concurrently.
  // ResolveNow 嘗試再一次對域名進行解析,在個人實踐中,服務端進程掛掉會觸發該調用
 ResolveNow(ResolveNowOptions)
  // Close closes the resolver.
  // 資源釋放。
 Close()
}

解析器需要有能力從注冊中心獲取解析結果,并更新客戶端中連接(cc ClientConn)的信息。還可以持續watch一個名字的解析結果,實時的更新客戶端中連接的信息

  • 解析出來的地址列表(包含ip和port)
  • 針對連接的服務配置,如負載均衡等,來想覆蓋全局的負責均衡配置
  • 每一個地址可以包含一系列的屬性(kv),他們可以用來支持后續的負載均衡策略

示例代碼

gRPC resolver 原理

?? 在 init() 階段時

  • 創建并注冊Builder 實例,將其注冊到 grpc 內部的 resolveBuilder 表中(其實是一個全局 map,key 為協議名;value 為構造的 resolveBuilder)

?? 客戶端啟動時通過自定義Dail()方法構造grpc.ClientConn單例

  • grpc.DialContext() 方法內部解析 URI,分析協議類型,并從 resolveBuilder 表中查找協議對應的 resolverBuilder
  • 將地址作為 Target 、conn單例作為resolver.ClientConn參數調用 resolver.Build 方法實例化出 Resolver
  • 用戶 Resolver實現中調用 cc.UpdateState 傳入 State.Addresses 地址,gRPC使用這個地址建立連接,傳入State.ServiceConfig,gRPC使用這份服務配置覆蓋默認配置

name-reslover原理name-reslover原理

代碼

# builder.go
package resolver

import "google.golang.org/grpc/resolver"

var _ resolver.Builder = Builder{}

type Builder struct {
 addrsStore map[string][]string
}

func NewResolverBuilder(addrsStore map[string][]string) *Builder {
 return &Builder{addrsStore: addrsStore}
}

func (b Builder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
 r := &Resolver{
  target:     target,
  cc:         cc,
  addrsStore: b.addrsStore,
 }
 r.Start()
 return r, nil
}

func (b Builder) Scheme() string {
 return "example"
}
# resolver.go
package resolver

import (
 "google.golang.org/grpc/resolver"
)

var _ resolver.Resolver = &Resolver{}

// impl google.golang.org/grpc/resolver.Resolver
type Resolver struct {
 target resolver.Target
 cc     resolver.ClientConn

 addrsStore map[string][]string
}

func (r *Resolver) Start() {
 // 在靜態路由表中查詢此 Endpoint 對應 addrs
 var addrs []resolver.Address
 for _, addr := range r.addrsStore[r.target.URL.Opaque] {
  addrs = append(addrs, resolver.Address{Addr: addr})
 }

 r.cc.UpdateState(resolver.State{
  Addresses: addrs,
    // 設置負載均衡策略為round_robin
  ServiceConfig: r.cc.ParseServiceConfig(
    `{"loadBalancingPolicy":"round_robin"}`),
 })
}

func (r *Resolver) ResolveNow(resolver.ResolveNowOptions) {

}

func (r *Resolver) Close() {

}
# main.go
package main

import (
 "context"
 "log"

 rs "github.com/liangwt/note/grpc/name_resolver_lb_example/client/resolver"
 pb "github.com/liangwt/note/grpc/name_resolver_lb_example/ecommerce"
 "google.golang.org/grpc"
 "google.golang.org/grpc/resolver"
)

func main() {
 resolver.Register(rs.NewResolverBuilder(map[string][]string{
  "cluster@callee": {
   "127.0.0.1:8009",
  },
 }))

 conn, err := grpc.Dial("example:cluster@callee", grpc.WithInsecure())
 if err != nil {
  panic(err)
 }
  
 // ...
}

負載均衡

同樣來通俗易懂的解釋下什么負載均衡。為了提高系統的負載能力和穩定性,我們的服務端往往具有多臺服務器,負載均衡的目的就是希望請求能分散到不同的服務器,從服務器列表中選擇一臺服務器的算法就是負載均衡的策略,常見的輪循、加權輪詢等

負載均衡器要在多臺服務器之間選擇,所以通常情況下負載均衡器是具備服務發現的能力的

根據負載均衡實現所在的位置不同,通常可分為以下三種解決方案:

1、集中式負載均衡(Proxy Model)

在客戶端和服務端之間有一個獨立的LB,通常是專門的硬件設備如 F5,或者基于軟件如 LVS,HAproxy,Nginx等實現。LB使用負載均衡策略將請求轉發到目標服務

因為所有服務調用流量都經過LB,當服務數量和調用量大的時候,LB容易成為瓶頸;一旦LB發生故障影響整個系統;客戶端、服務端之間增加了一級,有一定性能開銷

圖片集中式負載均衡

2、客戶端負載均衡(Balancing-aware Client)

客戶端負載將LB的功能集成到客戶端進程里,然后使用負載均衡策略選擇一個目標服務地址,向目標服務發起請求。LB能力被分散到每一個服務消費者的進程內部,同時服務消費方和服務提供方之間是直接調用,沒有額外開銷,性能比較好。

但如果有多種不同的語言棧,就要配合開發多種不同的客戶端,有一定的研發和維護成本;后續如果要對客戶庫進行升級,勢必要求服務調用方修改代碼并重新發布,升級較復雜。

圖片客戶端負載均衡

3、獨立負載均衡進程(External Load Balancing Service)

將LB從進程內移出來,變成主機上的一個獨立進程。主機上的一個或者多個服務要訪問目標服務時,他們都通過同一主機上的獨立LB進程做負載均衡

此方案有兩種模式

第一種是直接由LB進行轉發請求,被稱為sidecar方案

第二種是從LB獲取到IP后依舊由客戶端發起請求,gRPC曾經支持過此方案叫lookaside方案,目前已廢棄

該方案也是一種分布式方案沒有單點問題,一個LB進程掛了只影響該主機上的客戶端;客戶端和LB之間是本地調用調用性能好;同時該方案還簡化了客戶端,不需要為不同語言開發客戶庫,LB的升級不需要服務調用方改代碼。該方案主要問題:部署較復雜,環節多,出錯調試排查問題不方便

獨立負載均衡進程獨立負載均衡進程


gRPC的負載均衡

上文介紹的三種負載均衡方式,集中式負載均衡和gRPC無關,屬于外部的基礎設施,因此我們不再介紹

gRPC中的負載平衡是以每次調用為基礎,而不是以每個連接為基礎。換句話說,即使所有的請求都來自一個客戶端,它仍能在所有的服務器上實現負載平衡

gRPC目前內置四種策略

?? pick_first:默認策略,選擇第一個

?? round_robin:輪詢

使用默認的負載均衡器很簡單,只需要在建立連接的時候指定負載均衡策略即可。

?? 注意

舊版本gRPC使用 grpc.WithBalancerName("round_robin"),已經被廢棄,使用grpc.WithDefaultServiceConfig。

grpc.WithDefaultServiceConfig可以被上文服務發現中提到的cc.UpdateState(State) error覆蓋配置

conn, err := grpc.Dial("example:cluster@callee",
  grpc.WithInsecure(),
  grpc.WithDefaultServiceConfig(
   `{"loadBalancingPolicy":"round_robin"}`,
  ),
 )

?? grpclb:已廢棄

它屬于上文介紹的負載均衡中獨立負載均衡進程第二種。不必直接在客戶端中添加新的LB策略,而只實現諸如round-robin之類的簡單算法,任何更復雜的算法都將由lookaside負載平衡器提供

gRPC的grpclb方案gRPC的grpclb方案

?? xDS

如果接觸過servicemesh那么對xDS并不會陌生,xDS 本身是Envoy中的概念,現在已經發展為用于配置各種數據平面軟件的標準,最新版本的gRPC已經支持xDS。不同于單純的負載均衡策略,xDS在gRPC包含了服務發現和負載均衡的概念

這里簡單的理解下xDS,本質上xDS就是一個標準的協議

它規定了xDS客戶端和xDS服務端的交互流程,即API調用的順序

我們在xDS 服務端實現服務發現,配置負載均衡策略等等,支持xDS的客戶端連接到xDS 服務端并通過xDS api來獲取各種需要的數據和配置

xDS主要應用于servicemesh中,在mesh中由sidecar連接到xDS server進行數據交互,同時由sidecar來控制流量的分發。也就是上文提到的獨立負載均衡進程的第一種模式

servicemesh的負載均衡servicemesh的負載均衡

gRPC使用xDS是一種無proxy的客戶端負載均衡方案。對比Mesh方案,性能更好。我們把servicemesh的負載均衡和grpc的xds負載均衡放在一起感受下區別

gRPC的xDS的方案

?? 這意味著,grpclb廢棄后,gRPC內置的pick_first、round_robin、xDS三種模式都屬于客戶端的負載均衡模式。pick_first、round_robin是單純的負載均衡策略;xDS包含了服務發現等一系列能力,并且還在不斷拓展中,而我們控制gRPC的行為也被轉移到了xDS server上了。

xDS模式的使用

xDS內容較多,又比較新,單獨開個章節介紹下xDS的使用

gRPC xDS架構中出現了三個服務

  • xDS server:它是我們的控制面
  • gRPC client:它既是gRPC服務的客戶端,同時也是xDS的客戶端
  • gRPC server:它是gRPC服務的服務端,它需要具備被xDS server發現的能力

我們可以使用 Envoy go-control-plane庫來實現xDS server,這部分的開發類似于servicemesh,就不介紹太多了,如果位于k8s平臺內可以參考下istio中控制面的實現

gRPC server需要自注冊或者托管到k8s平臺,如果托管到k8s則可以繼續參考istio中控制面的實現

因為xDS也包含了服務發現的部分,因此對于client來說第一步需要先開發自定義的服務發現和負載均衡配置。幸運的是gRPC官方已經為我們開發了對應實現,只需要引入包即可,在init階段會注冊xDS的解析器和負載均衡器

_ "google.golang.org/grpc/xds" // To install the xds resolvers and balancers.

隨后只需要把gRPC client連接到xDs server即可,這部分與非xDS并無不同。只是目標服務的地址的URI scheme為xds

conn, err := grpc.Dial("xds:///localhost:50051", grpc.WithTransportCredentials(creds))
if err != nil {
  panic(err)
}

ctx, cancelFn := context.WithCancel(context.Background())
defer cancelFn()

c := pb.NewOrderManagementClient(conn)
res, err := c.AddOrder(ctx, &order)

完整代碼可以參考:https://github.com/grpc/grpc-go/tree/master/examples/features/xds

自定義負載均衡器

自定義負載均衡器需要使用google.golang.org/grpc/balancer.Register提前注冊,此函數和服務發現一樣接受工廠函數

// Builder creates a balancer.
type Builder interface {
 // Build creates a new balancer with the ClientConn.
 Build(cc ClientConn, opts BuildOptions) Balancer
 // Name returns the name of balancers built by this builder.
 // It will be used to pick balancers (for example in service config).
 Name() string
}

? Name()是負載均衡策略的名字

? Build(...)需要返回負載均衡器

?? cc ClientConn代表客戶端與服務端的連接,其擁有一系列函數可以讓我們更新鏈接的狀態

type Balancer interface {
 // UpdateClientConnState is called by gRPC when the state of the ClientConn
 // changes.  If the error returned is ErrBadResolverState, the ClientConn
 // will begin calling ResolveNow on the active name resolver with
 // exponential backoff until a subsequent call to UpdateClientConnState
 // returns a nil error.  Any other errors are currently ignored.
 UpdateClientConnState(ClientConnState) error
 // ResolverError is called by gRPC when the name resolver reports an error.
 ResolverError(error)
 // UpdateSubConnState is called by gRPC when the state of a SubConn
 // changes.
 UpdateSubConnState(SubConn, SubConnState)
 // Close closes the balancer. The balancer is not required to call
 // ClientConn.RemoveSubConn for its existing SubConns.
 Close()
}

負載均衡器需要實現一系列的函數用于gRPC在不同場景下調用

類RR算法負載均衡器

如果要實現一個類round_robin的負載均衡策略,gRPC官方實現提供了一個baseBuilder,它已經實現了大部Balancer接口,可以大幅簡化了我們創建RR策略的邏輯。使用google.golang.org/grpc/balancer/base.NewBalancerBuilder創建負載均衡的工廠

func NewBalancerBuilder(name string, pb PickerBuilder, config Config) balancer.Builder
  • name string負載均衡器的名字
  • pb PickerBuilder是我們要實現的負載均衡策略邏輯的地方
  • config Config可以配置是否要進行健康檢查
// PickerBuilder creates balancer.Picker.
type PickerBuilder interface {
 // Build returns a picker that will be used by gRPC to pick a SubConn.
 Build(info PickerBuildInfo) balancer.Picker
}
type Picker interface {
  // 子連接選擇
 Pick(info PickInfo) (PickResult, error)
}

于是借助base.NewBalancerBuilder我們僅需要實現Picker一個函數即可實現類RR的負載均衡策略了

代碼

利用Picker接口來實現一個隨機選擇策略

# builder.go
package balancer

import (
 "google.golang.org/grpc/balancer"
 "google.golang.org/grpc/balancer/base"
)

var _ base.PickerBuilder = &Builder{}

type Builder struct {
}

func NewBalancerBuilder() balancer.Builder {
 return base.NewBalancerBuilder("random_picker", &Builder{}, base.Config{HealthCheck: true})
}

func (b *Builder) Build(info base.PickerBuildInfo) balancer.Picker {
 if len(info.ReadySCs) == 0 {
  return base.NewErrPicker(balancer.ErrNoSubConnAvailable)
 }

 var scs []balancer.SubConn
 for subConn := range info.ReadySCs {
  scs = append(scs, subConn)
 }

 return &Picker{
  subConns: scs,
 }
}
// picker.go
package balancer

import (
 "math/rand"

 "google.golang.org/grpc/balancer"
)

var _ balancer.Picker = &Picker{}

type Picker struct {
 subConns []balancer.SubConn
}

func (p *Picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
 index := rand.Intn(len(p.subConns))
 sc := p.subConns[index]
 return balancer.PickResult{SubConn: sc}, nil
}
#client.go
package main

import (
 "context"
 "log"

 bl "github.com/liangwt/note/grpc/name_resolver_lb_example/client/balancer"
 rs "github.com/liangwt/note/grpc/name_resolver_lb_example/client/resolver"
 pb "github.com/liangwt/note/grpc/name_resolver_lb_example/ecommerce"
 "google.golang.org/grpc"
 "google.golang.org/grpc/balancer"
 "google.golang.org/grpc/resolver"
)

func main() {
 resolver.Register(rs.NewResolverBuilder(map[string][]string{
  "cluster@callee": {
   "127.0.0.1:8009",
   "127.0.0.1:8010",
  },
 }))

 balancer.Register(bl.NewBalancerBuilder())

 conn, err := grpc.Dial("example:cluster@callee",
  grpc.WithInsecure(),
  grpc.WithDefaultServiceConfig(
   `{"loadBalancingPolicy":"random_picker"}`,
  ),
 )
 if err != nil {
  panic(err)
 }
 
  ....
}

參考資料

[1]URI語法: https://zh.wikipedia.org/wiki/%E7%BB%9F%E4%B8%80%E8%B5%84%E6%BA%90%E6%A0%87%E5%BF%97%E7%AC%A6

[2]go-control-plane: https://github.com/envoyproxy/go-control-plane

[3]gRPC Name Resolution: https://github.com/grpc/grpc/blob/master/doc/naming.md

[4]Load Balancing in gRPC: https://github.com/grpc/grpc/blob/master/doc/load-balancing.md

[5]https://github.com/grpc/grpc-go: https://github.com/grpc/grpc-go

[6]gRPC Go 服務發現與負載均衡: https://blog.cong.moe/post/2021-03-06-grpc-go-discovery-lb/

[7][轉]gRPC服務發現&負載均衡: https://colobu.com/2017/03/25/grpc-naming-and-load-balance/

[8]淺淡 xDS 協議在 gRPC 中的應用: http://limeng.org/2020/03/08/xds-in-grpc.html

責任編輯:武曉燕 來源: 涼涼的知識庫
相關推薦

2020-04-15 22:18:55

架構負載均衡分布式

2011-02-22 14:07:52

2013-11-26 09:43:36

開發日志博客

2019-09-19 09:03:13

Docker負載均衡服務

2022-01-12 18:20:36

GoJava開發

2025-07-31 06:00:00

Go后端開發

2013-03-28 10:22:33

數據庫關系型數據庫數據庫設計

2019-09-19 14:57:27

Docker語言技術

2012-06-13 01:23:30

開發者程序員

2021-12-16 20:12:37

后端開發Sentry

2012-11-03 21:03:37

2019-11-29 08:05:26

連接池負載均衡互聯網架構

2023-10-27 12:36:37

gRPCKubernetes

2023-10-17 08:08:37

Dubbo服務注冊中心

2019-02-21 09:18:27

服務路由負載均衡微服務

2022-04-22 14:15:59

Go開發者受訪者

2019-06-09 09:13:14

Istio負載均衡架構

2011-04-18 15:38:15

喬布斯佩奇開發者

2011-11-16 13:47:05

點贊
收藏

51CTO技術棧公眾號

狠狠久久亚洲欧美| 天天揉久久久久亚洲精品| 富二代精品短视频| 五月天男人天堂| 亚洲大尺度网站| 老司机精品导航| 欧美xxxx18性欧美| 免费毛片视频网站| 日韩高清二区| 色诱视频网站一区| 青少年xxxxx性开放hg| 色婷婷中文字幕| 韩国成人精品a∨在线观看| 久久久久久午夜| 亚洲色图27p| 亚洲精品一级二级三级| 日韩一区二区精品葵司在线| 可以在线看的黄色网址| 色女人在线视频| 国产精品国产三级国产普通话蜜臀 | 精品无码一区二区三区电影桃花 | 你懂的av在线| 国产一区久久精品| 久久蜜桃av一区精品变态类天堂| 亚洲直播在线一区| 中国黄色一级视频| 亚洲综合另类| 欧美激情在线观看| 欧美精品久久久久久久久46p| 免费看日本一区二区| 欧美本精品男人aⅴ天堂| 中文字幕 日韩 欧美| 伊人久久高清| 色成人在线视频| jizzjizzxxxx| a级片免费在线观看| 亚洲免费观看高清完整版在线观看 | 人人妻人人藻人人爽欧美一区| 久久久精品区| 91 com成人网| 91亚洲免费视频| av在线一区不卡| 91福利国产精品| 欧美女人性生活视频| 2021天堂中文幕一二区在线观| 亚洲激情一二三区| 97久久国产亚洲精品超碰热| 菠萝蜜视频国产在线播放| 国产精品久久久久久久岛一牛影视| 日本不卡久久| 黄色片免费在线| 久久精品网站免费观看| 欧洲久久久久久| 国产综合在线观看| 国产色产综合产在线视频| 秋霞久久久久久一区二区| 美国一级片在线免费观看视频 | а天堂中文在线资源| 日韩电影免费网址| 自拍偷拍亚洲欧美| 国产精品视频看看| 99久久99视频只有精品| 久久精品99久久香蕉国产色戒| 殴美一级黄色片| 91精品秘密在线观看| 欧美成人午夜激情视频| 麻豆亚洲av成人无码久久精品| 午夜精品久久久久99热蜜桃导演| 久久国产精品偷| 久久综合亚洲色hezyo国产| 精品91在线| 人九九综合九九宗合| 中文字幕丰满人伦在线| 国内精品视频一区二区三区八戒| 亚洲字幕一区二区| 日本国产在线观看| 久久久久久电影| 伊人久久大香线蕉成人综合网| 国产在线看片| 午夜私人影院久久久久| 欧美伦理片在线看| 亚洲久草在线| 亚洲精品一区二区三区在线观看 | 日韩在线黄色| 日韩中文第一页| 国产在线拍揄自揄拍| 久久黄色网页| 亚洲va国产va天堂va久久| 黄色片一区二区三区| 国产日产欧产精品推荐色| 日本三级福利片| 国产欧洲在线| 欧美日韩大陆在线| 国产婷婷在线观看| 不卡一区综合视频| 久久久久久久久久久人体| 波多野结衣激情视频| 国产乱国产乱300精品| 免费成人看片网址| 最新av在线播放| 色欧美日韩亚洲| 青青草精品在线| 禁断一区二区三区在线| 久久69精品久久久久久国产越南| 日韩精品一区二区亚洲av观看| 国产一区不卡视频| 日韩国产高清一区| freexxx性亚洲精品| 欧美酷刑日本凌虐凌虐| 人妻熟女aⅴ一区二区三区汇编| 国产精品91一区二区三区| 欧美在线不卡区| www日本高清视频| 中文字幕在线不卡一区二区三区| 大j8黑人w巨大888a片| 日韩精品三级| 日韩午夜在线视频| 无码人妻丰满熟妇精品| 成人永久看片免费视频天堂| 中文精品一区二区三区| 亚洲www免费| 精品中文视频在线| 国产精品30p| 国产盗摄视频一区二区三区| 五月天久久狠狠| 原纱央莉成人av片| 亚洲福利视频网| 青娱乐免费在线视频| 久久www免费人成看片高清| 茄子视频成人在线观看| 伊人久久精品一区二区三区| 精品国产髙清在线看国产毛片| 黄色av片三级三级三级免费看| 天堂蜜桃一区二区三区| 久久资源av| 日韩伦理在线一区| 精品国产青草久久久久福利| 欧美丰满艳妇bbwbbw| 国模大尺度一区二区三区| 亚洲精品成人三区| 日本黄色一区| 日韩亚洲综合在线| 在线观看国产精品视频| 国产精品视频一二三| 草草草在线视频| 欧美综合在线视频观看| 国产精国产精品| 国产毛片在线看| 日本电影亚洲天堂一区| 伊人网在线视频观看| 亚洲女同同性videoxma| 欧美精品v日韩精品v国产精品| 亚洲精品动漫| 亚洲区中文字幕| 成人午夜精品视频| 国产精品黄色在线观看| 色网站在线视频| 欧美日本免费| 久久99精品国产一区二区三区| 日韩伦理在线一区| 国产一区二区三区丝袜| 亚洲天天综合网| 日韩理论在线观看| 台湾佬美性中文| 日韩视频一区| 三级三级久久三级久久18| 欧美日韩视频免费看| 久久精品国产免费观看| 亚洲国产www| 欧美体内谢she精2性欧美| 永久免费毛片在线观看| 国产一区视频网站| 国产自产在线视频| 精品视频亚洲| 亚洲影院在线看| 咪咪网在线视频| 亚洲一区第一页| 国产区精品在线| 香蕉加勒比综合久久| 欧洲av一区二区三区| 韩国理伦片一区二区三区在线播放| 日b视频免费观看| 久久99国产精品视频| 成人羞羞国产免费| 女厕盗摄一区二区三区| 中文字幕最新精品| 日日夜夜精品免费| 欧美亚洲动漫制服丝袜| 日韩一级片av| 久久精品视频在线免费观看| 日韩欧美理论片| 六月婷婷一区| 免费视频爱爱太爽了| 精品在线99| 国产91视觉| 久久人体av| 97精品久久久| 99热国产在线| 亚洲视频999| 亚洲男人天堂久久| 欧美精品免费视频| 亚洲日本视频在线观看| 一区二区在线观看av| 国产精品815.cc红桃| 国产传媒欧美日韩成人| 超碰在线97免费| 在线一区欧美| 日韩亚洲欧美一区二区| 成人一级毛片| 欧美日韩国产一二| 久久97精品| 99精品国产高清一区二区| 91av一区| 国产成人激情小视频| 黄视频网站在线观看| 欧美成人免费va影院高清| 成人在线免费看| 精品无人国产偷自产在线| 亚洲女同志亚洲女同女播放| 91精品一区二区三区久久久久久| 日韩在线视频不卡| 精品福利樱桃av导航| 国产亚洲精品久久777777| 亚洲乱码国产乱码精品精可以看| 99久久久无码国产精品衣服| 久久综合中文字幕| 波多野结衣影院| 成人精品视频一区二区三区尤物| 尤物网站在线看| 久久99精品网久久| 精品日韩久久久| 男女性色大片免费观看一区二区| 成人在线免费在线观看| 99国产精品久久久久久久| 国产欧美日韩网站| 伊人精品视频| 青青青青草视频| 亚洲国产一区二区三区高清 | 高h视频在线播放| 欧美美女18p| 神马午夜伦理不卡| 欧美黄色www| 美女精品导航| 午夜欧美大片免费观看| а√在线天堂官网| 91av在线精品| 欧美片第一页| 国产精品成人久久久久| 男女啪啪999亚洲精品| 成人国产在线视频| 国内精品视频| 春色成人在线视频| 久久久久高潮毛片免费全部播放| 国产欧美日韩一区| 小说区图片区色综合区| 日韩一本精品| 午夜精品视频一区二区三区在线看| 中文字幕久精品免| 欧美成人69av| 国产手机免费视频| 久久国产精品亚洲77777| 91在线视频观看免费| 久久99国产精品尤物| 国产精品99精品无码视亚| www.成人在线| 一级黄色录像毛片| 亚洲精品高清在线| 日韩伦人妻无码| 欧洲一区在线电影| 国产伦精品一区二区三区免.费| 日韩欧美一区二区在线视频| 搡老岳熟女国产熟妇| 亚洲精品wwww| 日本韩国在线视频爽| 欧美黑人一区二区三区| 欧美成人h版| 成人字幕网zmw| 你懂的在线观看一区二区| 日韩福利二区| 国产精品扒开腿做爽爽爽软件| www国产精品内射老熟女| 蜜桃久久久久久| 一级黄色片毛片| 国产日本欧美一区二区| 青娱乐国产精品| 欧洲色大大久久| 亚洲xxxx天美| 一个人看的www久久| 欧美黑人猛交的在线视频| 国产91精品久久久| 国产视频一区二区在线播放| 精品一区二区日本| 欧美疯狂party性派对| 91免费黄视频| 久久激情综合网| 瑟瑟视频在线观看| 亚洲午夜一区二区| 中文字幕欧美人妻精品一区蜜臀| 精品乱码亚洲一区二区不卡| 国内av一区二区三区| 久久久久久伊人| 热久久久久久| 欧美日韩大片一区二区三区 | 中文字幕成人网| 日韩手机在线观看| 欧美精品久久99久久在免费线| 色欲av永久无码精品无码蜜桃| 日韩有码在线电影| 少妇一区视频| 国模精品娜娜一二三区| 中文av一区| 超碰在线播放91| 久久亚洲欧美国产精品乐播| 免费无遮挡无码永久在线观看视频| 欧美色区777第一页| 美女毛片在线看| 4438全国成人免费| 国产精品极品国产中出| 欧美aaa在线观看| 麻豆成人91精品二区三区| 欧美 日韩 国产 成人 在线观看| 精品国产91久久久久久| 欧美视频一二区| 久久久久久欧美| 777久久精品| 国风产精品一区二区| 久久精品国产精品亚洲红杏| 妖精视频在线观看免费 | 免费看污黄网站| 久久免费美女视频| www.国产高清| 日韩精品视频免费| 日本蜜桃在线观看视频| 精品久久精品久久| 一本色道久久综合亚洲精品高清 | 99在线精品视频免费观看软件| 中文字幕亚洲综合久久筱田步美| gogo亚洲高清大胆美女人体| 热舞福利精品大尺度视频| 天堂成人免费av电影一区| 免费观看一级一片| 色综合久久九月婷婷色综合| 欧美女v视频| 国产精品成人一区二区| 成人在线亚洲| 在线观看日本一区二区| 国产精品久久久久一区| 亚洲午夜激情视频| 日韩三级影视基地| 我要色综合中文字幕| 无码日本精品xxxxxxxxx| 国产成人午夜电影网| 妺妺窝人体色www聚色窝仙踪| 精品久久久久久久久久久久包黑料 | 亚洲国产日韩欧美在线| 欧美性猛交乱大交| 亚洲韩国精品一区| 欧美性孕妇孕交| 国产精品91在线观看| 日韩免费特黄一二三区| 无人码人妻一区二区三区免费| 一区二区三区在线视频观看| 免费看黄色一级视频| 日本人成精品视频在线| 日韩综合精品| 91超薄肉色丝袜交足高跟凉鞋| 欧美日韩国产在线看| 免费福利在线观看| 91精品免费看| 亚洲高清激情| 国产7777777| 日韩午夜在线观看| 僵尸再翻生在线观看| 亚洲一区二区三区精品动漫| 国产一区亚洲一区| 成人免费a视频| 久久精品小视频| 色先锋久久影院av| www.国产视频.com| 婷婷综合另类小说色区| 在线观看av的网站| 国产乱码一区| 蜜臂av日日欢夜夜爽一区| 久久久久久久久久久久久久久久久 | 国产精品视频999| 海角社区69精品视频| www.99热| 亚洲成人免费在线视频| 成人久久网站| 欧美成人一区二区在线观看| 国产精品成人免费| 亚洲欧美丝袜中文综合| 国产日韩中文字幕| 国产精品日韩精品欧美精品| 五月婷婷综合激情网| 日韩国产在线播放| 美女精品久久| 视频二区在线播放| 午夜精品福利在线| a篇片在线观看网站|