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

Go進階 | 如何優雅接入多個遠程配置中心?

開發 前端
本地配置文件的接入能很快速的完成,那么對于遠程apollo配置中心的接入,是否也能很快速完成呢?如果有多個apollo實例都需要接入,是否能支持呢?以及apollo遠程配置變更后,是否能支持熱加載,實時更新呢?

前言

viper是適用于go應用程序的配置解決方案,這款配置管理神器,支持多種類型、開箱即用、極易上手。

本地配置文件的接入能很快速的完成,那么對于遠程apollo配置中心的接入,是否也能很快速完成呢?如果有多個apollo實例都需要接入,是否能支持呢?以及apollo遠程配置變更后,是否能支持熱加載,實時更新呢?

擁抱開源

帶著上面的這些問題,結合實際商業項目的實踐,已經有較成熟的解決方案。本著分享的原則,現已將xconfig包脫敏開源:github地址[1],歡迎體驗和star。

下面快速介紹下xconfig包的使用與能力,然后針對包的封裝實踐做個講解

獲取安裝

go get -u github.com/jinzaigo/xconfig

Features

  • 支持viper包諸多同名方法
  • 支持本地配置文件和遠程apollo配置熱加載,實時更新
  • 使用sync.RWMutex讀寫鎖,解決了viper并發讀寫不安全問題
  • 支持apollo配置中心多實例配置化快速接入

接入示例

本地配置文件

指定配置文件路徑完成初始化,即可通過xconfig.GetLocalIns().xxx()鏈式操作,讀取配置

package main

import (
"fmt"
"github.com/jinzaigo/xconfig"
)

func main() {
if xconfig.IsLocalLoaded() {
fmt.Println("local config is loaded")
return
}
//初始化
configIns := xconfig.New(xconfig.WithFile("example/config.yml"))
xconfig.InitLocalIns(configIns)

//讀取配置
fmt.Println(xconfig.GetLocalIns().GetString("appId"))
fmt.Println(xconfig.GetLocalIns().GetString("env"))
fmt.Println(xconfig.GetLocalIns().GetString("apollo.one.endpoint"))
}

xxx支持的操作方法:

  • IsSet(key string) bool
  • Get(key string) interface{}
  • AllSettings() map[string]interface{}
  • GetStringMap(key string) map[string]interface{}
  • GetStringMapString(key string) map[string]string
  • GetStringSlice(key string) []string
  • GetIntSlice(key string) []int
  • GetString(key string) string
  • GetInt(key string) int
  • GetInt32(key string) int32
  • GetInt64(key string) int64
  • GetUint(key string) uint
  • GetUint32(key string) uint32
  • GetUint64(key string) uint64
  • GetFloat(key string) float64
  • GetFloat64(key string) float64
  • GetFloat32(key string) float32
  • GetBool(key string) bool
  • SubAndUnmarshal(key string, i interface{}) error

遠程apollo配置中心

指定配置類型與apollo信息完成初始化,即可通過xconfig.GetRemoteIns(key).xxx()鏈式操作,讀取配置

單實例場景

//初始化
configIns := xconfig.New(xconfig.WithConfigType("properties"))
err := configIns.AddApolloRemoteConfig(endpoint, appId, namespace, backupFile)
if err != nil {
...handler
}
xconfig.AddRemoteIns("ApplicationConfig", configIns)

//讀取配置
fmt.Println(xconfig.GetRemoteIns("ApplicationConfig").AllSettings())

多實例場景

在本地配置文件config.yaml維護apollo配置信息,然后批量完成多個實例的初始化,即可通過xconfig.GetRemoteIns(key).xxx()鏈式操作,讀取配置

#apollo配置,支持多實例多namespace
apollo:
one:
endpoint: xxx
appId: xxx
namespaces:
one:
key: ApplicationConfig #用于讀取配置,保證全局唯一,避免相互覆蓋
name: application #注意:name不要帶類型(例如application.properties),這里name和type分開配置
type: properties
two:
key: cipherConfig
name: cipher
type: properties
backupFile: /tmp/xconfig/apollo_bak/test.agollo #每個appId使用不同的備份文件名,避免相互覆蓋
package main

