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

Spring Boot 啟動優(yōu)化實踐

開發(fā)
本文系統(tǒng)性分析并優(yōu)化了一個Spring Boot項目啟動耗時高達 280 秒的問題。通過識別瓶頸、優(yōu)化分庫分表加載邏輯、異步初始化耗時任務(wù)等手段,最終將啟動耗時縮短至 159 秒,提升近 50%。文章涵蓋啟動流程分析、性能熱點識別、異步初始化設(shè)計等關(guān)鍵技術(shù)細節(jié),適用于大型Spring Boot項目的性能優(yōu)化參考。

一、前言

隨著業(yè)務(wù)的發(fā)展,筆者項目對應(yīng)的Spring Boot工程的依賴越來越多。隨著依賴數(shù)量的增長,Spring 容器需要加載更多組件、解析復(fù)雜依賴并執(zhí)行自動裝配,導(dǎo)致項目啟動時間顯著增長。在日常開發(fā)或測試過程中,一旦因為配置變更或者其他熱部署不生效的變更時,項目重啟就需要等待很長的時間影響代碼的交付。加快Spring項目的啟動可以更好的投入項目中,提升開發(fā)效率。

整體環(huán)境介紹:

  • Spring版本:4.3.22
  • Spring Boot版本:1.5.19
  • CPU:i5-9500
  • 內(nèi)存:24GB
  • 優(yōu)化前啟動耗時:280秒

二、Spring Boot項目啟動流程介紹

Spring Boot項目主要啟動流程都在org.spring-framework.boot.SpringApplication#run(java.lang.String...)方法中:

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    // Spring上下文
    ConfigurableApplicationContext context = null;
    FailureAnalyzers analyzers = null;
    configureHeadlessProperty();
    // 初始化SpringApplicationRunListener監(jiān)聽器
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                args);
        // 環(huán)境準備
        ConfigurableEnvironment environment = prepareEnvironment(listeners,
                applicationArguments);
         // 打印banner
        Banner printedBanner = printBanner(environment);
        // 創(chuàng)建上下文
        context = createApplicationContext();
        analyzers = new FailureAnalyzers(context);
        // 容器初始化
        prepareContext(context, environment, listeners, applicationArguments,
                printedBanner);
        // 刷新容器內(nèi)容
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        // 結(jié)束監(jiān)聽廣播
        listeners.finished(context, null);
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass)
                    .logStarted(getApplicationLog(), stopWatch);
        }
        return context;
    } catch (Throwable ex) {
        handleRunFailure(context, listeners, analyzers, ex);
        throw new IllegalStateException(ex);
    }
}

可以看到在啟動流程中,監(jiān)聽器應(yīng)用在了應(yīng)用的多個生命周期中。并且Spring Boot中也預(yù)留了針對listener的擴展點。我們可以借此實現(xiàn)一個自己的擴展點去監(jiān)聽Spring Boot的每個階段的啟動耗時,實現(xiàn)如下:

@Slf4j
public class MySpringApplicationRunListener implements SpringApplicationRunListener{
    private Long startTime;
    public MySpringApplicationRunListener(SpringApplication application, String[] args){
    }
    @Override
    public void starting(){
        startTime = System.currentTimeMillis();
        log.info("MySpringListener啟動開始 {}", LocalTime.now());
    }
    @Override
    public void environmentPrepared(ConfigurableEnvironment environment){
        log.info("MySpringListener環(huán)境準備 準備耗時:{}毫秒", (System.currentTimeMillis() - startTime));
        startTime = System.currentTimeMillis();
    }
    @Override
    public void contextPrepared(ConfigurableApplicationContext context){
        log.info("MySpringListener上下文準備 耗時:{}毫秒", (System.currentTimeMillis() - startTime));
        startTime = System.currentTimeMillis();
    }
    @Override
    public void contextLoaded(ConfigurableApplicationContext context){
        log.info("MySpringListener上下文載入 耗時:{}毫秒", (System.currentTimeMillis() - startTime));
        startTime = System.currentTimeMillis();
    }
   @Override
   public void finished(ConfigurableApplicationContext context, Throwable exception){
        log.info("MySpringListener結(jié)束 耗時:{}毫秒", (System.currentTimeMillis() - startTime));
        startTime = System.currentTimeMillis();
    }
}

