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

如何實現一個分布式配置中心?

開發 架構
配置中心在大廠系統開發中是一個非常常用的功能,它的核心功能在于不需要上線系統的情況下,改變系統中對象或者屬性的值。是屬性的值,也就是你在通過類獲取某個屬性,判斷;功能開關、渠道地址、人群名單、息費費率、切量占比等等,這些可能隨時動態調整的值,都是通過配置中心實現的。

本文的宗旨在于通過簡單干凈實踐的方式,向讀者介紹 Zookeeper 的安裝配置,學習 SpringBoot 整合使用,以及基于 Zookeeper 開發一個簡單的配置中心功能內核。通過這樣的實踐方式,讓讀者入門和掌握 Zookeeper 以應對后續需要此技術棧的相關開發項目。

本文的重點是基于 Zookeeper 實現的配置中心,那配置中心是啥呢?

配置中心在大廠系統開發中是一個非常常用的功能,它的核心功能在于不需要上線系統的情況下,改變系統中對象或者屬性的值。是屬性的值,也就是你在通過類獲取某個屬性,判斷;功能開關、渠道地址、人群名單、息費費率、切量占比等等,這些可能隨時動態調整的值,都是通過配置中心實現的。所以在本章節的案例中,小傅哥基于 Zookeeper 組件的功能特性,來設計這樣一個配置中心,方便大家學習。

本文涉及的工程:

  • xfg-dev-tech-zookeeper:https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-connection-pool - docs/dev-ops 提供了 Zookeeper 安裝腳本。

一、配置中心

Zookeeper 有什么特性,動態配置中心怎么做?

技術是支撐解決方案實現的,有了各個技術棧組件的自身特點,才好實現出我們所需的各類功能。那么這樣的一個能讓,各個服務都可以動態變更配置的配置中心,就要用到 Zookeeper 的節點監聽和節點值的變化來動態設置 Java 類中屬性的變化。如圖:

圖片圖片

  • 首先,我們需要定義出一個 Zookeeper 監聽的配置路徑,一般這個路徑在配置中心中是申請的系統使用地址,以確保值的唯一。
  • 之后,每個類對應的屬性,需要映射出一個監聽的節點。比如;Zookeeper 監聽了 /xfg-dev-tech/config 那么類中 a 屬性可以是 /xfg-dev-tech/config/a 這對這個路徑設置的值,就可以被監聽拿到了。
  • 最后,把獲取到的監聽值,通過 Java 反射操作,把值設置到對應的屬性上。這樣在 SpringBoot 應用程序中,使用某個類的屬性值的時候,就可以動態的獲取到變化的屬性值了。

二、環境配置

在安裝執行 docker-compose.yml 腳本之前,你需要先在本地安裝 docker 之后 IntelliJ IDEA 打開 docker-compose.yml 文件,如圖操作即可安裝。

圖片圖片

圖片圖片

  • 另外,如果你是在服務器上安裝,則需要執行 docker-compose -f docker-compose.yml up -d 并且是你已經安裝了 Docker-Compose 包。—— 這些內容在小傅哥的《Java 簡明教程》中都有講解,可以進入學習。

三、基本使用

連接腳本:

docker exec -it zookeeper bash
zkCli.sh -server IP(替換為你自己的):2181

常用命令:

1. 創建節點:create /path data
2. 創建臨時節點:create -e /path data
3. 創建順序節點:create -s /path data
4. 創建臨時順序節點:create -e -s /path data
5. 獲取節點數據:get /path
6. 獲取節點子節點列表:ls /path
7. 更新節點數據:set /path data
8. 刪除節點:delete /path
9. 刪除節點及其子節點:deleteall /path
10. 監聽節點變化:get -w /path
11. 查看節點狀態:stat /path
12. 查看節點ACL權限:getAcl /path
13. 設置節點ACL權限:setAcl /path acl
14. 查看節點子節點數量:count /path
15. 查看節點子節點數量并監聽變化:count -w /path
root@4365b68d50d6:/apache-zookeeper-3.9.0-bin# ls
bin  conf  docs  lib  LICENSE.txt  NOTICE.txt  README.md  README_packaging.md
root@4365b68d50d6:/apache-zookeeper-3.9.0-bin# zkCli.sh -server 10.253.6.71:2181