import (
"fmt"
"github.com/jinzaigo/xconfig"
)

type ApolloConfig struct {
Endpoint string `json:"endpoint"`
AppId string `json:"appId"`
Namespaces map[string]ApolloNameSpace `json:"namespaces"`
BackupFile string `json:"backupFile"`
}

type ApolloNameSpace struct {
Key string `json:"key"`
Name string `json:"name"`
Type string `json:"type"`
}

func main() {
//本地配置初始化
xconfig.InitLocalIns(xconfig.New(xconfig.WithFile("example/config.yml")))
if !xconfig.GetLocalIns().IsSet("apollo") {
fmt.Println("without apollo key")
return
}

apolloConfigs := make(map[string]ApolloConfig, 0)
err := xconfig.GetLocalIns().SubAndUnmarshal("apollo", &apolloConfigs)
if err != nil {
fmt.Println(apolloConfigs)
fmt.Println("SubAndUnmarshal error:", err.Error())
return
}

//多實例初始化
for _, apolloConfig := range apolloConfigs {
for _, namespaceConf := range apolloConfig.Namespaces {
configIns := xconfig.New(xconfig.WithConfigType(namespaceConf.Type))
err = configIns.AddApolloRemoteConfig(apolloConfig.Endpoint, apolloConfig.AppId, namespaceConf.Name, apolloConfig.BackupFile)
if err != nil {
fmt.Println("AddApolloRemoteConfig error:" + err.Error())
}
xconfig.AddRemoteIns(namespaceConf.Key, configIns)
}
}

//讀取
fmt.Println(xconfig.GetRemoteIns("ApplicationConfig").AllSettings())
}

封裝實踐

學會使用xconfig包后,能快速的實現本地配置文件和遠程apollo配置中心多實例的接入。

再進一步了解這個包在封裝過程都中遇到過哪些問題,以及對應的解決方案,能更深入的理解與使用這個包,同時也有助于增加讀者自己在封裝新包時的實踐理論基礎。

1.viper遠程連接不支持apollo

查看viper的使用文檔,會發現viper是支持遠程K/V存儲連接的,所以一開始我嘗試著連接apollo

v := viper.New()
v.SetConfigType("properties")
err := v.AddRemoteProvider("apollo", "http://endpoint", "application")
if err != nil {
panic(fmt.Errorf("AddRemoteProvider error: %s", err))
}
fmt.Println("AddRemoteProvider success")
//執行結果:
//panic: AddRemoteProvider error: Unsupported Remote Provider Type "apollo"

執行后發現,并不支持apollo,隨即查看viper源碼,發現只支持以下3個provider

// SupportedRemoteProviders are universally supported remote providers.
var SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}

解決方案:

安裝shima-park/agollo包: go get -u github.com/shima-park/agollo

安裝成功后,只需要在上面代碼基礎上,最前面加上 remote.SetAppID("appId") 即可連接成功

import (
"fmt"
remote "github.com/shima-park/agollo/viper-remote"
"github.com/spf13/viper"
)

remote.SetAppID("appId")
v := viper.New()
v.SetConfigType("properties")
err := v.AddRemoteProvider("apollo", "http://endpoint", "application")
if err != nil {
panic(fmt.Errorf("AddRemoteProvider error: %s", err))
}
fmt.Println("AddRemoteProvider success")
//執行結果:
//AddRemoteProvider success

2.agollo是怎么讓viper支持apollo連接的呢

不難發現,在執行 remote.SetAppID("appId") 之前,remote.go 中init方法,會往viper.SupportedRemoteProviders中append一個"apollo",其實就是讓viper認識一下這個provider,隨后將viper.RemoteConfig 做重新賦值,并重新實現了viper中的Get Watch WatchChannel這3個方法,里邊就會做apollo連接的適配。

//github.com/shima-park/agollo/viper-remote/remote.go 278-284
func init() {
viper.SupportedRemoteProviders = append(
viper.SupportedRemoteProviders,
"apollo",
)
viper.RemoteConfig = &configProvider{}
}

