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

自己開發一個分布式的 Xxl-Job 任務調度組件

開發 前端
如果我們的任務是比較大型的,比如;定時跑批T+1結算、商品秒殺前狀態變更、刷新數據預熱到緩存等等,這些定時任務都相同的特點;作業量大、實時性強、可用率高。而這時候如果只是單純使用Schedule就顯得不足以控制。
前言
@SpringBootApplication
@EnableScheduling
public class Application{
public static void mian(String[] args){
SpringApplication.run(Application.class,args);
}

@Scheduled(cron = "0/3 * * * * *")
public void demoTask() {
//...
}
}
  • 咔咔,上面這段代碼很熟悉吧,他就是SpringBoot的Schedule定時任務,簡單易用。在我們開發中如果需要做一些定時或指定時刻循環執行邏輯時候,基本都會使用到Schedule。
  • 但是,如果我們的任務是比較大型的,比如;定時跑批T+1結算、商品秒殺前狀態變更、刷新數據預熱到緩存等等,這些定時任務都相同的特點;作業量大、實時性強、可用率高。而這時候如果只是單純使用Schedule就顯得不足以控制。
  • 那么,我們產品需求就出來了,分布式DcsSchedule任務;
  • 多機器部署任務
  • 統一控制中心啟停
  • 宕機災備,自動啟動執行
  • 實時檢測任務執行信息:部署數量、任務總量、成功次數、失敗次數、執行耗時等
  • 嗯?有人憋半天了想說可以用Quertz,嗯可以的,但這不是本篇文章的重點。難道你不想看看一個自言開源中間件是怎么誕生的嗎,怎么推到中心Maven倉的嗎?比如下圖;真香不!
  • 首頁監控

  • 任務列表

  • 好了,接下來開始介紹這個中間件如何使用和怎么開發的了!
  • 中間件使用
  • 1. 版本記錄
  • 版本 發布日期 備注 1 1.0.0-RELEASE 2019-12-07 基本功能實現;任務接入、分布式啟停 1.0.1-RELEASE 2019-12-07 上傳測試版本
  • 2. 環境準備
  • jdk1.8
  • StringBoot 2.x
  • 配置中心zookeeper 3.4.14 {準備好zookeeper服務,如果windows調試可以從這里下載:https://www-eu.apache.org/dist/zookeeper}
  • 下載后解壓,在bin同級路徑創建文件夾data、logs
  • 修改conf/zoo.cfg,修改配置如下;dataDir=D:\\Program Files\\apache-zookeeper-3.4.14\\data
    dataLogDir=D:\\Program Files\\apache-zookeeper-3.4.14\\logs
  • 打包部署控制平臺
  • 下載地址:https://git***.com/fuzhengwei/itstack-middleware-control.git
  • 部署訪問:http://localhost:7397
  • 3. 配置POM
<dependency>
<groupId>org.itstack.middleware</groupId>
<artifactId>schedule-spring-boot-starter</artifactId>
<version>1.0.0-RELEASE</version>
</dependency>
  • 4. 引入分布式任務DcsSchedule @EnableDcsScheduling
?與SpringBoot的Sceduling非常像,他的注解是;@EnableScheduling,盡可能降低使用難度
  • 這個注解主要方便?給我們自己的中間件一個入口,也是扒拉源碼發現的可以這么干{我一直說好的代碼都很騷氣}
@SpringBootApplication
@EnableDcsScheduling
public class HelloWorldApplication {

public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}

}

5. 在任務方法上添加注解

  • 這個注解也和SpringBoot的Schedule很像,但是多了desc描述和啟停初始化控制
  • cron:執行計劃
  • desc:任務描述
  • autoStartup:默認啟動狀態
  • 如果你的任務需要參數可以通過引入service去調用獲取等方式都可以