[zk: 192.168.1.101:2181(CONNECTED) 1] ls /xfg-dev-tech
[config, configdowngradeSwitch]
[zk: 192.168.1.101:2181(CONNECTED) 2]

執行完鏈接 Zookeeper 以后,就可以執行這些常用命令了。你也可以嘗試著練習下這些命令。

四、功能實現

1. 工程結構

圖片圖片

工程結構分為2個部分:

  • app 啟動層的 config 包下,用于提供 Zookeeper 服務的啟動配置。以及小傅哥在這里新添加的功能 DCCValue 配置中心模塊。
  • trigger 是觸發器,這里吧 http 請求、listener 監聽,都是放到這里使用。另外像 MQ、JOB、RPC 也是放到這一層,以這一層觸發,來調用我們的領域服務。

2. 啟動 Zookeeper 服務

2.1 自定配置

@Data
@ConfigurationProperties(prefix = "zookeeper.sdk.config", ignoreInvalidFields = true)
public class ZookeeperClientConfigProperties {

    private String connectString;
    private int baseSleepTimeMs;
    private int maxRetries;
    private int sessionTimeoutMs;
    private int connectionTimeoutMs;

}

2.2 使用配置

zookeeper:
  sdk:
    config:
      connect-string: 10.253.6.71:2181
      base-sleep-time-ms: 1000
      max-retries: 3
      session-timeout-ms: 1800000
      connection-timeout-ms: 30000

2.3 配置服務

@Configuration
@EnableConfigurationProperties(ZookeeperClientConfigProperties.class)
public class ZooKeeperClientConfig {

    /**
     * 多參數構建ZooKeeper客戶端連接
     *
     * @return client
     */
    @Bean(name = "zookeeperClient")
    public CuratorFramework createWithOptions(ZookeeperClientConfigProperties properties) {
        ExponentialBackoffRetry backoffRetry = new ExponentialBackoffRetry(properties.getBaseSleepTimeMs(), properties.getMaxRetries());
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(properties.getConnectString())
                .retryPolicy(backoffRetry)
                .sessionTimeoutMs(properties.getSessionTimeoutMs())
                .connectionTimeoutMs(properties.getConnectionTimeoutMs())
                .build();
        client.start();
        return client;
    }

}
  • 這樣我們就可以啟動一個 Zookeeper 的客戶端了,自定義可以更好的控制和使用。

3. 定義注解

就功能來講,我們需要對類中的屬性進行賦值操作。那么就需要使用自定義注解進行標記。所以這里我們先自定義一個注解。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
public @interface DCCValue {

    String value() default "";

}
  • 這樣所有使用了 @DCCValue 的注解的字段就都可以被我掃描到了。

4. 監聽變化

4.1 獲取屬性