//github.com/spf13/viper/viper.go 113-120
type remoteConfigFactory interface {
Get(rp RemoteProvider) (io.Reader, error)
Watch(rp RemoteProvider) (io.Reader, error)
WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool)
}

// RemoteConfig is optional, see the remote package
var RemoteConfig remoteConfigFactory

3.agollo只支持apollo單實例,怎么擴展為多實例呢

執行remote.SetAppID("appId")之后,這個appId是往全局變量appID里寫入的,并且在初始化時也是讀取的這個全局變量。帶來的問題就是不支持apollo多實例,那么解決呢

//github.com/shima-park/agollo/viper-remote/remote.go 26
var (
// apollod的appid
appID string
...
)
func SetAppID(appid string) {
appID = appid
}

//github.com/shima-park/agollo/viper-remote/remote.go 252
switch rp.Provider() {
...
case "apollo":
return newApolloConfigManager(appID, rp.Endpoint(), defaultAgolloOptions)
}

解決方案:

既然agollo包能讓viper支持apollo連接,那么為什么我們自己的包不能讓viper也支持apollo連接呢?并且我們還可以定制化的擴展成多實例連接。實現步驟如下:

  1. shima-pack/agollo/viper-remote/remote.go復制一份出來,把全局變量appID刪掉
  2. 定義"providers sync.Map",實現AddProviders()方法,將多個appId往里邊寫入,里邊帶上agollo.Option相關配置;同時關鍵操作要將新的provider往viper.SupportedRemoteProviders append,讓viper認識這個新類型
  3. 使用的地方,根據寫入時用的provider 串,去讀取,這樣多個appId和Option就都區分開了
  4. 其他代碼有標紅的地方就相應改改就行了

核心代碼 查看GitHub即可[2]:

//github.com/jinzaigo/xconfig/remote/remote.go
var (
...
providers sync.Map
)

func init() {
viper.RemoteConfig = &configProvider{} //目的:重寫viper.RemoteConfig的相關方法
}

type conf struct {
appId string
opts []agollo.Option
}

//【重要】這里是實現支持多個appId的核心操作
func AddProviders(appId string, opts ...agollo.Option) string {
provider := "apollo:" + appId
_, loaded := providers.LoadOrStore(provider, conf{
appId: appId,
opts: opts,
})

//之前未存儲過,則向viper新增一個provider,讓viper認識這個新提供器
if !loaded {
viper.SupportedRemoteProviders = append(
viper.SupportedRemoteProviders,
provider,
)
}

return provider
}

//使用的地方
func newApolloConfigManager(rp viper.RemoteProvider) (*apolloConfigManager, error) {
//讀取provider相關配置
providerConf, ok := providers.Load(rp.Provider())
if !ok {
return nil, ErrUnsupportedProvider
}

p := providerConf.(conf)
if p.appId == "" {
return nil, errors.New("The appid is not set")
}
...
}

4.viper開啟熱加載后會有并發讀寫不安全問題

首先 viper的使用文檔[3],也說明了這個并發讀寫不安全問題,建議使用sync包避免panic

圖片

然后本地通過-race試驗,也發現會有這個競態問題

圖片

進一步分析viper實現熱加載的源代碼:其實是通過協程實時更新kvstrore這個map,讀取數據的時候也是從kvstore讀取,并沒有加鎖,所以會有并發讀寫不安全問題

// 在github.com/spf13/viper/viper.go 1909
// Retrieve the first found remote configuration.
func (v *Viper) watchKeyValueConfigOnChannel() error {
if len(v.remoteProviders) == 0 {
return RemoteConfigError("No Remote Providers")
}

for _, rp := range v.remoteProviders {
respc, _ := RemoteConfig.WatchChannel(rp)
// Todo: Add quit channel
go func(rc <-chan *RemoteResponse) {
for {
b := <-rc
reader := bytes.NewReader(b.Value)
v.unmarshalReader(reader, v.kvstore)
}
}(respc)
return nil
}
return RemoteConfigError("No Files Found")
}

解決方案:

寫:不使用viper自帶熱加載方法,而是采用重寫,也是使用協程實時更新,但會加讀寫鎖。

讀:也加讀寫鎖