@Component("demoTaskThree")
public class DemoTaskThree {

@DcsScheduled(cron = "0 0 9,13 * * *", desc = "03定時任務執行測試:taskMethod01", autoStartup = false)
public void taskMethod01(){
System.out.println("03定時任務執行測試:taskMethod01");
}

@DcsScheduled(cron = "0 0/30 8-10 * * *", desc = "03定時任務執行測試:taskMethod02", autoStartup = false)
public void taskMethod02(){
System.out.println("03定時任務執行測試:taskMethod02");
}

}

6. 啟動驗證

  1. 啟動SpringBoot工程即可,autoStartup = true的會自動啟動任務(任務是多線程并行執行的)
  2. 啟動控制平臺:itstack-middleware-control,訪問:http://localhost:7397/ 成功界面如下;可以開啟/關閉驗證了!{功能還在完善}

中間件開發

以SpringBoot為基礎開發一款中間件我也是第一次,因為接觸SpringBoot也剛剛1個月左右。雖然SpringBoot已經出來挺久的了,但由于我們項目開發并不使用SpringBoot的一套東西,所以一直依賴沒有接觸。直到上個月開始考慮領域驅動設計才接觸,嗯!真的不錯,那么就開始了夯實技能、學習思想用到項目里。

按照我的產品需求,開發這么一款分布式任務的中間件,我腦袋中的模型已經存在了。另外就是需要開發過程中去探索我需要的知識工具,簡單包括;

  1. 讀取Yml自定義配置
  2. 使用zookeeper作為配置中心,這樣如果有機器宕機了就可以通過臨時節點監聽知道
  3. 通過Spring類;ApplicationContextAware, BeanPostProcessor, ApplicationListener,執行服務啟動、注解掃描、節點掛在
  4. 分布式任務統一控制臺,來管理任務

1. 工程模型

schedule-spring-boot-starter
└── src
├── main
│ ├── java
│ │ └── org.itstack.middleware.schedule
│ │ ├── annotation
│ │ │ ├── DcsScheduled.java
│ │ │ └── EnableDcsScheduling.java
│ │ ├── annotation
│ │ │ └── InstructStatus.java
│ │ ├── config
│ │ │ ├── DcsSchedulingConfiguration.java
│ │ │ ├── StarterAutoConfig.java
│ │ │ └── StarterServiceProperties.java
│ │ ├── domain
│ │ │ ├── DataCollect.java
│ │ │ ├── DcsScheduleInfo.java
│ │ │ ├── DcsServerNode.java
│ │ │ ├── ExecOrder.java
│ │ │ └── Instruct.java
│ │ ├── export
│ │ │ └── DcsScheduleResource.java
│ │ ├── service
│ │ │ ├── HeartbeatService.java
│ │ │ └── ZkCuratorServer.java
│ │ ├── task
│ │ │ ├── TaskScheduler.java
│ │ │ ├── ScheduledTask.java
│ │ │ ├── SchedulingConfig.java
│ │ │ └── SchedulingRunnable.java
│ │ ├── util
│ │ │ └── StrUtil.java
│ │ └── DoJoinPoint.java
│ └── resources
│ └── META_INF
│ └── spring.factories
└── test
└── java
└── org.itstack.demo.test
└── ApiTest.java

2. 代碼講解

  1. 篇幅較長,只講解部分重點代碼塊,如果你愿意參與到開源編寫,可以和我申請
  2. 我說過好的代碼都很騷氣,那么就從這部分入手吧

2.1 自定義注解

annotation/EnableDcsScheduling.java & 自定義注解

這個注解一堆的圈A,這些配置都是為了開始啟動執行我們的中間件;

  • Target 標識需要放到類上執行
  • Retention 注釋將由編譯器記錄在類文件中,并且在運行時由VM保留,因此可以反射地讀取它們
  • Import 引入入口資源,在程序啟動時會執行到自己定義的類中,以方便我們;初始化配置/服務、啟動任務、掛在節點
  • ComponentScan 告訴程序掃描位置
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({DcsSchedulingConfiguration.class})
@ImportAutoConfiguration({SchedulingConfig.class, CronTaskRegister.class, DoJoinPoint.class})
@ComponentScan("org.itstack.middleware.*")
public @interface EnableDcsScheduling {
}