源碼:cn.bugstack.xfg.dev.tech.config.DCCValueBeanFactory#postProcessAfterInitialization

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    Class<?> beanClass = bean.getClass();
    Field[] fields = beanClass.getDeclaredFields();
    for (Field field : fields) {
        if (field.isAnnotationPresent(DCCValue.class)) {
            DCCValue dccValue = field.getAnnotation(DCCValue.class);
            try {
                if (null == client.checkExists().forPath(BASE_CONFIG_PATH.concat("/").concat(dccValue.value()))) {
                    client.create().creatingParentsIfNeeded().forPath(BASE_CONFIG_PATH.concat("/").concat(dccValue.value()));
                    log.info("DCC 節點監聽 listener node {} not absent create new done!", BASE_CONFIG_PATH.concat("/").concat(dccValue.value()));
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            dccObjGroup.put(BASE_CONFIG_PATH.concat("/").concat(dccValue.value()), bean);
        }
    }
    return bean;
}
  • DCCValueBeanFactory 實現了 BeanPostProcessor 接口的 postProcessAfterInitialization 方法。
  • 在實現中,通過對 bean 對象的解析獲取到使用 DCCValue 注解屬性,并判斷這個屬性拼接的地址是否在 Zookeeper 中創建,如果沒有則創建。之后保存對象到內存中。

4.2 設置屬性

源碼:cn.bugstack.xfg.dev.tech.config.DCCValueBeanFactory#DCCValueBeanFactory

curatorCache.listenable().addListener((type, oldData, data) -> {
    switch (type) {
        case NODE_CHANGED:
            String dccValuePath = data.getPath();
            Object objBean = dccObjGroup.get(dccValuePath);
            try {
                // 1. getDeclaredField 方法用于獲取指定類中聲明的所有字段,包括私有字段、受保護字段和公共字段。
                // 2. getField 方法用于獲取指定類中的公共字段,即只能獲取到公共訪問修飾符(public)的字段。
                Field field = objBean.getClass().getDeclaredField(dccValuePath.substring(dccValuePath.lastIndexOf("/") + 1));
                field.setAccessible(true);
                field.set(objBean, new String(data.getData()));
                field.setAccessible(false);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            break;
        default:
            break;
    }
});
  • 基于 Zookeeper 對節點的監聽,只要這個節點上有值發生變化。就可以立刻檢測到對應的路徑信息和值信息。
  • 那么拿到這個值信息,就可以把值寫入到對應的屬性上了。如類.A = Zookeeper 獲取到的值

五、功能使用

源碼:cn.bugstack.xfg.dev.tech.trigger.http.ConfigController

@RestController
public class ConfigController {

    @DCCValue("downgradeSwitch")
    private String downgradeSwitch;

    @DCCValue("userWhiteList")
    private String userWhiteList;

    @Resource
    private CuratorFramework curatorFramework;

    /**
     * curl http://localhost:8091/getConfig/downgradeSwitch
     */
    @RequestMapping("/getConfig/downgradeSwitch")
    public String getConfigDowngradeSwitch() {
        return downgradeSwitch;
    }

    /**
     * curl http://localhost:8091/getConfig/userWhiteList
     */
    @RequestMapping("/getConfig/userWhiteList")
    public String getConfigUserWhiteList() {
        return userWhiteList;
    }

    /**
     * curl -X GET "http://localhost:8091/setConfig?downgradeSwitch=false&userWhiteList=xfg,user2,user3"
     */
    @GetMapping("/setConfig")
    public void setConfig(Boolean downgradeSwitch, String userWhiteList) throws Exception {
        curatorFramework.setData().forPath("/xfg-dev-tech/config/downgradeSwitch", (downgradeSwitch ? "開" : "關").getBytes(StandardCharsets.UTF_8));
        curatorFramework.setData().forPath("/xfg-dev-tech/config/userWhiteList", userWhiteList.getBytes(StandardCharsets.UTF_8));
    }
    
}

這里的核心驗證就是讓 downgradeSwitch、userWhiteList 這2個屬性值可以動態變化;

  1. 在兩個屬性上添加注解后,就會被掃描和管理。
  2. 獲取值方法:http://localhost:8091/getConfig/downgradeSwitch、http://localhost:8091/getConfig/userWhiteList
  3. 設置值方法:http://localhost:8091/setConfig?downgradeSwitch=false&userWhiteList=xfg,user2,user3 - 這里的設置值操作不非得在這里,可以是一個單獨的控制后臺來操作。這里的方式主要是演示作用

圖片圖片

你可以按照如圖的操作順序,進行驗證屬性值的變化。

六、其他測試

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApiTest {

    @Resource
    private CuratorFramework curatorFramework;

    @Test
    public void test_all() throws Exception {
        String path = "/xfg-dev-tech/config/downgradeSwitch";
        String data = "0";
        curatorFramework.create().withMode(CreateMode.EPHEMERAL).forPath(path, data.getBytes(StandardCharsets.UTF_8));

        for (int i = 0; i < 2; i++) {
            curatorFramework.setData().forPath(path, String.valueOf(i).getBytes(StandardCharsets.UTF_8));
        }
    }

    /**
     * 創建永久節點
     */
    @Test
    public void createNode() throws Exception {
        String path = "/xfg-dev-tech/config/downgradeSwitch/test/a";
        String data = "0";
        if (null == curatorFramework.checkExists().forPath(path)) {
            curatorFramework.create().creatingParentsIfNeeded().forPath(path);
        }
    }

    /**
     * 創建臨時節點
     */
    @Test
    public void createEphemeralNode() throws Exception {
        String path = "/xfg-dev-tech/config/epnode";
        String data = "0";
        curatorFramework.create().withMode(CreateMode.EPHEMERAL).forPath(path, data.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 創建臨時有序節點
     */
    @Test
    public void crateEphemeralSequentialNode() throws Exception {
        String path = "/xfg-dev-tech/config/epsnode";
        String data = "0";
        curatorFramework.create()
                .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                .forPath(path, data.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 往節點種設置數據
     */
    @Test
    public void setData() throws Exception {
        curatorFramework.setData().forPath("/xfg-dev-tech/config/downgradeSwitch", "111".getBytes(StandardCharsets.UTF_8));
        curatorFramework.setData().forPath("/xfg-dev-tech/config/userWhiteList", "222".getBytes(StandardCharsets.UTF_8));
    }

    @Test
    public void getData() throws Exception {
        String downgradeSwitch = new String(curatorFramework.getData().forPath("/xfg-dev-tech/config/downgradeSwitch"), StandardCharsets.UTF_8);
        log.info("測試結果: {}", downgradeSwitch);
        String userWhiteList = new String(curatorFramework.getData().forPath("/xfg-dev-tech/config/userWhiteList"), StandardCharsets.UTF_8);
        log.info("測試結果: {}", userWhiteList);
    }

    /**
     * 異步修改數據
     */
    @Test
    public void setDataAsync() throws Exception {
        String path = "/xfg-dev-tech/config/downgradeSwitch";
        String data = "0";
        CuratorListener listener = (client, event) -> {
            Stat stat = event.getStat();
            log.info("stat=" + JSON.toJSONString(stat));
            CuratorEventType eventType = event.getType();
            log.info("eventType=" + eventType.name());
        };
        curatorFramework.getCuratorListenable().addListener(listener);
        curatorFramework.setData().inBackground().forPath(path, data.getBytes(StandardCharsets.UTF_8));
    }


    /**
     * 刪除節點
     */
    @Test
    public void deleteData() throws Exception {
        String path = "/xfg-dev-tech/config/downgradeSwitch";
        curatorFramework.delete().deletingChildrenIfNeeded().forPath(path);
    }

    /**
     * 安全刪除節點
     */
    @Test
    public void guaranteedDeleteData() throws Exception {
        String path = "/xfg-dev-tech/config/downgradeSwitch";
        curatorFramework.delete().guaranteed().forPath(path);
    }

    /**
     * 獲取子節點下的全部子節點路徑集合
     */
    @Test
    public void watchedGetChildren() throws Exception {
        String path = "/xfg-dev-tech";
        List<String> children = curatorFramework.getChildren().watched().forPath(path);
        log.info("測試結果:{}", JSON.toJSONString(children));
    }


    /**
     * 獲取節點數據
     */
    @Test
    public void getDataByPath() throws Exception {
        String path = "/xfg-dev-tech/config/downgradeSwitch";
        String fullClassName = "";
        String jsonStr = new String(curatorFramework.getData().forPath(path), StandardCharsets.UTF_8);
        Class clazz = Class.forName(fullClassName);
        log.info("測試結果:{}", JSON.parseObject(jsonStr, clazz));
    }

}
  • 這些功能也都可以測試驗證,也是平常用的較多的東西。

七、其他資料

  • Zookeeper Web UI:https://zoonavigator.elkozmon.com/en/latest/
  • 官網文檔:https://zookeeper.apache.org/doc/r3.5.0-alpha/zookeeperAdmin.html
責任編輯:武曉燕 來源: bugstack蟲洞棧
相關推薦

2024-07-15 08:25:07

2021-11-01 12:25:56

Redis分布式

2020-07-30 09:35:09

Redis分布式鎖數據庫

2019-12-27 16:00:56

分布式事務框架Java

2022-06-13 10:01:36

Apollo攜程框架

2025-03-06 11:30:15

2022-04-14 07:56:30

公平鎖Java線程

2023-03-06 08:14:48

MySQLRedis場景

2022-06-27 08:36:27

分布式事務XA規范

2024-03-18 08:50:20

分布式系統機制

2016-09-30 10:13:07

分布式爬蟲系統

2022-08-01 08:01:04

ID發號器系統

2021-02-10 09:54:15

分布式NacosApollo

2024-05-08 10:20:00

Redis分布式

2024-02-19 00:00:00

Redis分布式

2022-04-08 11:24:39

分布式配置中心服務端

2018-09-06 22:49:31

分布式架構服務器

2023-08-21 19:10:34

Redis分布式

2022-09-22 13:28:34

Redis分布式鎖

2022-09-29 08:28:57

SpringRedis分布式
點贊
收藏

51CTO技術棧公眾號

99r国产精品视频| 美女黄色丝袜一区| 午夜免费福利视频在线观看| 久久精品视频观看| 成人黄色小视频在线观看| 欧美又大又粗又长| 小泽玛利亚一区二区免费| 久久精品色综合| 欧美日韩成人综合在线一区二区| 男人的天堂avav| 福利在线视频导航| 成a人片亚洲日本久久| 国产精品入口福利| 亚洲一区 视频| 色偷偷综合网| 日韩电影在线观看中文字幕 | 国产欧美一区二区色老头| 中文字幕精品久久久久| 人妻激情偷乱频一区二区三区| av一区在线播放| 亚洲成精国产精品女| 在线免费观看成人网| 青青草免费在线视频| 国产精品一级黄| 国产精品久久久久久久av电影| 国产精品第二十页| 中文字幕亚洲综合久久五月天色无吗''| 日韩电影在线观看中文字幕| 97中文字幕在线观看| 久久亚洲人体| 色噜噜狠狠成人中文综合| 成人性生活视频免费看| gogogogo高清视频在线| 国产精品丝袜在线| 欧美主播一区二区三区美女 久久精品人 | 精品影片一区二区入口| 国产精品久久久久久av公交车| 色综合婷婷久久| 国产美女网站在线观看| 欧美人动性xxxxz0oz| 亚洲欧洲日韩在线| 亚洲制服中文| av电影在线观看一区二区三区| 91视频xxxx| 久久99精品国产一区二区三区| 成人精品在线播放| 国产丶欧美丶日本不卡视频| 91在线网站视频| 一卡二卡三卡在线观看| 美女在线观看视频一区二区| 国产精品av在线播放| 一级片在线观看免费| 久久久久久久欧美精品| 国产成+人+综合+亚洲欧美丁香花| 日韩精品久久久久久久| 在线视频精品| 欧美综合国产精品久久丁香| 亚洲精品午夜国产va久久成人| 亚洲毛片一区| 欧美在线免费观看| 国产又粗又猛又黄视频| 日本va欧美va瓶| 国产精品女主播| 亚洲综合视频在线播放| 国产精品一区在线观看你懂的| 亚洲专区中文字幕| 亚洲免费不卡视频| 成人美女视频在线看| 久久精品ww人人做人人爽| 欧美欧美欧美| 国产精品电影一区二区| 五月天在线免费视频| 美女日批视频在线观看| 欧美日韩一区二区精品| 亚洲一二三区av| 欧美大陆国产| 欧美mv和日韩mv的网站| 国产三级国产精品| 欧美色图国产精品| 美日韩精品视频免费看| 久久久香蕉视频| 久久精品盗摄| 成人性生交大片免费看视频直播| 性生交大片免费看女人按摩| 99久久免费精品| 亚洲福利av| 在线观看男女av免费网址| 午夜精品久久久久久久久久久| 亚洲 中文字幕 日韩 无码| 97精品国产综合久久久动漫日韩| 91精品国产综合久久久久久| 欧美成人三级伦在线观看| 成人免费av| 九色精品美女在线| 日本视频网站在线观看| 国产乱一区二区| 欧洲av一区| 中文字幕中文字幕在线中高清免费版| 精品久久久久久久久久国产| 女同激情久久av久久| 成人av动漫| 在线视频中文亚洲| 精品一级少妇久久久久久久| 日韩电影免费在线看| 99久久无色码| 91九色在线porn| 精品国产户外野外| 色婷婷综合在线观看| 伊人久久大香线蕉av不卡| 久久久久www| 国产一级片av| www.爱久久.com| 日本a级片在线观看| 欧美黑人粗大| 精品国产乱码久久久久久夜甘婷婷 | 国产成人精品一区二区无码呦| 久久久久99精品一区| 欧美久久久久久久久久久久久久| 亚洲第一会所| 亚洲开心激情网| 久久精品视频日本| 久久99精品久久久| 日本一区二区三区www| 丁香花在线影院| 午夜精品一区二区三区国产| 成年人午夜视频| 欧美综合久久| 91av国产在线| 国产精品国产三级国产普通话对白| 99在线精品免费| 17c丨国产丨精品视频| 欧洲亚洲精品| 在线观看国产成人av片| 91在线视频在线观看| 成人动漫一区二区| 日本免费黄色小视频| 国产69精品久久久久9999人| 亚洲欧洲一区二区三区久久| av大全在线观看| www.欧美.com| 精品久久一二三| 精品网站aaa| 久久久久久久999| 亚洲精品97久久中文字幕| 亚洲精品欧美在线| www.色.com| 欧美成人精品| 亚洲综合成人婷婷小说| h片在线播放| 日韩欧美国产麻豆| 麻豆成人在线视频| 成人激情午夜影院| 欧美成人三级在线视频| 欧美综合精品| 欧美有码在线观看视频| 国产在线视频网站| 欧美亚洲一区二区在线观看| 中文字幕在线观看免费高清| 青青草一区二区三区| 亚洲自拍三区| 久久伊人影院| 久久久久久欧美| 日韩资源在线| 欧美在线观看视频一区二区三区| 国产aaaaaaaaa| 国产一区二区三区免费观看| 成人在线播放网址| 欧美性生活一级片| 国产精品va在线播放| av片在线免费观看| 欧美成人一区二区三区片免费 | 日韩免费观看av| 国产1区2区3区在线| 欧美日韩国产片| 久草视频免费在线播放| 99久久国产综合精品色伊 | aaa在线播放视频| 亚洲美女在线视频| 少妇又紧又色又爽又刺激视频 | 精品久久免费视频| 99精品国产热久久91蜜凸| 最近免费中文字幕中文高清百度| 精品成人影院| 97人摸人人澡人人人超一碰| 精品三级久久| 日韩在线激情视频| 日韩一区二区三区在线观看视频| 色域天天综合网| 夫妻性生活毛片| 26uuu精品一区二区三区四区在线| 日日噜噜噜噜久久久精品毛片| 91精品国产自产拍在线观看蜜| 99视频免费观看| 日韩漫画puputoon| 久久97精品久久久久久久不卡| 青青草在线播放| 欧美一卡二卡在线| 国产成人综合欧美精品久久| 综合亚洲深深色噜噜狠狠网站| a级一a一级在线观看| 美女看a上一区| 亚洲午夜精品久久久久久人妖| 99久久久国产精品美女| 久久99精品久久久久久青青日本| 国产日韩在线观看视频| 国产精品va在线播放| 精精国产xxxx视频在线野外| 欧美xxxx18国产| 91电影在线播放| 亚洲精品视频久久| 精品区在线观看| 欧美日韩一区二区三区免费看 | 国产欧美黑人| 尤物九九久久国产精品的特点| 性中国xxx极品hd| 欧美日韩国产一二三| 91浏览器在线观看| 一区二区高清视频在线观看| 人妻互换一区二区激情偷拍| 91欧美激情一区二区三区成人| 性一交一黄一片| 精品中文字幕一区二区| 国产视频一区二区视频| 亚洲永久免费| 免费一级特黄毛片| 欧美阿v一级看视频| 最近看过的日韩成人| 欧美手机视频| 日本高清一区| 亚洲资源网站| 久久久亚洲综合网站| 国产精品欧美大片| julia一区二区中文久久94| 亚洲精品伦理| 国产精品一区二区久久国产| 婷婷午夜社区一区| 欧美一区二区影院| 国模私拍一区二区国模曼安| 97人人模人人爽人人喊中文字 | 日本欧美中文字幕| 欧美一级鲁丝片| 性欧美长视频免费观看不卡| 成年网站在线视频网站| 欧美精品激情在线| 黄色成人在线网| 国内精品久久久久影院优| 搞黄网站在线看| 欧美激情欧美激情| av影院在线| 91精品国产色综合久久不卡98口 | 日本久久久久久久久久| 国产成人精品免费| 亚洲免费观看在线| 91在线视频官网| 色婷婷av777| 国产亚洲一本大道中文在线| 成人无码av片在线观看| 国产精品素人一区二区| 国产免费一区二区三区四区| 亚洲欧美精品午睡沙发| 欧美成人一区二区三区高清| 亚洲国产精品自拍| 日操夜操天天操| 欧美性猛交xxxx富婆| 波多野结衣大片| 91精品久久久久久久99蜜桃| 亚洲欧美另类一区| 日韩av在线免费| 午夜视频在线免费观看| 久久综合久久八八| 好吊日av在线| 日本中文字幕久久看| 少妇高潮一区二区三区99| av日韩中文字幕| 亚洲精品**不卡在线播he| 色一情一区二区三区四区| 国产精品videosex性欧美| av在线免费观看国产| 免费永久网站黄欧美| 无尽裸体动漫2d在线观看| 国产美女久久久久| 黄色国产在线观看| 国产精品水嫩水嫩| 免费一级肉体全黄毛片| 欧美性猛xxx| 国产乱色精品成人免费视频 | 五月婷婷在线观看| 久久精品国产一区| 久草在线中文最新视频| 成人黄色av免费在线观看| 欧美日韩一区二区三区不卡视频| 亚洲欧美精品| 亚洲精一区二区三区| 天堂av在线8| 久久男人中文字幕资源站| 中文字幕手机在线观看| 色综合久久久久综合99| 国产丰满果冻videossex| 亚洲色图第一页| 免费网站在线观看人| 国产美女被下药99| 欧美黑白配在线| 国产一级片91| 美女视频黄免费的久久 | 久久高清精品| 春日野结衣av| 国产成人精品免费| 日韩一卡二卡在线观看| 色婷婷国产精品| 欧美视频一二区| 久久久av一区| 99只有精品| 欧美久久久久久| 亚洲第一伊人| 熟女人妻一区二区三区免费看| 欧美国产一区在线| 亚洲欧美自拍视频| 亚洲国产91精品在线观看| 国产福利视频在线观看| 国产精品黄色av| 中文字幕亚洲影视| 男人揉女人奶房视频60分| 粉嫩久久99精品久久久久久夜 | 一区二区不卡| 992kp快乐看片永久免费网址| 99久久夜色精品国产网站| 免费一级肉体全黄毛片| 717成人午夜免费福利电影| 在线免费看黄| 国产精品丝袜高跟| 精品视频国产| 女性隐私黄www网站视频| 91麻豆精品一区二区三区| 国产精品美女毛片真酒店| 精品电影一区二区三区| 羞羞网站在线免费观看| 亚洲一区二区三区视频| 欧美一区成人| 一级全黄裸体片| 亚洲一区影音先锋| 午夜精品久久久久久久99热黄桃| 久久av资源网站| 欧美黄视频在线观看| 欧美a级黄色大片| 国产精品一区二区三区乱码| www.99re7| 日韩一区二区免费在线电影| 在线观看三级视频| 超碰97在线资源| 最新国产乱人伦偷精品免费网站| 性猛交╳xxx乱大交| 亚洲高清免费视频| 手机看片福利在线| 91成人在线观看国产| 中国av一区| 男人的天堂日韩| 中文字幕在线免费不卡| av网站在线免费看| 久久久久久亚洲精品不卡| 国产精品qvod| 成人三级视频在线播放 | 久久久久久久久久综合| 欧美精品一区二区三区在线播放 | 午夜不卡久久精品无码免费| 亚洲1区2区3区视频| 三级av在线| 91精品久久久久久久久久久久久 | 欧美日本亚洲视频| 一区二区网站| 少妇性饥渴无码a区免费| 国产亚洲精品中文字幕| 国产又粗又黄又爽| 国内精品久久影院| 欧美在线电影| 操人视频免费看| 精品久久久久久| 麻豆网站在线看| 狠狠色噜噜狠狠狠狠色吗综合| 日日骚欧美日韩| 精品女人久久久| 亚洲国产精品女人久久久| 日韩三区在线| 激情视频小说图片| 97精品久久久久中文字幕| 中文字幕黄色av| 国内精品模特av私拍在线观看| 国产日产精品_国产精品毛片| 免费精品99久久国产综合精品应用| 一区二区三区**美女毛片| 美国成人毛片| 亚洲在线www| 男女男精品网站| 精品无码人妻一区二区三区品 | 久久久久久久免费| 麻豆91小视频| 日本一区二区三区四区五区| 中文字幕日韩欧美在线视频| 成人影院中文字幕| 五月天亚洲视频| 精品日韩中文字幕|