精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

欧美午夜欧美| 久久久成人av| 在线视频日韩一区| 超碰在线无需免费| 99久久婷婷国产综合精品| 日本一本a高清免费不卡| 国产成人在线网址| 国产精品x8x8一区二区| 在线免费视频一区二区| 日韩精品手机在线观看| 天堂a√中文在线| 看电视剧不卡顿的网站| 久久久亚洲精选| 99国产精品免费| 国产精品zjzjzj在线观看| 欧美亚洲国产一卡| 五十路熟女丰满大屁股| 好了av在线| 久久久www免费人成精品| 91在线|亚洲| 91久久国产综合久久91| 欧美婷婷在线| 久久色在线播放| 国产在线观看h| 全球av集中精品导航福利| 欧美一区二区女人| 免费看涩涩视频| 亚洲女同av| 亚洲成人综合视频| 国产制服91一区二区三区制服| 你懂的在线看| 99精品欧美一区二区三区小说| 成人日韩在线电影| 中文字幕乱码中文字幕| 久久国产主播| 欧美在线性爱视频| 男人天堂中文字幕| 欧美日韩午夜| 另类专区欧美制服同性| 久久嫩草捆绑紧缚| 精品精品99| 亚洲一区二区国产| 成人无码www在线看免费| 综合激情久久| 欧美一区二区成人| 亚洲黄色片免费| 日韩黄色碟片| 欧美美女黄视频| 五月激情婷婷在线| 国精品产品一区| 精品视频免费在线| 色一情一区二区三区| 少妇精品视频在线观看| 欧美高清精品3d| 在线观看免费视频高清游戏推荐| 播放一区二区| 精品视频资源站| 成人性生交免费看| 性欧美video另类hd尤物| 538prom精品视频线放| www,av在线| 日韩欧美激情电影| 精品国产一区二区三区四区四| 91porn在线| 噜噜噜狠狠夜夜躁精品仙踪林| 亚洲国产高潮在线观看| yy6080午夜| 国产精品日韩精品中文字幕| 亚洲色图在线观看| 日本成人午夜影院| 亚洲成人精选| 久久乐国产精品| 免费黄色网址在线| 日韩av不卡一区二区| 国产精品日韩精品| 国产精品久久久久久久久久久久久久久久 | 精品国产99久久久久久| 亚洲欧美综合色| 国产91在线亚洲| 性欧美18xxxhd| 欧美日韩亚州综合| 国产精品19p| 亚洲肉体裸体xxxx137| 中日韩午夜理伦电影免费| 动漫性做爰视频| a91a精品视频在线观看| 国产精品欧美激情| 亚洲国产精品成人久久蜜臀| 91原创在线视频| 在线码字幕一区| 激情av在线| 欧美性猛交xxxxxxxx| 四虎国产精品永久免费观看视频| 噜噜噜狠狠夜夜躁精品仙踪林| 中文一区二区视频| 国产大片aaa| 美女视频一区二区| 国产伦精品一区二区三区高清版 | y97精品国产97久久久久久| 国产一级二级毛片| 青青草视频一区| 国产亚洲一区二区三区在线播放| 精品亚洲成a人片在线观看| 亚洲欧美日韩国产中文在线| 草草久久久无码国产专区| **欧美日韩在线| 日韩精品免费观看| 亚洲最大的黄色网址| 久久久久国内| 国产伦精品一区二区| 色多多视频在线观看| 富二代精品短视频| 中国老熟女重囗味hdxx| 国产精品嫩模av在线| 欧美巨乳在线观看| 在线观看中文字幕网站| 91丨九色丨尤物| 国产精品无码免费专区午夜| 日韩成人精品一区二区三区| 亚洲女成人图区| 国产成人啪精品午夜在线观看| 久久狠狠亚洲综合| 日韩久久不卡| 伊人网在线播放| 亚洲成人激情在线| 国产成人久久久久| 蜜桃一区二区三区在线观看| 久久一区二区三区欧美亚洲| 黑人玩欧美人三根一起进| 欧美群妇大交群的观看方式| 国产精品高清无码在线观看| 国产精品永久| 黑人另类av| 高清电影在线观看免费| 91精品国产高清一区二区三区 | 国产综合亚洲精品一区二| 91久久精品视频| 免费av毛片在线看| 欧美日韩一区二区三区在线看| 免费黄色在线视频| 国产精品一区毛片| 久久久久久久久一区| 国产在线美女| 亚洲国产另类 国产精品国产免费| 九九九在线视频| 国产激情精品久久久第一区二区| 美女在线免费视频| 在线精品国产亚洲| 久久这里只有精品视频首页| 国产精品一区二区黑人巨大 | 上原亚衣av一区二区三区| 黄色片视频免费| 久久综合九色综合97_久久久| 日韩欧美国产免费| 一区二区三区韩国免费中文网站| 全球成人中文在线| 国产网站在线播放| 欧美偷拍一区二区| 一级性生活免费视频| 极品美女销魂一区二区三区| 丰满女人性猛交| 国产专区精品| 欧美黑人巨大精品一区二区| 色一情一乱一乱一区91av| 精品久久久久久中文字幕大豆网| 久久久久国产精品区片区无码| 三级成人在线视频| 亚洲欧美综合一区| 麻豆国产一区| 69视频在线免费观看| 青青草av免费在线观看| 欧美伊人久久大香线蕉综合69| 男人天堂资源网| 国产成人亚洲精品青草天美| 久草热视频在线观看| 在线成人动漫av| 成人免费网站在线| 福利影院在线看| 中国人与牲禽动交精品| 精品国产乱码一区二区三| 亚洲成av人片一区二区梦乃| 中文字幕成人动漫| 国产一区二区三区香蕉| 青青草视频在线免费播放 | www.亚洲在线| 熟妇人妻va精品中文字幕| 国产精品久久久久无码av| 丁香婷婷久久久综合精品国产| 日韩电影免费看| 久久精品久久久久久| 国产精品国产高清国产| 欧美日韩中文精品| 日韩黄色一级大片| 亚洲欧美怡红院| 久久午夜夜伦鲁鲁片| 精品在线视频一区| 国产青青在线视频| 国产精品88久久久久久| 精品1区2区| 九九99久久精品在免费线bt| 欧美在线视频a| 日本动漫同人动漫在线观看| 在线电影中文日韩| 日韩在线观看视频网站| 欧美男女性生活在线直播观看| 国产精品免费av一区二区| 国产精品欧美极品| aa片在线观看视频在线播放| 国内精品久久久久影院薰衣草| 日韩有码免费视频| 国产精品v日韩精品v欧美精品网站| 日韩片电影在线免费观看| 国产精品国产| 91视频免费网站| 小明成人免费视频一区| 66m—66摸成人免费视频| √天堂8在线网| 在线视频国产日韩| 天堂网av2014| 日韩欧美视频在线| 97超碰人人草| 欧洲一区在线电影| 九九热精品视频在线| 亚洲香蕉伊在人在线观| 在线观看亚洲网站| 中文字幕第一区综合| 久久国产精品影院| 91一区在线观看| 国产艳妇疯狂做爰视频| 国产麻豆视频一区二区| 日韩精品视频一二三| 日韩va欧美va亚洲va久久| 日韩av一二三四区| 中文国产一区| 欧美日韩成人免费视频| 在线欧美亚洲| 可以在线看的av网站| 一区二区视频欧美| 日韩在线观看a| 黄色一区二区三区四区| 青青草视频国产| 一区二区中文字| 男人j进女人j| 欧美日韩精品免费观看视频完整| 四虎4hu永久免费入口| 亚洲区综合中文字幕日日| 在线精品亚洲一区二区| 国产精品久久观看| 玖玖精品在线视频| 欧美久久久久| av免费看网址| 欧美亚洲一级| 校园春色 亚洲色图| 美女视频黄频大全不卡视频在线播放| 亚洲精品怡红院| 久久成人羞羞网站| 永久免费看片在线观看| 国产成人在线视频网址| 成年女人免费视频| 91婷婷韩国欧美一区二区| av网站免费在线看| 国产精品欧美经典| 中文字幕另类日韩欧美亚洲嫩草| 亚洲一区二区视频在线| 亚洲精品国产精品乱码| 日韩人在线观看| 一本色道久久综合精品婷婷 | 亚洲欧洲视频在线观看| 亚洲欧美一区二区激情| av在线收看| 欧美xxxx做受欧美.88| 色操视频在线| 欧美壮男野外gaytube| 欧美国产日韩电影| 亚洲free性xxxx护士hd| 欧美变态网站| 亚洲欧洲国产精品久久| 精品动漫3d一区二区三区免费版| 久久网站免费视频| 麻豆91在线观看| 人妻 日韩 欧美 综合 制服| 久久免费看少妇高潮| 亚洲精品电影院| 精品高清一区二区三区| 在线观看一二三区| 精品国产乱码久久久久久老虎| 蜜芽tv福利在线视频| 欧美成人三级视频网站| 都市激情综合| 91精品国产一区二区三区动漫 | 国产人成一区二区三区影院| 国产这里有精品| 欧洲一区在线电影| 亚洲奶汁xxxx哺乳期| 国产一区二区三区在线播放免费观看| 91在线中文| 国产精品久久久999| 无人区乱码一区二区三区| 日韩电影免费观看在| 欧美特黄一区| 日韩欧美国产片| 久久综合色婷婷| 唐朝av高清盛宴| 欧美亚洲国产一区在线观看网站| 免费av网站观看| 久久精品久久久久电影| 一二区成人影院电影网| 成人综合电影| 欧美影院一区| 亚洲高清免费在线观看| 久久久无码精品亚洲日韩按摩| 欧美日韩精品一区二区三区视频播放| 欧美性xxxxxx少妇| 神马午夜一区二区| 欧美日韩第一视频| 日韩亚洲国产免费| 日韩精品一线二线三线| 国产精品社区| 中文字幕一区二区人妻电影丶| 综合精品久久久| 亚洲一区精品在线观看| 亚洲色图狂野欧美| 亚洲黄色免费看| 黄色91av| 最新日韩在线| 国产在线观看免费播放| 一区二区三区在线视频免费观看| 在线视频 中文字幕| 亚洲视频视频在线| 亚洲精品88| 久久精品aaaaaa毛片| 亚洲久久在线| 亚洲一区二区三区四区av| 亚洲免费看黄网站| 国产免费叼嘿网站免费| 色婷婷久久一区二区| 国产精品久久久久久妇女| 日韩高清dvd| 日韩av在线发布| 国产又粗又猛又爽视频| 一本一本大道香蕉久在线精品| 天天综合网在线观看| 欧美亚洲视频在线看网址| 欧美wwwsss9999| 精品一卡二卡三卡| 久久综合五月天婷婷伊人| 无码无套少妇毛多18pxxxx| 亚洲日本中文字幕| 久久99久久99精品免观看软件| 日韩欧美精品一区二区| 蜜臀av性久久久久av蜜臀妖精| 中文字幕求饶的少妇| 91精品国产免费| 欧美寡妇性猛交xxx免费| 好看的日韩精品视频在线| 国产欧美成人| 日本xxxxxxxxx18| 欧美婷婷六月丁香综合色| 黄色网页在线免费看| 96国产粉嫩美女| 夜夜精品视频| 天天干天天舔天天操| 91精品一区二区三区久久久久久| av免费在线观| 九色视频成人porny| 日韩中文字幕区一区有砖一区 | 77导航福利在线| 91在线网站视频| 在线成人www免费观看视频| 亚洲精品视频久久久| 欧美三级视频在线| 日韩伦理av| 麻豆av一区| 久久电影网站中文字幕| 精品视频久久久久| 亚洲男人天堂久| 国产精品成人3p一区二区三区| 免费在线看黄色片| 久久久国产午夜精品| 国产视频第二页| 91精品国产精品| 久久国产电影| 亚洲精品国产成人av在线| 欧美系列日韩一区| 国产高清在线a视频大全| 日本中文不卡| 国产 日韩 欧美大片| 精品国产xxx| 欧美激情一区二区久久久| 精品影片在线观看的网站| 中文字幕第三区| 色哟哟在线观看一区二区三区| а√资源新版在线天堂| 乱一区二区三区在线播放| 精品一区二区三区欧美| 五月天婷婷久久| 久久99精品久久久久久噜噜| 国产一区二区精品福利地址| 国产人妻精品午夜福利免费| 色婷婷av一区二区三区软件 |