2.2 掃描自定義注解、初始化配置/服務、啟動任務、掛在節點

config/DcsSchedulingConfiguration.java & 初始化配置/服務、啟動任務、掛在節點

  • 寫到這的時候,我們的自定義注解有了,已經寫到方法上了,那么我們怎么拿到呢?
  • 需要通過實現BeanPostProcessor.postProcessAfterInitialization,在每個bean實例化的時候進行掃描
  • 這里遇到一個有趣的問題,一個方法會得到兩次,因為有一個CGLIB給代理的,像真假美猴王一樣,幾乎一毛一樣。扒了源碼才看到,生命注解批注沒有。好那就可以判斷了!method.getDeclaredAnnotations()
  • 我們將掃描下來的任務信息匯總到Map中,當Spring初始化完成后,在執行我們中間件內容。{太早執行有點喧賓奪主了!主要人家也不讓呀,給你拋異常。}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
if (this.nonAnnotatedClasses.contains(targetClass)) return bean;
Method[] methods = ReflectionUtils.getAllDeclaredMethods(bean.getClass());
if (methods == null) return bean;
for (Method method : methods) {
DcsScheduled dcsScheduled = AnnotationUtils.findAnnotation(method, DcsScheduled.class);
if (null == dcsScheduled || 0 == method.getDeclaredAnnotations().length) continue;
List<ExecOrder> execOrderList = Constants.execOrderMap.computeIfAbsent(beanName, k -> new ArrayList<>());
ExecOrder execOrder = new ExecOrder();
execOrder.setBean(bean);
execOrder.setBeanName(beanName);
execOrder.setMethodName(method.getName());
execOrder.setDesc(dcsScheduled.desc());
execOrder.setCron(dcsScheduled.cron());
execOrder.setAutoStartup(dcsScheduled.autoStartup());
execOrderList.add(execOrder);
this.nonAnnotatedClasses.add(targetClass);
}
return bean;
}
  • 初始化服務連接zookeeper配置中心
  • 連接后將創建我們的節點以及添加監聽,這個監聽主要負責分布式消息通知,收到通知負責控制任務啟停
  • 這里包括了循環創建節點以及批量節點刪除,似乎!面試題會問
private void init_server(ApplicationContext applicationContext) {
try {
//獲取zk連接
CuratorFramework client = ZkCuratorServer.getClient(Constants.Global.zkAddress);
//節點組裝
path_root_server = StrUtil.joinStr(path_root, LINE, "server", LINE, schedulerServerId);
path_root_server_ip = StrUtil.joinStr(path_root_server, LINE, "ip", LINE, Constants.Global.ip);
//創建節點&遞歸刪除本服務IP下的舊內容
ZkCuratorServer.deletingChildrenIfNeeded(client, path_root_server_ip);
ZkCuratorServer.createNode(client, path_root_server_ip);
ZkCuratorServer.setData(client, path_root_server, schedulerServerName);
//添加節點&監聽
ZkCuratorServer.createNodeSimple(client, Constants.Global.path_root_exec);
ZkCuratorServer.addTreeCacheListener(applicationContext, client, Constants.Global.path_root_exec);
} catch (Exception e) {
logger.error("itstack middleware schedule init server error!", e);
throw new RuntimeException(e);
}
}
  • 啟動標記了True的Schedule任務
  • Scheduled默認是單線程執行的,這里擴展為多線程并行執行
private void init_task(ApplicationContext applicationContext){
CronTaskRegister cronTaskRegistrar = applicationContext.getBean("itstack-middlware-schedule-cronTaskRegister", CronTaskRegister.class);
Set<String> beanNames = Constants.execOrderMap.keySet();
for (String beanName : beanNames) {
List<ExecOrder> execOrderList = Constants.execOrderMap.get(beanName);
for (ExecOrder execOrder : execOrderList) {
if (!execOrder.getAutoStartup()) continue;
SchedulingRunnable task = new SchedulingRunnable(execOrder.getBean(), execOrder.getBeanName(), execOrder.getMethodName());
cronTaskRegistrar.addCronTask(task, execOrder.getCron());
}
}
}
  • 掛在任務節點到zookeeper掛在
  • 按照不同的場景,有些內容是掛在到虛擬機節點。{又來個面試題,虛擬節點數據怎么掛在,創建的是永久節點,那么虛擬值怎么加?}
  • path_root_server_ip_clazz_method;這個結構是:根目錄、服務、IP、類、方法