讀寫鎖核心代碼GitHub[4]:

//github.com/jinzaigo/xconfig/config.go
type Config struct {
configType string
viper *viper.Viper
viperLock sync.RWMutex
}

//
//_ = c.viper.WatchRemoteConfigOnChannel()
respc, _ := viper.RemoteConfig.WatchChannel(remote.NewProviderSt(provider, endpoint, namespace, ""))
go func(rc <-chan *viper.RemoteResponse) {
for {
<-rc
c.viperLock.Lock()
err = c.viper.ReadRemoteConfig()
c.viperLock.Unlock()
}
}(respc)

//
func (c *Config) Get(key string) interface{} {
c.viperLock.RLock()
defer c.viperLock.RUnlock()
return c.viper.Get(key)
}

5.如何正確的輸入namespace參數

問題描述:

調用agollo包中的相關方法,輸入namespace=application.properties(帶類型),發現主動拉取數據成功,遠程變更通知后數據拉取失??;輸入namespace=application(不帶類型),發現主動拉取數據成功,遠程變更通知后數據拉取也能成功。兩者輸入差異就在于是否帶類型

問題原因:

查看Apollo官方接口文檔[5],配置更新推送接口notifications/v2 notifications字段說明,一目了然。

圖片

基于上述說明,我們在代碼里做了兼容處理,并且配置文件也加上了使用說明

//github.com/jinzaigo/xconfig/config.go 72
func (c *Config) AddApolloRemoteConfig(endpoint, appId, namespace, backupFile string) error {
...
//namespace默認類型不用加后綴,非默認類型需要加后綴(備注:這里會涉及到apollo變更通知后的熱加載操作 Start->longPoll)
if c.configType != "properties" {
namespace = namespace + "." + c.configType
}
...
}

//config.yml配置說明
namespaces:
one:
key: ApplicationConfig #用于讀取配置,保證全局唯一,避免相互覆蓋
name: application #注意:name不要帶類型(例如application.properties),這里name和type分開配置
type: properties

總結

基于實際商業項目實踐,提升配置管理組件能力,實現了本地配置文件與遠程apollo配置中心多實例快速接入;

從xconfig包的快速上手的使用說明到封裝實踐難點痛點的解析,雙管齊下,讓你更深入的理解,希望對你有所幫助與收獲。

相關資料

[1]github地址: https://github.com/jinzaigo/xconfig

[2]查看GitHub即可: https://github.com/jinzaigo/xconfig

[3]viper的使用文檔: https://github.com/spf13/viper#is-it-safe-to-concurrently-read-and-write-to-a-viper

[4]讀寫鎖核心代碼GitHub: https://github.com/jinzaigo/xconfig

[5]Apollo官方接口文檔: https://www.apolloconfig.com/#/zh/usage/other-language-client-user-guide?id=_14-應用感知配置更新

本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關注。

轉載本文請聯系「 程序員升級打怪之旅」公眾號。

責任編輯:武曉燕 來源: 程序員升職加薪之旅
相關推薦

2021-07-15 08:58:15

指定配置項Go

2021-09-08 08:34:37

Go 文檔Goland

2012-04-23 11:13:33

2022-09-15 07:31:49

Spring攔截器注解

2009-09-02 10:05:22

遠程接入

2022-09-16 10:19:36

HarborContainerd

2009-10-28 10:55:27

2022-03-07 14:38:10

數據中心人工智能

2021-03-15 11:02:04

Docker網絡代理Linux

2025-11-18 07:52:13

2012-05-09 14:22:46

2009-10-28 14:35:16

遠程接入技術

2021-12-27 08:27:18

RepoGo 代碼

2010-12-21 17:36:12

2009-10-27 17:51:52

遠程接入技術

2009-10-28 10:26:36

2023-02-10 09:40:36

Go語言并發

2023-07-14 08:12:21

計時器unsafecontext

2013-03-20 15:40:00

騰訊數據中心萬兆接入

2022-01-27 08:27:23

Dubbo上下線設計
點贊
收藏

51CTO技術棧公眾號