接著還需要在classpath/META-INF目錄下新建spring.factories文件,并添加如下文件內(nèi)容:

org.springframework.boot.SpringApplicationRunListener=com.vivo.internet.gameactivity.api.web.MySpringApplicationRunListener

至此,借助Listener機制,我們能夠追蹤Spring Boot啟動各階段的耗時分布,為后續(xù)性能優(yōu)化提供數(shù)據(jù)支撐。

contextLoaded事件是在run方法中的prepareContext()結(jié)束時調(diào)用的,因此contextLoaded事件和finished事件之間僅存在兩個語句:refreshContext(context)和afterRefresh(context,applicationArguements)消耗了285秒的時間,調(diào)試一下就能發(fā)現(xiàn)主要耗時在refreshContext()中。

三、AbstractApplicationContext#refresh

refreshContext()最終調(diào)用到org.spring-framework.context.support.AbstractApplicationContext#refresh方法中,這個方法主要是beanFactory的預(yù)準備、對beanFactory完成創(chuàng)建并進行后置處理、向容器添加bean并且給bean添加屬性、實例化所有bean。通過調(diào)試發(fā)現(xiàn),finishBeanFactoryInitialization(beanFactory) 方法耗時最久。該方法負責實例化容器中所有的單例 Bean,是啟動性能的關(guān)鍵影響點。

四、找出實例化耗時的Bean

Spring Boot也是利用的Spring的加載流程。在Spring中可以實現(xiàn)InstantiationAwareBeanPost-Processor接口去在Bean的實例化和初始化的過程中加入擴展點。因此我們可以實現(xiàn)該接口并添加自己的擴展點找到處理耗時的Bean。

@Service
public class TimeCostCalBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    private Map<String, Long> costMap = Maps.newConcurrentMap();


    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (!costMap.containsKey(beanName)) {
            costMap.put(beanName, System.currentTimeMillis());
        }
        return null;
    }
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    }
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
         if (costMap.containsKey(beanName)) {
            Long start = costMap.get(beanName);
            long cost = System.currentTimeMillis() - start;
            // 只打印耗時長的bean
             if (cost > 5000) {
                System.out.println("bean: " + beanName + "\ttime: " + cost + "ms");
            }
        }
         return bean;
    }
}

具體原理就是在Bean開始實例化之前記錄時間,在Bean初始化完成后記錄結(jié)束時間,打印實例化到初始化的時間差獲得Bean的加載總體耗時。結(jié)果如圖:

可以看到有許多耗時在10秒以上的類,接下來可以針對性的做優(yōu)化。值得注意的是,統(tǒng)計方式為單點耗時計算,未考慮依賴鏈上下文對整體加載順序的影響,實際優(yōu)化還需結(jié)合依賴關(guān)系分析。

五、singletonDataSource

@Bean(name = "singletonDataSource")
public DataSource singletonDataSource(DefaultDataSourceWrapper dataSourceWrapper) throws SQLException {
    //先初始化連接
    dataSourceWrapper.getMaster().init();
    //構(gòu)建分庫分表數(shù)據(jù)源
    String dataSource0 = "ds0";
    Map<String, DataSource> dataSourceMap = new HashMap<>();
    dataSourceMap.put(dataSource0, dataSourceWrapper.getMaster());
    //分庫分表數(shù)據(jù)源
    DataSource shardingDataSource = ShardingDataSourceFactory.createDataSource
    (dataSourceMap,shardingRuleConfiguration, prop);
    return shardingDataSource;    
    }

singletonDataSource是一個分庫分表的數(shù)據(jù)源,連接池采用的是Druid,分庫分表組件采用的是公司內(nèi)部優(yōu)化后的中間件。通過簡單調(diào)試代碼發(fā)現(xiàn),整個Bean耗時的過程發(fā)生在createDataSource方法,該方法中會調(diào)用createMetaData方法去獲取數(shù)據(jù)表的元數(shù)據(jù),最終運行到loadDefaultTables方法。該方法如下圖,會遍歷數(shù)據(jù)庫中所有的表。因此數(shù)據(jù)庫中表越多,整體就越耗時。