private void init_node() throws Exception {
Set<String> beanNames = Constants.execOrderMap.keySet();
for (String beanName : beanNames) {
List<ExecOrder> execOrderList = Constants.execOrderMap.get(beanName);
for (ExecOrder execOrder : execOrderList) {
String path_root_server_ip_clazz = StrUtil.joinStr(path_root_server_ip, LINE, "clazz", LINE, execOrder.getBeanName());
String path_root_server_ip_clazz_method = StrUtil.joinStr(path_root_server_ip_clazz, LINE, "method", LINE, execOrder.getMethodName());
String path_root_server_ip_clazz_method_status = StrUtil.joinStr(path_root_server_ip_clazz, LINE, "method", LINE, execOrder.getMethodName(), "/status");
//添加節點
ZkCuratorServer.createNodeSimple(client, path_root_server_ip_clazz);
ZkCuratorServer.createNodeSimple(client, path_root_server_ip_clazz_method);
ZkCuratorServer.createNodeSimple(client, path_root_server_ip_clazz_method_status);
//添加節點數據[臨時]
ZkCuratorServer.appendPersistentData(client, path_root_server_ip_clazz_method + "/value", JSON.toJSONString(execOrder));
//添加節點數據[永久]
ZkCuratorServer.setData(client, path_root_server_ip_clazz_method_status, execOrder.getAutoStartup() ? "1" : "0");
}
}
}

2.3 zookeeper控制服務

service/ZkCuratorServer.java & zk服務

  • 這里提供一個zk的方法集合,其中比較重要的方法添加監聽
  • zookeeper有一個特性是對這個監聽后,當節點內容發生變化時會收到通知,當然宕機也是收得到的,這個也就是我們后面開發災備的核心觸發點
public static void addTreeCacheListener(final ApplicationContext applicationContext, final CuratorFramework client, String path) throws Exception {
TreeCache treeCache = new TreeCache(client, path);
treeCache.start();
treeCache.getListenable().addListener((curatorFramework, event) -> {
//...
switch (event.getType()) {
case NODE_ADDED:
case NODE_UPDATED:
if (Constants.Global.ip.equals(instruct.getIp()) && Constants.Global.schedulerServerId.equals(instruct.getSchedulerServerId())) {
//執行命令
Integer status = instruct.getStatus();
switch (status) {
case 0: //停止任務
cronTaskRegistrar.removeCronTask(instruct.getBeanName() + "_" + instruct.getMethodName());
setData(client, path_root_server_ip_clazz_method_status, "0");
logger.info("itstack middleware schedule task stop {} {}", instruct.getBeanName(), instruct.getMethodName());
break;
case 1: //啟動任務
cronTaskRegistrar.addCronTask(new SchedulingRunnable(scheduleBean, instruct.getBeanName(), instruct.getMethodName()), instruct.getCron());
setData(client, path_root_server_ip_clazz_method_status, "1");
logger.info("itstack middleware schedule task start {} {}", instruct.getBeanName(), instruct.getMethodName());
break;
case 2: //刷新任務
cronTaskRegistrar.removeCronTask(instruct.getBeanName() + "_" + instruct.getMethodName());
cronTaskRegistrar.addCronTask(new SchedulingRunnable(scheduleBean, instruct.getBeanName(), instruct.getMethodName()), instruct.getCron());
setData(client, path_root_server_ip_clazz_method_status, "1");
logger.info("itstack middleware schedule task refresh {} {}", instruct.getBeanName(), instruct.getMethodName());
break;
}
}
break;
case NODE_REMOVED:
break;
default:
break;
}
});
}