91精品国产91久久久久久| 欧美日韩一区在线| 国产精品伊人日日| av黄色在线看| 欧美mv日韩| 日韩你懂的在线播放| 成人免费观看cn| 美女毛片在线看| 狠狠v欧美v日韩v亚洲ⅴ| 久久91亚洲精品中文字幕| 男女污污视频网站| 多野结衣av一区| 国产欧美日韩视频在线观看| 91久热免费在线视频| 日韩免费一二三区| 欧美手机视频| 精品久久人人做人人爰| 凹凸国产熟女精品视频| 亚洲精品传媒| 91蝌蚪porny| 91免费电影网站| 久草视频手机在线观看| 国产一区二区三区四区大秀| 在线综合亚洲欧美在线视频| 国产一区一区三区| 四虎影院在线播放| 经典三级在线一区| 国产精品成人一区二区三区吃奶| 精品97人妻无码中文永久在线| 久久av资源| 69精品人人人人| 日本在线观看a| 国产精品偷拍| 久久九九影视网| 99re在线视频观看| 中文字幕观看在线| 中文在线不卡| 欧美成人精品在线| 91在线无精精品白丝| japanese色系久久精品| 欧美丝袜丝交足nylons| 日韩视频 中文字幕| 国产精品毛片一区二区三区四区| 国产成人精品亚洲日本在线桃色 | 黄色网址在线视频| 国产麻豆一区二区三区| 色成年激情久久综合| 成人av在线不卡| 久草资源在线| 国产精品久久久久久久久久久免费看| 姬川优奈aav一区二区| 幼a在线观看| 亚洲黄色高清| 美女国内精品自产拍在线播放| a级大片在线观看| www.成人网| 日韩欧美激情在线| 日韩a一级欧美一级| 国产a亚洲精品| 欧美主播一区二区三区| 色综合av综合无码综合网站| 国产三级电影在线播放| 亚洲1区2区3区4区| 91国视频在线| 日韩精品av| 色综合视频一区二区三区高清| 少妇高潮毛片色欲ava片| 啪啪免费视频一区| 亚洲永久免费视频| 九九热只有这里有精品| 精品精品导航| 亚洲丶国产丶欧美一区二区三区| 青青在线视频免费观看| 牛牛在线精品视频| 午夜精品一区二区三区免费视频| 久久99久久久久久| 欧美大胆a人体大胆做受| 五月天久久比比资源色| 日本在线xxx| 超级碰碰久久| 婷婷开心激情综合| 国产精品wwwww| 8av国产精品爽爽ⅴa在线观看| 日本高清成人免费播放| 爱爱爱爱免费视频| 天堂久久av| 日韩精品一二三四区| 亚洲精品国产熟女久久久| av在线不卡免费观看| 日韩在线观看免费高清| 91成人福利视频| 国产日产高清欧美一区二区三区| 欧美在线中文字幕| 中文字幕+乱码+中文| 激情五月婷婷综合| 国产精品一区视频网站| 黄色片在线免费看| 久久久www成人免费无遮挡大片| 午夜精品一区二区在线观看的| 午夜视频1000| 国产精品你懂的在线| 宅男一区二区三区| 波多野结衣在线播放| 色婷婷香蕉在线一区二区| 婷婷免费在线观看| 136国产福利精品导航网址应用| 亚洲黄一区二区| 欧美高清性xxxx| 五月天久久久| 欧美黑人性猛交| 精品无码一区二区三区的天堂| 久久超碰97人人做人人爱| 国产精品区二区三区日本| sese一区| 亚洲成人av电影| 97超碰人人爽| 免费成人av| 欧美极品少妇xxxxⅹ免费视频| 中文字幕永久在线| 成人av在线网| 日本黄色播放器| 日韩电影av| 日韩欧美www| 亚洲一级片在线播放| 夜夜嗨av一区二区三区网站四季av| 国产成人一区二区三区| 成人av手机在线| 久久久高清一区二区三区| 看全色黄大色大片| 亚洲精品永久免费视频| 日韩一区二区精品| 成人午夜剧场视频网站| 欧美三级视频| 亚洲自拍在线观看| 爱爱爱免费视频在线观看| 五月天久久比比资源色| 中文写幕一区二区三区免费观成熟| 少妇精品久久久| 九九热视频这里只有精品| 最近中文字幕在线视频| 91免费在线看| 国产欧美日韩网站| 超碰一区二区| 日韩精品电影网| 久久精品性爱视频| 成人午夜视频在线| av 日韩 人妻 黑人 综合 无码| 超清av在线| 欧美一区二区人人喊爽| 欧美日韩黄色网| 国产一区二区免费视频| 久久天天东北熟女毛茸茸| 成人动漫视频在线观看| 色综合天天综合网国产成人网| 国产丰满果冻videossex| 一区二区高清在线| 亚洲av无码专区在线播放中文| 精品999成人| 欧美xxxx黑人又粗又长密月| 在线日韩影院| 一区二区三区视频在线| 91麻豆国产视频| 亚洲精品国产a| 久久人人妻人人人人妻性色av| 中日韩男男gay无套| 欧美一区二视频在线免费观看| 国产成人a视频高清在线观看| 久久精品国产久精国产一老狼| www.97超碰| 五月天久久比比资源色| 成熟人妻av无码专区| 久久99精品久久久久久| 91亚洲精品国产| 亚洲宅男一区| 成人夜晚看av| 国产欧洲在线| www.亚洲男人天堂| 欧洲成人一区二区三区| 一本大道av一区二区在线播放| 中文字幕黄色网址| 岛国一区二区在线观看| 蜜臀久久99精品久久久酒店新书| 9999国产精品| 久热国产精品视频一区二区三区| 日本午夜精品久久久久| 国内精品久久久久久久久| 国产无套粉嫩白浆在线2022年 | av动漫在线播放| 蜜桃成人av| 91日本在线视频| 韩日精品一区二区| 欧美日韩国产成人高清视频| 毛片在线免费| 欧美成人伊人久久综合网| 无码视频在线观看| 亚洲国产va精品久久久不卡综合| 国产精久久一区二区三区| 国产精品一区久久久久| 日本老熟妇毛茸茸| 伊人久久成人| 手机在线视频你懂的| 欧美调教网站| www日韩av| 欧美xxxx性| 97激碰免费视频| 成人免费视屏| 色偷偷av一区二区三区| 神马久久精品| 亚洲国产欧美久久| 午夜精品久久久久久久爽 | 亚洲欧美日韩国产手机在线| 添女人荫蒂视频| 成人综合婷婷国产精品久久蜜臀| 亚洲精品久久久中文字幕| 国产精品一区毛片| 乱熟女高潮一区二区在线| 日韩欧美高清在线播放| 欧美成熟毛茸茸复古| 黄色免费大全亚洲| 91av免费看| 国产精品亚洲四区在线观看| 国产精品女主播视频| 亚洲精品mv| 97香蕉久久超级碰碰高清版| 午夜影院免费在线| 久久综合久久八八| 日本免费视频在线观看| 在线一区二区日韩| 成年人视频在线观看免费| 亚洲女人天堂视频| 内衣办公室在线| 亚洲天堂一区二区三区| 九色在线播放| 亚洲欧洲日产国码av系列天堂| 四季av日韩精品一区| 精品电影一区二区| 亚洲毛片欧洲毛片国产一品色| 日韩一级完整毛片| 性做久久久久久久久久| 日韩欧美一级二级三级久久久| 国产又爽又黄免费软件| 91麻豆精品国产91久久久久| 亚洲系列在线观看| 制服丝袜av成人在线看| 99热这里只有精品99| 日韩一区二区视频| 亚洲第一视频在线| 欧美精品一区二| 特黄aaaaaaaaa真人毛片| 亚洲精品国产精品乱码不99按摩| 神马午夜一区二区| 日韩精品视频观看| 电影在线高清| 久久九九热免费视频| gogo在线观看| 久久久免费av| 亚洲国产福利| 91精品久久久久久久久| 精品视频一区二区三区在线观看 | 精品嫩草影院| 美女三级99| 色综合久久网| 毛片在线视频观看| 亚洲性图久久| 18禁免费无码无遮挡不卡网站| 老司机精品导航| 国产传媒免费观看| av资源网一区| 国产探花视频在线播放| 中文字幕综合网| 999这里只有精品| 欧美日韩在线精品一区二区三区激情 | 香蕉视频免费在线播放| 欧美成aaa人片免费看| 国产第一页在线视频| 57pao国产成人免费| 99久久伊人| 成人综合色站| 红桃成人av在线播放| 激情视频小说图片| 天堂蜜桃91精品| 亚洲综合中文网| 久久精品人人爽人人爽| 久久爱一区二区| 欧美性猛交xxxx富婆| 91在线你懂的| 日韩精品视频在线观看免费| 亚洲欧美视频一区二区| 91精品91久久久久久| www一区二区三区| 欧美精品久久| 欧美日韩mv| 日日噜噜夜夜狠狠| 99久久精品国产精品久久| 日本伦理一区二区三区| 欧美日韩激情视频8区| 国产精品一区二区av白丝下载| 亚洲精品720p| 成人av福利| 国产精品wwwwww| 成人av地址| 激情五月五月婷婷| 日韩不卡一区二区| 完美搭档在线观看| 亚洲乱码国产乱码精品精98午夜| 免费黄色网址在线| 亚洲大胆人体在线| 米奇精品一区二区三区| 国产97色在线| 欧美a大片欧美片| 黄色a级片免费看| 国产美女一区二区三区| 伊人网在线视频观看| 亚洲第一av色| 精品人妻久久久久一区二区三区| 国产亚洲一区二区精品| 欧美大胆a人体大胆做受| 国产精品久久久对白| 亚洲一级淫片| 国产传媒免费观看| 1024精品合集| 91在线公开视频| 色婷婷久久一区二区| 精品视频在线一区二区在线| 免费电影一区| 久久尤物视频| 国产激情在线免费观看| 懂色av一区二区三区| 欧美熟女一区二区| 欧美—级a级欧美特级ar全黄| 成人免费91| 做爰高潮hd色即是空| 久久99国产精品久久99果冻传媒| 最近中文字幕免费视频| 一本色道久久综合亚洲aⅴ蜜桃 | av不卡在线观看| 国产精品自拍视频一区| 欧美精品一区二区三区蜜臀| 青青青国内视频在线观看软件| 91视频在线免费观看| 欧美视频网站| 人妻 日韩 欧美 综合 制服| 亚洲一区二区中文在线| 丰满少妇一级片| 色综合91久久精品中文字幕 | 美女一区二区视频| 任我爽在线视频| 91精品国产欧美一区二区成人| 韩国av网站在线| 国产高清一区二区三区| 伊人精品成人久久综合软件| 日本黄色录像片| 色综合av在线| 欧美成人三区| 99在线看视频| 99视频精品| 国产免费无遮挡吸奶头视频| 在线亚洲精品福利网址导航| av网在线观看| 91在线免费观看网站| 亚洲最新av| 国产视频精品视频| 色一区在线观看| 麻豆传媒在线观看| 99热国产免费| 免费永久网站黄欧美| 色噜噜噜噜噜噜| 欧美一区三区四区| 日韩大片免费观看| 一本一生久久a久久精品综合蜜| 国产一区二区三区av电影| 国产成人啪精品午夜在线观看| 亚洲美女av在线播放| 色婷婷成人网| 国产深夜男女无套内射| 中文字幕乱码日本亚洲一区二区| 国产精品久久免费| 91chinesevideo永久地址| 不卡在线一区二区| 精品无码人妻少妇久久久久久| 色综合久久久久综合体桃花网| 一级毛片视频在线| 久久99精品久久久久久三级| 欧美aaaaa成人免费观看视频| 欧美片一区二区| 亚洲人成在线观看网站高清| 国产精品美女久久久久人| 免费av观看网址| 亚洲欧美中日韩| 青青久草在线| 91亚洲精品丁香在线观看| 久久精品五月| 久久免费视频播放| 中文字幕亚洲精品| 网友自拍一区| 女教师高潮黄又色视频| 欧美自拍偷拍午夜视频| 超黄网站在线观看| 国产av不卡一区二区| 国产视频911|