筆者的測試環(huán)境數(shù)據(jù)庫中有很多的分表,這些分表為了和線上保持一致,分表的數(shù)量都和線上是一樣的。

因此在測試環(huán)境啟動時,為了加載這些分表會更加的耗時。可通過將分表數(shù)量配置化,使測試環(huán)境在不影響功能驗證的前提下減少分表數(shù)量,從而加快啟動速度。

六、初始化異步

activityServiceImpl啟動中,主要會進行活動信息的查詢初始化,這是一個耗時的操作。類似同樣的操作在工程的其他類中也存在。

@Service
public class ActivityServiceImpl implements ActivityService, InitializingBean{
     // 省略無關(guān)代碼
     @Override
     public void afterPropertiesSet() throws Exception {
        initActivity();
    }
     // 省略無關(guān)代碼
}

可以通過將afterPropertiesSet()異步化的方式加速項目的啟動。

觀察Spring源碼可以注意到afterPropertiesSet方法是在AbstractAutowireCapableBeanFactory#invokeInitMethods中調(diào)用的。在這個方法中,不光處理了afterPropertiesSet方法,也處理了init-method。

因此我們可以寫一個自己的BeanFactory繼承AbstractAutowireCapableBeanFactory,將invokeInitMethods方法進行異步化重寫。考慮到AbstractAutowireCapableBeanFactory是個抽象類,有額外的抽象方法需要實現(xiàn),因此繼承該抽象類的子類DefaultListableBeanFactory。具體實現(xiàn)代碼如下:

public class AsyncInitListableBeanFactory extends DefaultListableBeanFactory{
     public AsyncInitBeanFactory(ConfigurableListableBeanFactory beanFactory){
         super(beanFactory);
    }
     @Override
     protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)throws Throwable {
        if (beanName.equals("activityServiceImpl")) {
            AsyncTaskExecutor.submitTask(() -> {
                try {
                      super.invokeInitMethods(beanName, bean, mbd);
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            });
        } else {
              super.invokeInitMethods(beanName, bean, mbd);
        }
    }
}

又因為Spring在refreshContext()方法之前的prepareContext()發(fā)放中針對initialize方法提供了接口擴展(applyInitializers())。因此我們可以通過實現(xiàn)該接口并將我們的新的BeanFactory通過反射的方式更新到Spring的初始化流程之前。

public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
     /**
     * Initialize the given application context.
     * @param applicationContext the application to configure
     */
    void initialize(C applicationContext);


}

改造后的代碼如下,新增AsyncAccelerate-Initializer類實現(xiàn)ApplicationContextInitializer接口:

public class AsyncBeanFactoryInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @SneakyThrows
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext){
        if (applicationContext instanceof GenericApplicationContext) {
            AsyncInitListableBeanFactory beanFactory = new AsyncInitListableBeanFactory(applicationContext.getBeanFactory());
            Field field = GenericApplicationContext.class.getDeclaredField("beanFactory");
            field.setAccessible(true);
            field.set(applicationContext, beanFactory);
        }
    }
}
public class AsyncBeanInitExecutor{
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final AtomicReference<ThreadPoolExecutor> THREAD_POOL_REF = new AtomicReference<>();
    private static final List<Future<?>> FUTURES = new ArrayList<>();
     /**
      * 創(chuàng)建線程池實例
      */
     private static ThreadPoolExecutor createThreadPoolExecutor(){
         int poolSize = CPU_COUNT + 1;
         return new ThreadPoolExecutor(poolSize, poolSize, 50L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
    /**
     * 確保線程池已初始化(線程安全)
     */
     private static void ensureThreadPoolExists(){
         if (THREAD_POOL_REF.get() != null) {
              return;
        }
        ThreadPoolExecutor executor = createThreadPoolExecutor();
         if (!THREAD_POOL_REF.compareAndSet(null, executor)) {
            executor.shutdown(); // 另一線程已初始化成功
        }
    }
    /**
     * 提交異步初始化任務(wù)
     *
     * @param task 初始化任務(wù)
     * @return 提交后的 Future 對象
     */
    public static Future<?> submitInitTask(Runnable task) {
        ensureThreadPoolExists();
        Future<?> future = THREAD_POOL_REF.get().submit(task);
        FUTURES.add(future);
        return future;
    }
    /**
     * 等待所有初始化任務(wù)完成并釋放資源
     */
    public static void waitForInitTasks(){
        try {
            for (Future<?> future : FUTURES) {
                future.get();
            }
        } catch (Exception ex) {
            throw new RuntimeException("Async init task failed", ex);
        } finally {
            FUTURES.clear();
            shutdownThreadPool();
        }
    }
     /**
     * 關(guān)閉線程池并重置引用
     */
     private static void shutdownThreadPool(){
        ThreadPoolExecutor executor = THREAD_POOL_REF.getAndSet(null);
         if (executor != null) {
            executor.shutdown();
        }
    }
}

實現(xiàn)類后,還需要在META-INF/spring.factories下新增說明org.springframework.context.Applicatinotallow=com.xxx.AsyncAccelerateInitializer,這樣這個類才能真正生效。

這樣異步化以后還有一個點需要注意,如果該初始化方法執(zhí)行耗時很長,那么會存在Spring容器已經(jīng)啟動完成,但是異步初始化任務(wù)沒執(zhí)行完的情況,可能會導(dǎo)致空指針等異常。為了避免這種問題的發(fā)生,還要借助于Spring容器啟動中finishRefresh()方法,監(jiān)聽對應(yīng)事件,確保異步任務(wù)執(zhí)行完成之后,再啟動容器。

public class AsyncInitCompletionListener implements ApplicationListener<ContextRefreshedEvent>, ApplicationContextAware, PriorityOrdered{
    private ApplicationContext currentContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
         this.currentContext = applicationContext;
    }
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event){
        if (event.getApplicationContext() == currentContext) {
            AsyncBeanInitExecutor.waitForInitTasks();
        }
    }
    @Override
    public int getOrder(){
         return Ordered.HIGHEST_PRECEDENCE;
    }
}

七、總結(jié)

啟動優(yōu)化后的項目實際測試結(jié)果如下:

通過異步化初始化和分庫分表加載優(yōu)化,項目啟動時間從 280 秒縮短至 159 秒,提升約 50%。這對于提升日常開發(fā)效率、加快測試與聯(lián)調(diào)流程具有重要意義。

責任編輯:龐桂玉 來源: vivo互聯(lián)網(wǎng)技術(shù)
相關(guān)推薦

2023-09-27 08:14:56

2017-01-23 21:05:00

AndroidApp啟動優(yōu)化

2024-05-31 14:06:55

SpringCDSGraalVM

2023-06-02 16:24:46

SpringBootSSM

2024-12-16 08:10:00

Spring開發(fā)

2022-03-29 13:27:22

Android優(yōu)化APP

2024-12-25 16:01:01

2024-11-21 14:42:31

2024-11-28 09:43:04

2024-07-26 07:59:25

2024-12-03 11:12:47

2017-03-06 15:43:33

Springboot啟動

2022-09-02 08:41:20

Spring項目微服務(wù)

2019-04-28 09:00:15

開發(fā)者技能工具

2023-09-22 10:12:57

2019-07-24 10:34:28

Spring Boot項目模板

2021-09-02 10:10:59

技術(shù)VS Code實踐

2024-09-09 05:30:00

數(shù)據(jù)庫Spring

2022-10-11 14:58:00

性能優(yōu)化Java

2020-02-26 15:35:17

Spring Boot項目優(yōu)化JVM調(diào)優(yōu)
點贊
收藏

51CTO技術(shù)棧公眾號