2.4 并行任務注冊

  • 由于默認的SpringBoot是單線程的,所以這里改造了下,可以支持多線程并行執行
  • 包括了添加任務和刪除任務,也就是執行取消future.cancel(true)
public void addCronTask(SchedulingRunnable task, String cronExpression) {
if (null != Constants.scheduledTasks.get(task.taskId())) {
removeCronTask(task.taskId());
}
CronTask cronTask = new CronTask(task, cronExpression);
Constants.scheduledTasks.put(task.taskId(), scheduleCronTask(cronTask));
}
public void removeCronTask(String taskId) {
ScheduledTask scheduledTask = Constants.scheduledTasks.remove(taskId);
if (scheduledTask == null) return;
scheduledTask.cancel();
}

2.5 待擴展的自定義AOP

  • 我們最開始配置的掃描@ComponentScan("org.itstack.middleware.*"),主要用到這里的自定義注解,否則是掃描不到的,也就是你自定義切面失效的效果
  • 目前這里的功能并沒有擴展,基本只是打印執行耗時,后續完善的任務執行耗時監聽等,就需要這里來完善
@Pointcut("@annotation(org.itstack.middleware.schedule.annotation.DcsScheduled)")
public void aopPoint(){
}

@Around("aopPoint()")
public Object doRouter(ProceedingJoinPoint jp) throws Throwable {
long begin = System.currentTimeMillis();
Method method = getMethod(jp);
try {
return jp.proceed();
} finally {
long end = System.currentTimeMillis();
logger.info("\nitstack middleware schedule method:{}.{} take time(m):{}", jp.getTarget().getClass().getSimpleName(), method.getName(), (end - begin));
}
}

3. Jar包發布

開發完成后還是需要將Jar包發布到manven中心倉庫的,這個過程較長單獨寫了博客;發布Jar包到Maven中央倉庫(為開發開源中間件做準備)

綜上總結

  1. 要開發要實現的還很多,一個周末也干不完所有的!而且需要有想法的小猿/媛伴一起加入!
  2. 這里沒有講解分布式任務中間件控制平臺itstack-middleware-control,因為比較簡單只是使用了中間件的zk功能接口做展示和操作。
  3. 中間件開發是一件非常有意思的事情,不同于業務它更像易筋經,寺廟老僧,劍走偏鋒,馳騁縱橫,騷招滿屏。
責任編輯:武曉燕 來源: 今日頭條
相關推薦

2022-01-27 08:44:58

調度系統開源

2023-01-04 09:23:58

2023-11-07 07:56:40

2023-11-22 10:07:22

2024-11-06 18:01:15

分布式任務調度組件

2021-12-26 00:03:27

響應式編程異步

2022-09-23 13:57:11

xxl-job任務調度中間件

2025-08-05 01:45:00

XXL-JOB自動注冊運維

2019-07-19 15:51:11

框架選型分布式

2024-08-07 08:15:47

2020-09-29 19:20:05

鴻蒙

2023-06-26 00:14:28

Openjob分布式任務

2020-07-17 09:33:39

CPU內存調度

2024-08-27 09:34:24

2025-06-27 09:31:25

2024-09-09 08:11:12

2025-09-18 09:31:01

2022-03-26 17:13:22

ElasticJobxxl-job分布式

2021-11-10 16:10:18

鴻蒙HarmonyOS應用

2025-01-06 08:53:37

點贊
收藏

51CTO技術棧公眾號

99亚洲精品| 麻豆网站免费在线观看| 九九久久精品视频| 久久91亚洲精品中文字幕奶水 | 久久一二三四| 日韩中文理论片| 欧美图片自拍偷拍| 欧美私密网站| 亚洲欧洲日本在线| 国产乱码精品一区二区三区中文 | 5566中文字幕| av成人app永久免费| 欧美日韩国产中文字幕 | 精品麻豆一区二区三区| 国产成人丝袜美腿| 国产精品成人一区二区| 欧美片一区二区| 精品日韩在线| 精品国产99国产精品| 久久久久久久片| 男女在线观看视频| 国产精品理论在线观看| 久久国产精品久久| 国内老熟妇对白xxxxhd| 日韩精品1区2区3区| 欧美极品欧美精品欧美视频 | 国产精品成人播放| 91av在线免费视频| 午夜日韩视频| 伊人伊成久久人综合网站| 国产免费一区二区三区香蕉精| 可以免费在线看黄的网站| 久久大胆人体| 亚洲欧美激情插| 午夜久久资源| 欧美老女人性开放| aaa欧美色吧激情视频| 亚洲永久在线观看| 91在线精品入口| 日韩高清电影一区| 91超碰中文字幕久久精品| 性色av无码久久一区二区三区| 精品一二三区| 亚洲天堂影视av| 9.1成人看片| 国产福利资源一区| 欧美一区二区国产| 两性午夜免费视频| 日韩精品一页| 欧美日韩一区二区三区视频 | 成人无码精品1区2区3区免费看| 加勒比视频一区| 日韩精品一区二区三区四区| 免费黄频在线观看| 精品一区二区三区中文字幕视频| 欧美中文字幕一区二区三区亚洲| 免费裸体美女网站| 成年美女黄网站色大片不卡| 粉嫩老牛aⅴ一区二区三区| 国产精品久久久久久久久电影网| xvideos国产在线视频| 国产精品第13页| gogogo免费高清日本写真| 生活片a∨在线观看| 中文字幕欧美一区| 麻豆一区二区三区在线观看| 天使と恶魔の榨精在线播放| 亚洲一区在线播放| 国产精品无码一区二区在线| 久久嫩草捆绑紧缚| 精品中文字幕一区二区三区av| 亚洲国产一区自拍| 99re久久精品国产| 黄色录像二级片| 四虎在线免费看| 成人精品国产免费网站| 国产欧美韩日| 欧美美女搞黄| 国产精品无码永久免费888| 日韩精品久久久| 尤物在线视频| 亚洲欧美视频一区| 国产美女在线一区| 成人免费看黄| 欧美另类变人与禽xxxxx| 在线观看欧美一区二区| 超碰97久久国产精品牛牛| 亚洲国产精品久久| 成年人免费观看视频网站 | 激情文学综合插| 91嫩草国产在线观看| 亚洲av成人精品毛片| 国产日韩亚洲欧美综合| 性做爰过程免费播放| 51精品在线| 亚洲综合成人在线| 久久人妻无码一区二区| 正在播放日韩精品| 91精品国产手机| 日本丰满少妇裸体自慰| 欧美疯狂party性派对| 欧美激情喷水视频| 最近中文字幕在线免费观看| 国产成人午夜电影网| 奇米888一区二区三区| 精品麻豆一区二区三区| 一本大道久久a久久综合婷婷| 在线免费看污网站| 西野翔中文久久精品字幕| 日日骚av一区| 成人精品在线看| 精久久久久久久久久久| 久久偷窥视频| 成人午夜在线影视| 欧美制服丝袜第一页| 午夜福利三级理论电影| 97人妻一区二区精品免费视频| 午夜一区不卡| 亚洲free嫩bbb| 国产69久久| 图片区小说区区亚洲影院| 免费一区二区三区在线观看| 欧美大胆视频| 九九热这里只有精品免费看| 最近中文字幕免费观看| www激情久久| 久久精品无码中文字幕| 亚洲欧美一级| 在线观看欧美日韩国产| 日韩欧美一级视频| 成人av动漫在线| 99re6这里有精品热视频| 久久福利在线| 国产一区二区欧美日韩| 韩国av中文字幕| 成人免费观看男女羞羞视频| 色一情一乱一乱一区91| 欧美性www| 中文字幕在线视频日韩| 波多野结衣电车痴汉| 91啪亚洲精品| 国产中文字幕免费观看| 加勒比色综合久久久久久久久| 欧美裸身视频免费观看| 99久久精品无免国产免费| 亚洲人成人一区二区在线观看| 性欧美极品xxxx欧美一区二区| 天天躁日日躁成人字幕aⅴ| 久久久久久久香蕉网| 高清乱码毛片入口| 亚洲一级二级三级在线免费观看| 又黄又爽又色的视频| 在线精品视频在线观看高清| 91色p视频在线| 国产在线高清理伦片a| 欧美精品一二三区| 粉嫩av性色av蜜臀av网站| 国内欧美视频一区二区| 国产一区一区三区| 日韩精品视频在线看| 欧美xxxx14xxxxx性爽| www.成人在线观看| 亚洲va欧美va人人爽| 国产高清成人久久| 久久久久国产一区二区| 精品视频在线播放| 三区视频在线观看| 亚洲综合色站| 国产精品久久国产精品| 国模精品视频| 国产亚洲激情在线| 97人妻精品一区二区三区视频| 亚洲柠檬福利资源导航| 少妇献身老头系列| 国产人成精品一区二区三| 麻豆成人av| 欧美成人家庭影院| 色与欲影视天天看综合网| 五月婷婷久久久| 欧美特黄级在线| 日本成人免费视频| 极品销魂美女一区二区三区| 欧美乱做爰xxxⅹ久久久| 好吊妞视频这里有精品| 欧美怡春院一区二区三区| 福利视频在线导航| 日韩一卡二卡三卡四卡| 久久久午夜影院| 中文久久乱码一区二区| 久久久久亚洲av无码网站| 亚洲欧美日韩在线观看a三区| 日日夜夜精品网站| 伊人精品综合| 国产成人精品日本亚洲专区61| 免费看a在线观看| 亚洲成人aaa| 亚洲无码久久久久久久| 伊人色综合久久天天| 可以直接看的无码av| 韩国成人精品a∨在线观看| 成年人午夜免费视频| 欧美一区电影| 国产欧美韩日| 国产亚洲久久| 国产精品99一区| 青青草原av在线| 少妇高潮久久77777| 人妻丰满熟妇av无码区hd| 欧美视频一区二区三区四区 | 亚洲欧美在线专区| 欧美成人dvd在线视频| 国产视频一区二| 国产精品劲爆视频| www视频在线观看| 久青草国产97香蕉在线视频| 免费国产在线视频| 精品国产免费一区二区三区四区| 日本三级福利片| 91成人app| 日本欧美国产在线| av资源一区| 欧美成人午夜剧场免费观看| av电影在线观看一区二区三区| 亚洲国产精品久久久久秋霞蜜臀| 99久久久国产精品无码免费| 欧美性受xxxx| 国产又大又黄又粗| 亚洲一级二级在线| 欧美成人综合色| 亚洲欧美在线视频| 蜜桃av免费观看| 国产视频一区在线播放| 亚洲黄色免费在线观看| 成人免费高清在线| 天堂av.com| 久久国产精品色| 天天爽人人爽夜夜爽| 久久综合导航| 亚洲自偷自拍熟女另类| 亚洲激情不卡| 国产美女在线一区| 国产精品a级| 日韩精品手机在线观看| 欧美a级片网站| 五月天av影院| 国产精品成久久久久| 97超级碰碰碰| missav|免费高清av在线看| 欧美丰满老妇厨房牲生活| 超碰免费在线播放| 美女国内精品自产拍在线播放| 免费黄网站在线播放| 久久人人爽人人爽人人片亚洲| 五月婷婷在线观看| 日韩最新av在线| 麻豆网站在线| 久久精品国产2020观看福利| 麻豆av在线导航| 美日韩精品视频免费看| 91小视频xxxx网站在线| 欧美精品第一页在线播放| 国精一区二区三区| 97色在线观看免费视频| 亚洲色图官网| 国产精品wwwwww| 久久久国产精品网站| 91亚洲va在线va天堂va国| 日韩一二三区| 国产一区二区不卡视频| 蜜桃成人av| 亚洲精品成人三区| 欧美1区2区| 狠狠爱免费视频| 美女在线一区二区| 婷婷中文字幕在线观看| 国产精品一区二区久激情瑜伽| 波多野结衣三级视频| 97久久超碰国产精品| 国产三级黄色片| 亚洲乱码国产乱码精品精的特点 | 亚洲av成人片无码| 91天堂素人约啪| 中文字幕伦理片| 一区二区三区在线视频播放| 日本少妇bbwbbw精品| 日韩欧美亚洲成人| ,亚洲人成毛片在线播放| 欧美日韩中文一区| 亚洲精品久久久久久久久久久久久久 | 成人精品一区二区三区四区| 中文字幕乱码在线| 日本一区免费视频| 亚洲av成人精品一区二区三区| 久久嫩草精品久久久精品一| 99成人在线观看| 亚洲欧美视频| 女人天堂av手机在线| 蜜桃视频在线观看一区| 日韩视频在线观看一区二区三区| 99精品欧美一区| 午夜国产小视频| 久久国产精品久久久久久电车| 成人在线观看黄| 寂寞少妇一区二区三区| 性欧美成人播放77777| 成人av电影在线观看| 国产精品麻豆免费版现看视频| 久久成人精品| 国产一级二级av| 久久久精品免费免费| 久久中文免费视频| 国产精品免费av| 人妻换人妻仑乱| 成人18精品视频| 一级黄色高清视频| 99久久.com| 成人高清视频观看www| 色三级在线观看| 一级特黄大欧美久久久| 女人扒开双腿让男人捅| 色天天综合网| 国产99在线|中文| 国产三级国产精品国产国在线观看| 经典一区二区三区| 91成人国产在线观看| 精品成人一区二区三区免费视频| 国产精品女同一区二区三区| 成人污网站在线观看| 午夜视频免费看| 色噜噜狠狠狠综合曰曰曰88av| 中文字幕观看在线| 亚洲欧美日韩国产手机在线| 免费无码一区二区三区| 爽好久久久欧美精品| 一区二区在线不卡| 免费视频成人| 久久婷婷国产麻豆91天堂| 国产亚洲欧美精品久久久www| 欧美暴力喷水在线| 性欧美极品xxxx欧美一区二区| 久久日韩粉嫩一区二区三区| 日本少妇做爰全过程毛片| 日韩手机在线导航| 在线免费av导航| 91亚洲精品在线观看| 91精品婷婷色在线观看| 国产欧美一区二| 国产精品久久久久久一区二区三区 | 97婷婷涩涩精品一区| 风间由美中文字幕在线看视频国产欧美| 免费看黄色a级片| 国产精品一区二区视频| 久久久久久久九九九九| 亚洲成色777777女色窝| av在线最新| 欧美精品七区| 日本成人在线视频网站| 91香蕉视频污在线观看| 91精品国产一区二区人妖| 四虎亚洲成人| 狠狠色综合色区| 快she精品国产999| 国产精品久久免费观看| 欧美理论片在线| 欧美人与性动交α欧美精品图片| 国产精品视频500部| 中文在线不卡| 亚洲成人黄色av| 91精品国产综合久久久久久久久久 | 国产黄色片在线| 9191国产精品| 视频在线这里都是精品| 精品无码久久久久国产| 日韩电影一区二区三区四区| 老司机福利在线观看| 欧美一区二区三区色| 丰满的护士2在线观看高清| 久久久神马电影| 日韩av一区二区三区四区| 少妇高潮一区二区三区喷水| 欧美一三区三区四区免费在线看| a视频在线播放| 久久国产精品久久精品国产| 麻豆精品视频在线观看| 东方av正在进入| 精品亚洲精品福利线在观看| 欧美aaa视频| 国产成人生活片| 久久影院午夜论| 国产三级视频在线播放| 久久久久久久久久久免费精品| 国产精品中文字幕亚洲欧美| 免费av不卡在线| 欧美日韩国产一中文字不卡| 91在线品视觉盛宴免费| 成人资源av| 日韩av中文字幕一区二区 | 欧美日韩国产色| 激情成人四房播| 韩国精品一区二区三区六区色诱|