亚洲视频国产| 亚洲精品免费在线观看视频| 亚洲**毛片| 亚洲视频在线一区二区| 国产欧美日韩中文字幕| 老司机福利在线观看| 日韩精品第二页| 一色桃子久久精品亚洲| 国产欧美精品日韩精品| 午夜激情视频在线播放| 91麻豆精品国产综合久久久| 亚洲人成精品久久久久久| 亚洲影院在线看| 亚洲精品在线观看av| 久久久久观看| 亚洲成人免费av| 美脚丝袜一区二区三区在线观看| 欧美成人一区二区三区四区| 日韩av久操| 欧美一二区视频| www.在线观看av| 日韩av视屏| 老司机午夜精品| 久久精品国产亚洲一区二区| 欧美丰满熟妇bbb久久久| 青春草视频在线观看| 91污片在线观看| 亚州av一区二区| 久久婷婷五月综合| 久久伊人精品| 欧美性xxxx18| 麻豆md0077饥渴少妇| 欧美自拍偷拍一区二区| 日韩电影在线免费看| 久久精品亚洲精品| 中国一级特黄录像播放| 国产免费不卡| 亚洲少妇中出一区| 美女主播视频一区| 国产草草影院ccyycom| 国产精品毛片| 久久精品亚洲国产| 久久精品国产亚洲av久| 精品一区二区三区亚洲| 色综合久久88色综合天天6| 91制片厂免费观看| 欧美女子与性| 国产福利不卡视频| 91精品91久久久久久| 精品少妇一区二区三区密爱| 999久久久久久久久6666| 欧美日韩视频在线第一区| 狠狠干 狠狠操| 日本在线观看免费| 色中色在线视频| 日韩欧美一区二区在线观看| 图片区小说区国产精品视频| 久久av网址| www.蜜臀av| 一区二区三区 欧美| 国产精品高潮呻吟久久av野狼| 欧美性20hd另类| 91免费看片在线| 欧美日韩综合一区二区三区| 午夜久久99| 中文精品99久久国产香蕉| 屁屁影院国产第一页| 久久免费福利| 欧美精品日日鲁夜夜添| av免费网站观看| 国产剧情av在线播放| 中文字幕日韩av资源站| 欧美一区二区三区四区在线观看地址 | 欧美中文字幕视频在线观看| 欧美三级在线免费观看| 国产精品97| 中文字幕亚洲二区| 日本黄色激情视频| 欧美一区二区三区激情视频| 亚洲人成电影网站色…| av无码一区二区三区| 国产不卡精品在线| 欧美日韩精品一区视频| 国产一伦一伦一伦| 精品三级在线| 欧美精三区欧美精三区| 天堂网在线免费观看| yiren22亚洲综合| 欧美日韩一区二区在线播放| 国产91xxx| 1区2区3区在线| 亚洲电影一级黄| 成 年 人 黄 色 大 片大 全| 超级碰碰不卡在线视频| 亚洲国产美国国产综合一区二区| 亚洲 欧美 综合 另类 中字| 波多野结衣中文在线| 调教+趴+乳夹+国产+精品| 高清无码视频直接看| 国产美女情趣调教h一区二区| 亚洲综合免费观看高清完整版在线 | 午夜精品久久久久久久爽| 国产成人综合亚洲网站| 国产日本一区二区三区| 无码国精品一区二区免费蜜桃| 99久久99精品久久久久久 | 都市激情亚洲欧美| 亚洲毛片一区二区| 给我看免费高清在线观看| 精品福利久久久| 日韩一区二区三区在线播放| 九九视频免费在线观看| 亚洲综合国产| 国产免费一区二区三区香蕉精| 国产精品一区二区黑人巨大| 国产成人精品www牛牛影视| 精品国产一区二区三区四区精华| 黄色的视频在线免费观看| 亚洲欧美一区二区久久| 日韩精品一区二区三区色欲av| 成人在线精品| 亚洲日本中文字幕| 懂色av.com| 激情综合色综合久久综合| 精品无码久久久久国产| av在线下载| 91久久精品网| 久久久高清视频| 999久久久亚洲| 欧美综合第一页| 亚洲av无码乱码国产精品久久| 国产情人综合久久777777| 人人妻人人澡人人爽欧美一区双 | 性亚洲最疯狂xxxx高清| 国产xxxx在线观看| 国产精品水嫩水嫩| 国产精品欧美激情在线观看| 亚洲精品v亚洲精品v日韩精品| 永久555www成人免费| 1级黄色大片儿| 国产精品羞羞答答xxdd| 亚洲精品一卡二卡三卡四卡| 在线看片福利| 亚洲国产精品一区二区久| 印度午夜性春猛xxx交| 免费成人在线网站| 欧美一区二区在线| 香蕉成人av| 日韩精品在线看| 五月天综合在线| 国产成人一区二区精品非洲| 中文字幕不卡每日更新1区2区| 日韩电影免费观看高清完整版| 亚洲激情视频在线播放| 国产精品.www| 成人听书哪个软件好| 国产成人亚洲综合无码| 国产成人免费视频网站视频社区| 中文在线资源观看视频网站免费不卡| 午夜精品免费观看| 国产三级久久久| 欧美一级黄色影院| 欧美日韩黑人| 国产精品男人的天堂| 国产1区2区3区在线| 91成人免费在线视频| 超碰97人人干| 三级欧美在线一区| 偷拍视频一区二区| 欧美亚洲综合视频| 另类色图亚洲色图| 亚洲国产成人一区二区| 亚洲成av人影院| 欧美熟妇精品黑人巨大一二三区| 欧美亚洲视频| 亚洲欧洲精品一区| 国产成人免费视频网站视频社区 | 亚洲精品精选| 狠狠爱一区二区三区| 天堂av在线网| 国产香蕉97碰碰久久人人| 亚洲图片视频小说| 亚洲激情图片小说视频| av2014天堂网| 日日摸夜夜添夜夜添亚洲女人| 婷婷亚洲婷婷综合色香五月| 亚洲人体在线| 欧美激情综合色综合啪啪五月| 人妻精品无码一区二区| 日韩欧美成人免费视频| 国产精品无码无卡无需播放器| 国内精品第一页| 日韩精品一区在线视频| 久久99性xxx老妇胖精品| 成人av在线亚洲| 国产盗摄在线视频网站| 亚洲色图17p| 成人黄色三级视频| 亚洲图片激情小说| 欧美xxxx×黑人性爽| 日韩av高清在线观看| 好色先生视频污| 欧美在线关看| 国产一区视频在线| 国产极品在线观看| 俺去了亚洲欧美日韩| 少妇喷水在线观看| 欧美日韩一区二区三区免费看| 久久黄色免费网站| 国产女主播视频一区二区| 国产精品99久久久精品无码| 香蕉成人久久| 青草全福视在线| 日韩欧美黄色| 亚洲自拍偷拍第一页| 午夜精品成人av| 久久久久久久999精品视频| yiren22综合网成人| 国产精品久久久久久久小唯西川| 成人影欧美片| 亚洲无限av看| 深爱五月激情五月| 在线不卡的av| 成人免费视频国产免费| 亚洲一二三级电影| 日本激情视频一区二区三区| 91免费精品国自产拍在线不卡| 久久久久xxxx| 久久一二三区| av高清在线免费观看| 亚洲先锋影音| 神马影院一区二区| 香蕉久久精品| 国产亚洲一区二区三区在线播放| www.久久草.com| 国产精品久久久久久久7电影| wwww在线观看免费视频| 久久精品视频亚洲| 亚洲搞黄视频| 一区二区三区视频在线| 日韩精品一二| 亚洲福利视频网| 国内精品久久久久久久久久| 欧美精选一区二区| 亚洲字幕av一区二区三区四区| 欧美性生活大片免费观看网址| 久久久久黄色片| 亚洲黄一区二区三区| 永久免费看片直接| 国产精品久久久久久久久免费樱桃| 性欧美精品中出| 久久精品亚洲一区二区三区浴池| 黄色片视频免费观看| 成人精品鲁一区一区二区| 国产又黄又嫩又滑又白| 国产主播一区二区| 亚洲无在线观看| 精品一区二区久久久| 伊人网在线综合| 精品一区二区三区影院在线午夜| 日韩大片一区二区| 麻豆精品视频在线观看视频| 在线观看亚洲色图| 精品在线视频一区| 欧美视频亚洲图片| 国产精品主播直播| 国产日韩视频一区| 99re这里只有精品6| 添女人荫蒂视频| 91欧美激情一区二区三区成人| 人妻少妇精品视频一区二区三区| 久久在线观看免费| 日韩毛片无码永久免费看| 国产精品乱码人人做人人爱| 亚洲少妇xxx| 亚洲激情av在线| 日韩xxx高潮hd| 色婷婷一区二区| 亚洲一卡二卡在线| 欧美一级免费观看| 人妻精品无码一区二区| 亚洲日韩中文字幕| 黄色成人在线观看| 久久久久久午夜| 韩国成人漫画| 成人激情在线播放| 国产精品xxx在线观看| 日韩av影视| 一二三区不卡| 欧美日韩精品在线一区二区| 视频在线观看国产精品| 91视频福利网| 91老司机福利 在线| 特级西西人体高清大胆| 亚洲一本大道在线| 日韩熟女一区二区| 欧美一区二区美女| 暖暖视频在线免费观看| 中文字幕日韩视频| 青春草在线免费视频| 国产精品成熟老女人| 91精品丝袜国产高跟在线| 欧美日韩高清在线一区| 中国精品18videos性欧美| 看av免费毛片手机播放| 精品亚洲欧美一区| 三上悠亚ssⅰn939无码播放| 亚洲视频香蕉人妖| 无码人妻精品一区二区蜜桃色欲| 91超碰这里只有精品国产| 香蕉视频网站在线| 久久亚洲一区二区三区四区五区高| 成人免费网站观看| 成人网在线观看| 亚洲区小说区图片区qvod| 7777在线视频| 日韩国产精品大片| 亚洲精品第二页| 综合欧美亚洲日本| 日日夜夜狠狠操| 亚洲黄在线观看| 性欧美ⅴideo另类hd| 国产精品久久久久久久久男 | 人人做人人澡人人爽欧美| 久久伊人影院| 正义之心1992免费观看全集完整版| 国产精品一页| 美女黄色一级视频| 玉足女爽爽91| 136福利视频导航| 亚洲日韩第一页| 中文在线аv在线| 国产久一道中文一区| 亚洲欧美综合国产精品一区| 一本色道久久亚洲综合精品蜜桃| 久久久亚洲午夜电影| 日韩av在线播放观看| 精品国产一区二区三区久久影院| 久久亚洲天堂| 国产精品视频一区二区高潮| 精品中文一区| 欧美日韩第二页| 久久亚洲综合色一区二区三区| 日本少妇毛茸茸高潮| 精品乱码亚洲一区二区不卡| 午夜激情在线| 亚洲综合精品一区二区| 91超碰成人| 日韩精品在线播放视频| 亚洲精品精品亚洲| 精品国精品国产自在久不卡| 久久成人人人人精品欧| 国产精品视频一区视频二区| 国产麻豆电影在线观看| 国产在线精品不卡| 国产天堂av在线| 欧美一区二区三区喷汁尤物| 黄色动漫在线观看| 99精品国产高清一区二区| 国产精品videosex极品| 亚洲一二三四五| 欧美日韩国产一区二区三区| 亚洲 另类 春色 国产| 97超级碰碰碰| 日韩a级大片| 午夜精品久久久内射近拍高清| 久久一区二区三区国产精品| 少妇高潮av久久久久久| 中文字幕国产亚洲| 99er精品视频| 污污污污污污www网站免费| 成人高清视频免费观看| 日本高清不卡码| 在线成人激情黄色| 97久久中文字幕| 欧美一级中文字幕| 成人av影院在线| 日韩精品一区二区亚洲av| 一本大道久久加勒比香蕉| 婷婷丁香久久| 国产传媒久久久| 26uuu亚洲婷婷狠狠天堂| 在线观看黄色国产| 欧美高清videos高潮hd| 少妇一区二区三区| 乌克兰美女av| 一区二区欧美视频| 国内精品一区视频| 亚洲最大成人在线| 国产日韩1区| 中文字幕无码日韩专区免费| 日韩免费看网站| 欧美magnet| 粉嫩av一区二区三区天美传媒| 99精品视频在线播放观看| 少妇无套内谢久久久久| 欧美日韩国产91| 国产精品午夜一区二区三区| 国产在线视频三区| 日韩欧美在线免费观看|