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

Flume架構與源碼分析-核心組件分析-1

開發 開發工具
start方法在整個Flume啟動時或者初始化組件時都會調用start方法進行組件初始化,Flume組件出現異常停止時會調用stop,getLifecycleState返回組件的生命周期狀態,有IDLE, START, STOP, ERROR四個狀態。

[[177130]]

首先所有核心組件都會實現org.apache.flume.lifecycle.LifecycleAware接口:

Java代碼

  1. public interface LifecycleAware {   
  2.   public void start();   
  3.   public void stop();   
  4.   public LifecycleState getLifecycleState();   
  5. }   

start方法在整個Flume啟動時或者初始化組件時都會調用start方法進行組件初始化,Flume組件出現異常停止時會調用stop,getLifecycleState返回組件的生命周期狀態,有IDLE, START, STOP, ERROR四個狀態。

如果開發的組件需要配置,如設置一些屬性;可以實現org.apache.flume.conf.Configurable接口:

Java代碼

  1. public interface Configurable {   
  2.    public void configure(Context context);   
  3. }   

Flume在啟動組件之前會調用configure來初始化組件一些配置。

1、Source

Source用于采集日志數據,有兩種實現方式:輪訓拉取和事件驅動機制;Source接口如下:

Java代碼

  1. public interface Source extends LifecycleAware, NamedComponent {   
  2.   public void setChannelProcessor(ChannelProcessor channelProcessor);   
  3.   public ChannelProcessor getChannelProcessor();   
  4. }    

Source接口首先繼承了LifecycleAware接口,然后只提供了ChannelProcessor的setter和getter接口,也就是說它的的所有邏輯的實現應該在LifecycleAware接口的start和stop中實現;ChannelProcessor之前介紹過用來進行日志流的過濾和Channel的選擇及調度。

而Source是通過SourceFactory工廠創建,默認提供了DefaultSourceFactory,其首先通過Enum類型org.apache.flume.conf.source.SourceType查找默認實現,如exec,則找到org.apache.flume.source.ExecSource實現,如果找不到直接Class.forName(className)創建。

Source提供了兩種機制: PollableSource(輪訓拉取)和EventDrivenSource(事件驅動):

PollableSource默認提供了如下實現:

比如JMSSource實現使用javax.jms.MessageConsumer.receive(pollTimeout)主動去拉取消息。

EventDrivenSource默認提供了如下實現:

比如NetcatSource、HttpSource就是事件驅動,即被動等待;比如HttpSource就是內部啟動了一個內嵌的Jetty啟動了一個Servlet容器,通過FlumeHTTPServlet去接收消息。

Flume提供了SourceRunner用來啟動Source的流轉:

Java代碼

  1. public class EventDrivenSourceRunner extends SourceRunner {   
  2.   private LifecycleState lifecycleState;   
  3.   public EventDrivenSourceRunner() {   
  4.       lifecycleState = LifecycleState.IDLE; //啟動之前是空閑狀態   
  5.   }   
  6.    
  7.   @Override   
  8.   public void start() {   
  9.     Source source = getSource(); //獲取Source   
  10.     ChannelProcessor cp = source.getChannelProcessor(); //Channel處理器   
  11.     cp.initialize(); //初始化Channel處理器   
  12.     source.start();  //啟動Source   
  13.     lifecycleState = LifecycleState.START; //本組件狀態改成啟動狀態   
  14.   }   
  15.   @Override   
  16.   public void stop() {   
  17.     Source source = getSource(); //先停Source   
  18.     source.stop();   
  19.     ChannelProcessor cp = source.getChannelProcessor();   
  20.     cp.close();//再停Channel處理器   
  21.     lifecycleState = LifecycleState.STOP; //本組件狀態改成停止狀態   
  22.   }   
  23. }    

從本組件也可以看出:1、首先要初始化ChannelProcessor,其實現時初始化過濾器鏈;2、接著啟動Source并更改本組件的狀態。

Java代碼

  1. public class PollableSourceRunner extends SourceRunner {   
  2.  @Override   
  3.  public void start() {   
  4.   PollableSource source = (PollableSource) getSource();   
  5.   ChannelProcessor cp = source.getChannelProcessor();   
  6.   cp.initialize();   
  7.   source.start();   
  8.    
  9.   runner = new PollingRunner();   
  10.   runner.source = source;   
  11.   runner.counterGroup = counterGroup;   
  12.   runner.shouldStop = shouldStop;   
  13.    
  14.   runnerThread = new Thread(runner);   
  15.   runnerThread.setName(getClass().getSimpleName() + "-" +    
  16.       source.getClass().getSimpleName() + "-" + source.getName());   
  17.   runnerThread.start();    
  18.    
  19.   lifecycleState = LifecycleState.START;   
  20.  }   
  21. }    

而PollingRunner首先初始化組件,但是又啟動了一個線程PollingRunner,其作用就是輪訓拉取數據:

Java代碼

  1. @Override   
  2.   public void run() {   
  3.     while (!shouldStop.get()) { //如果沒有停止,則一直在死循環運行   
  4.       counterGroup.incrementAndGet("runner.polls");   
  5.    
  6.       try {   
  7.         //調用PollableSource的process方法進行輪訓拉取,然后判斷是否遇到了失敗補償   
  8.         if (source.process().equals(PollableSource.Status.BACKOFF)) {/   
  9.           counterGroup.incrementAndGet("runner.backoffs");   
  10.    
  11.           //失敗補償時暫停線程處理,等待超時時間之后重試   
  12.           Thread.sleep(Math.min(   
  13.               counterGroup.incrementAndGet("runner.backoffs.consecutive")   
  14.               * source.getBackOffSleepIncrement(), source.getMaxBackOffSleepInterval()));   
  15.         } else {   
  16.           counterGroup.set("runner.backoffs.consecutive", 0L);   
  17.         }   
  18.       } catch (InterruptedException e) {   
  19.                 }   
  20.       }   
  21.     }   
  22.   }   
  23. }    

Flume在啟動時會判斷Source是PollableSource還是EventDrivenSource來選擇使用PollableSourceRunner還是EventDrivenSourceRunner。

比如HttpSource實現,其通過FlumeHTTPServlet接收消息然后:

Java代碼

  1. List<Event> events = Collections.emptyList(); //create empty list   
  2. //首先從請求中獲取Event   
  3. events = handler.getEvents(request);   
  4. //然后交給ChannelProcessor進行處理   
  5. getChannelProcessor().processEventBatch(events);    

到此基本的Source流程就介紹完了,其作用就是監聽日志,采集,然后交給ChannelProcessor進行處理。

2、Channel

Channel用于連接Source和Sink,Source生產日志發送到Channel,Sink從Channel消費日志;也就是說通過Channel實現了Source和Sink的解耦,可以實現多對多的關聯,和Source、Sink的異步化。

之前Source采集到日志后會交給ChannelProcessor處理,那么接下來我們先從ChannelProcessor入手,其依賴三個組件:

Java代碼

  1. private final ChannelSelector selector;  //Channel選擇器   
  2. private final InterceptorChain interceptorChain; //攔截器鏈   
  3. private ExecutorService execService; //用于實現可選Channel的ExecutorService,默認是單線程實現    

接下來看下其是如何處理Event的:

Java代碼

  1. public void processEvent(Event event) {   
  2.   event = interceptorChain.intercept(event); //首先進行攔截器鏈過濾   
  3.   if (event == null) {   
  4.     return;   
  5.   }   
  6.   List<Event> events = new ArrayList<Event>(1);   
  7.   events.add(event);   
  8.    
  9.   //通過Channel選擇器獲取必須成功處理的Channel,然后事務中執行   
  10.   List<Channel> requiredChannels = selector.getRequiredChannels(event);   
  11.   for (Channel reqChannel : requiredChannels) {    
  12.     executeChannelTransaction(reqChannel, events, false);   
  13.   }   
  14.    
  15.   //通過Channel選擇器獲取可選的Channel,這些Channel失敗是可以忽略,不影響其他Channel的處理   
  16.   List<Channel> optionalChannels = selector.getOptionalChannels(event);   
  17.   for (Channel optChannel : optionalChannels) {   
  18.     execService.submit(new OptionalChannelTransactionRunnable(optChannel, events));   
  19.   }   
  20. }    

另外內部還提供了批處理實現方法processEventBatch;對于內部事務實現的話可以參考executeChannelTransaction方法,整體事務機制類似于JDBC:

Java代碼

  1. private static void executeChannelTransaction(Channel channel, List<Event> batch, boolean isOptional) {   
  2.   //1、獲取Channel上的事務   
  3.   Transaction tx = channel.getTransaction();   
  4.   Preconditions.checkNotNull(tx, "Transaction object must not be null");   
  5.   try {   
  6.     //2、開啟事務   
  7.     tx.begin();   
  8.     //3、在Channel上執行批量put操作   
  9.     for (Event event : batch) {   
  10.       channel.put(event);   
  11.     }   
  12.     //4、成功后提交事務   
  13.     tx.commit();   
  14.   } catch (Throwable t) {   
  15.     //5、異常后回滾事務   
  16.     tx.rollback();   
  17.     if (t instanceof Error) {   
  18.        LOG.error("Error while writing to channel: " +   
  19.            channel, t);   
  20.        throw (Error) t;   
  21.     } else if(!isOptional) {//如果是可選的Channel,異常忽略   
  22.        throw new ChannelException("Unable to put batch on required " +   
  23.              "channel: " + channel, t);   
  24.     }   
  25.   } finally {   
  26.     //***關閉事務   
  27.     tx.close();   
  28.   }   
  29. }   

Interceptor用于過濾Event,即傳入一個Event然后進行過濾加工,然后返回一個新的Event,接口如下:

Java代碼

  1. public interface Interceptor {   
  2.     public void initialize();   
  3.     public Event intercept(Event event);   
  4.     public List<Event> intercept(List<Event> events);   
  5.     public void close();   
  6. }    

可以看到其提供了initialize和close方法用于啟動和關閉;intercept方法用于過濾或加工Event。比如HostInterceptor攔截器用于獲取本機IP然后默認添加到Event的字段為host的Header中。

接下來就是ChannelSelector選擇器了,其通過如下方式創建:

Java代碼

  1. //獲取ChannelSelector配置,比如agent.sources.s1.selector.type = replicating   
  2. ChannelSelectorConfiguration selectorConfig = config.getSelectorConfiguration();   
  3. //使用Source關聯的Channel創建,比如agent.sources.s1.channels = c1 c2   
  4. ChannelSelector selector = ChannelSelectorFactory.create(sourceChannels, selectorConfig);    

ChannelSelector默認提供了兩種實現:復制和多路復用:

默認實現是復制選擇器ReplicatingChannelSelector,即把接收到的消息復制到每一個Channel;多路復用選擇器MultiplexingChannelSelector會根據Event Header中的參數進行選擇,以此來選擇使用哪個Channel。

而Channel是Event中轉的地方,Source發布Event到Channel,Sink消費Channel的Event;Channel接口提供了如下接口用來實現Event流轉:

Java代碼

  1. public interface Channel extends LifecycleAware, NamedComponent {   
  2.   public void put(Event event) throws ChannelException;   
  3.   public Event take() throws ChannelException;   
  4.   public Transaction getTransaction();   
  5. }    

put用于發布Event,take用于消費Event,getTransaction用于事務支持。默認提供了如下Channel的實現:

對于Channel的實現我們后續單獨章節介紹。

3、Sink

Sink從Channel消費Event,然后進行轉移到收集/聚合層或存儲層。Sink接口如下所示:

Java代碼

  1. public interface Sink extends LifecycleAware, NamedComponent {   
  2.   public void setChannel(Channel channel);   
  3.   public Channel getChannel();   
  4.   public Status process() throws EventDeliveryException;   
  5.   public static enum Status {   
  6.     READY, BACKOFF   
  7.   }   
  8. }    

類似于Source,其首先繼承了LifecycleAware,然后提供了Channel的getter/setter方法,并提供了process方法進行消費,此方法會返回消費的狀態,READY或BACKOFF。

Sink也是通過SinkFactory工廠來創建,其也提供了DefaultSinkFactory默認工廠,比如傳入hdfs,會先查找Enum org.apache.flume.conf.sink.SinkType,然后找到相應的默認處理類org.apache.flume.sink.hdfs.HDFSEventSink,如果沒找到默認處理類,直接通過Class.forName(className)進行反射創建。

我們知道Sink還提供了分組功能,用于把多個Sink聚合為一組進行使用,內部提供了SinkGroup用來完成這個事情。此時問題來了,如何去調度多個Sink,其內部使用了SinkProcessor來完成這個事情,默認提供了故障轉移和負載均衡兩個策略。

首先SinkGroup就是聚合多個Sink為一組,然后將多個Sink傳給SinkProcessorFactory進行創建SinkProcessor,而策略是根據配置文件中配置的如agent.sinkgroups.g1.processor.type = load_balance來選擇的。

SinkProcessor提供了如下實現:

DefaultSinkProcessor:默認實現,用于單個Sink的場景使用。

FailoverSinkProcessor:故障轉移實現:

Java代碼

  1. public Status process() throws EventDeliveryException {   
  2.   Long now = System.currentTimeMillis();   
  3.     //1、首先檢查失敗隊列的頭部的Sink是否已經過了失敗補償等待時間了   
  4.   while(!failedSinks.isEmpty() && failedSinks.peek().getRefresh() < now) {   
  5.     //2、如果可以使用了,則從失敗Sink隊列獲取隊列***個Sink   
  6.     FailedSink cur = failedSinks.poll();   
  7.     Status s;   
  8.     try {   
  9.       s = cur.getSink().process(); //3、使用此Sink進行處理   
  10.       if (s  == Status.READY) { //4、如果處理成功   
  11.         liveSinks.put(cur.getPriority(), cur.getSink()); //4.1、放回存活Sink隊列   
  12.         activeSink = liveSinks.get(liveSinks.lastKey());   
  13.       } else {   
  14.         failedSinks.add(cur); //4.2、如果此時不是READY,即BACKOFF期間,再次放回失敗隊列   
  15.       }   
  16.       return s;   
  17.     } catch (Exception e) {   
  18.       cur.incFails(); //5、如果遇到異常了,則增加失敗次數,并放回失敗隊列   
  19.       failedSinks.add(cur);   
  20.     }   
  21.   }   
  22.    
  23.   Status ret = null;   
  24.   while(activeSink != null) { //6、此時失敗隊列中沒有Sink能處理了,那么需要使用存活Sink隊列進行處理   
  25.     try {   
  26.       ret = activeSink.process();   
  27.       return ret;   
  28.     } catch (Exception e) { //7、處理失敗進行轉移到失敗隊列   
  29.       activeSink = moveActiveToDeadAndGetNext();   
  30.     }   
  31.   }   
  32.    
  33.   throw new EventDeliveryException("All sinks failed to process, " +   
  34.       "nothing left to failover to");   
  35. }   

失敗隊列是一個優先級隊列,使用refresh屬性排序,而refresh是通過如下機制計算的:

Java代碼

  1. refresh = System.currentTimeMillis() 
  2. + Math.min(maxPenalty, (1 << sequentialFailures) * FAILURE_PENALTY); 

其中maxPenalty是***等待時間,默認30s,而(1 << sequentialFailures) * FAILURE_PENALTY)用于實現指數級等待時間遞增, FAILURE_PENALTY是1s。

LoadBalanceSinkProcessor:用于實現Sink的負載均衡,其通過SinkSelector進行實現,類似于ChannelSelector。LoadBalanceSinkProcessor在啟動時會根據配置,如agent.sinkgroups.g1.processor.selector = random進行選擇,默認提供了兩種選擇器:

LoadBalanceSinkProcessor使用如下機制進行負載均衡:

Java代碼

  1. public Status process() throws EventDeliveryException {   
  2.   Status status = null;   
  3.   //1、使用選擇器創建相應的迭代器,也就是用來選擇Sink的迭代器   
  4.   Iterator<Sink> sinkIterator = selector.createSinkIterator();   
  5.   while (sinkIterator.hasNext()) {   
  6.     Sink sink = sinkIterator.next();   
  7.     try {   
  8.       //2、選擇器迭代Sink進行處理,如果成功直接break掉這次處理,此次負載均衡就算完成了   
  9.       status = sink.process();   
  10.       break;   
  11.     } catch (Exception ex) {   
  12.       //3、失敗后會通知選擇器,采取相應的失敗退避補償算法進行處理   
  13.       selector.informSinkFailed(sink);   
  14.       LOGGER.warn("Sink failed to consume event. "   
  15.           + "Attempting next sink if available.", ex);   
  16.     }   
  17.   }   
  18.   if (status == null) {   
  19.     throw new EventDeliveryException("All configured sinks have failed");   
  20.   }   
  21.   return status;   
  22. }    

如上的核心就是怎么創建迭代器,如何進行失敗退避補償處理,首先我們看下RoundRobinSinkSelector實現,其內部是通過通用的RoundRobinOrderSelector選擇器實現:

Java代碼

  1. public Iterator<T> createIterator() {   
  2.   //1、獲取存活的Sink索引,   
  3.   List<Integer> activeIndices = getIndexList();   
  4.   int size = activeIndices.size();   
  5.   //2、如果上次記錄的下一個存活Sink的位置超過了size,那么從隊列頭重新開始計數   
  6.   if (nextHead >= size) {   
  7.     nextHead = 0;   
  8.   }   
  9.   //3、獲取本次使用的起始位置   
  10.   int begin = nextHead++;   
  11.   if (nextHead == activeIndices.size()) {   
  12.     nextHead = 0;   
  13.   }   
  14.   //4、從該位置開始迭代,其實現類似于環形隊列,比如整個隊列是5,起始位置是3,則按照 3、4、0、1、2的順序進行輪訓,實現了輪訓算法    
  15.   int[] indexOrder = new int[size];   
  16.   for (int i = 0; i < size; i++) {   
  17.     indexOrder[i] = activeIndices.get((begin + i) % size);   
  18.   }   
  19.   //indexOrder是迭代順序,getObjects返回相關的Sinks;   
  20.   return new SpecificOrderIterator<T>(indexOrder, getObjects());   
  21. }    

getIndexList實現如下:

Java代碼

  1. protected List<Integer> getIndexList() {   
  2.   long now = System.currentTimeMillis();   
  3.   List<Integer> indexList = new ArrayList<Integer>();   
  4.   int i = 0;   
  5.   for (T obj : stateMap.keySet()) {   
  6.     if (!isShouldBackOff() || stateMap.get(obj).restoreTime < now) {   
  7.       indexList.add(i);   
  8.     }   
  9.     i++;   
  10.   }   
  11.   return indexList;   
  12. }   

isShouldBackOff()表示是否開啟退避算法支持,如果不開啟,則認為每個Sink都是存活的,每次都會重試,通過agent.sinkgroups.g1.processor.backoff = true配置開啟,默認false;restoreTime和之前介紹的refresh一樣,是退避補償等待時間,算法類似,就不多介紹了。

那么什么時候調用Sink進行消費呢?其類似于SourceRunner,Sink提供了SinkRunner進行輪訓拉取處理,SinkRunner會輪訓調度SinkProcessor消費Channel的消息,然后調用Sink進行轉移。SinkProcessor之前介紹過,其負責消息復制/路由。

SinkRunner實現如下:

Java代碼

  1. public void start() {   
  2.   SinkProcessor policy = getPolicy();   
  3.   policy.start();   
  4.   runner = new PollingRunner();   
  5.   runner.policy = policy;   
  6.   runner.counterGroup = counterGroup;   
  7.   runner.shouldStop = new AtomicBoolean();   
  8.   runnerThread = new Thread(runner);   
  9.   runnerThread.setName("SinkRunner-PollingRunner-" +   
  10.       policy.getClass().getSimpleName());   
  11.   runnerThread.start();   
  12.   lifecycleState = LifecycleState.START;   
  13. }    

即獲取SinkProcessor然后啟動它,接著啟動輪訓線程去處理。PollingRunner線程負責輪訓消息,核心實現如下:

Java代碼

  1. public void run() {   
  2.   while (!shouldStop.get()) { //如果沒有停止   
  3.     try {   
  4.       if (policy.process().equals(Sink.Status.BACKOFF)) {//如果處理失敗了,進行退避補償處理   
  5.         counterGroup.incrementAndGet("runner.backoffs");   
  6.         Thread.sleep(Math.min(   
  7.             counterGroup.incrementAndGet("runner.backoffs.consecutive")   
  8.             * backoffSleepIncrement, maxBackoffSleep)); //暫停退避補償設定的超時時間   
  9.       } else {   
  10.         counterGroup.set("runner.backoffs.consecutive", 0L);   
  11.       }   
  12.     } catch (Exception e) {   
  13.       try {   
  14.         Thread.sleep(maxBackoffSleep); //如果遇到異常則等待***退避時間   
  15.       } catch (InterruptedException ex) {   
  16.         Thread.currentThread().interrupt();   
  17.       }   
  18.     }   
  19.   }   
  20. }    

整體實現類似于PollableSourceRunner實現,整體處理都是交給SinkProcessor完成的。SinkProcessor會輪訓Sink的process方法進行處理;此處以LoggerSink為例:

Java代碼

  1. @Override   
  2. public Status process() throws EventDeliveryException {   
  3.   Status result = Status.READY;   
  4.   Channel channel = getChannel();   
  5.   //1、獲取事務   
  6.   Transaction transaction = channel.getTransaction();   
  7.   Event event = null;   
  8.    
  9.   try {   
  10.     //2、開啟事務   
  11.     transaction.begin();   
  12.     //3、從Channel獲取Event   
  13.     event = channel.take();   
  14.     if (event != null) {   
  15.       if (logger.isInfoEnabled()) {   
  16.         logger.info("Event: " + EventHelper.dumpEvent(event, maxBytesToLog));   
  17.       }   
  18.     } else {//4、如果Channel中沒有Event,則默認進入故障補償機制,即防止死循環造成CPU負載高   
  19.       result = Status.BACKOFF;   
  20.     }   
  21.     //5、成功后提交事務   
  22.     transaction.commit();   
  23.   } catch (Exception ex) {   
  24.     //6、失敗后回滾事務   
  25.     transaction.rollback();   
  26.     throw new EventDeliveryException("Failed to log event: " + event, ex);   
  27.   } finally {   
  28.     //7、關閉事務   
  29.     transaction.close();   
  30.   }   
  31.   return result;   
  32. }    

Sink中一些實現是支持批處理的,比如RollingFileSink:

Java代碼

  1. //1、開啟事務   
  2. //2、批處理   
  3. for (int i = 0; i < batchSize; i++) {   
  4.   event = channel.take();   
  5.   if (event != null) {   
  6.     sinkCounter.incrementEventDrainAttemptCount();   
  7.     eventAttemptCounter++;   
  8.     serializer.write(event);   
  9.   }   
  10. }   
  11. //3、提交/回滾事務、關閉事務   

定義一個批處理大小然后在事務中執行批處理。

【本文是51CTO專欄作者張開濤的原創文章,作者微信公眾號:開濤的博客,id:kaitao-1234567】

責任編輯:武曉燕 來源: 開濤的博客
相關推薦

2016-11-29 09:38:06

Flume架構核心組件

2016-11-25 13:14:50

Flume架構源碼

2016-11-29 16:59:46

Flume架構源碼

2022-06-07 10:33:29

Camera組件鴻蒙

2015-04-24 09:33:11

Cloud Found組件分析PaaS

2021-09-05 07:35:58

lifecycleAndroid組件原理

2011-04-29 13:40:37

MongoDBCommand

2022-01-05 08:53:13

Spring原理分析MVC

2009-12-31 15:55:06

ADO.NET結構

2016-10-21 13:03:18

androidhandlerlooper

2021-09-08 10:47:33

Flink執行流程

2025-01-13 00:13:59

VSCode架構依賴注入

2015-08-11 15:52:52

大數據數據分析

2022-07-17 06:51:22

Vite 3.0前端

2019-10-08 10:01:22

Kafka應用場景架構

2017-05-04 22:30:17

Zuul過濾器微服務

2011-05-26 10:05:48

MongoDB

2014-08-26 11:11:57

AsyncHttpCl源碼分析

2011-03-15 11:33:18

iptables

2019-10-16 16:33:41

Docker架構語言
點贊
收藏

51CTO技術棧公眾號

日韩av高清在线看片| 99一区二区| 毛片aaaaaa| 亚洲图片小说区| 亚洲精品欧美激情| 精品国产免费一区二区三区| 日韩在线视频不卡| 欧美顶级大胆免费视频| 日韩欧美激情在线| 女人和拘做爰正片视频| 婷婷五月在线视频| 国产成人在线视频免费播放| 欧美夜福利tv在线| 久久一级免费视频| 日韩av网站在线免费观看| 欧美在线小视频| 97超碰在线人人| 午夜在线小视频| 97精品久久久午夜一区二区三区| 国产精品入口免费视| 伊人365影院| 欧美oldwomenvideos| 日韩精品在线观看一区二区| 日本高清一区二区视频| 欧美伦理91| 亚洲狼人国产精品| 婷婷五月色综合| 亚洲 美腿 欧美 偷拍| 国产一级精品在线| 国产精品美女久久久免费| 日韩欧美一区二区一幕| 亚洲久久久久| 日韩中文字幕第一页| 香蕉视频黄色在线观看| 一区中文字幕电影| 欧美一级欧美三级在线观看| 香蕉视频网站入口| 欧美一区国产| 欧美天天综合色影久久精品| 成人短视频在线观看免费| 最新真实国产在线视频| 久久久久久久久久看片| 精品久久久久久一区| 丰满人妻一区二区三区四区53| 久久精品国产99久久6| 国产成人精品视频在线| www.国产一区二区| 国产精品美女久久久浪潮软件| 九九视频这里只有精品| 国产美女福利视频| 爽成人777777婷婷| 丝袜情趣国产精品| sm捆绑调教视频| 凹凸成人精品亚洲精品密奴| 亚洲视频一区二区| 国产精品815.cc红桃| 亚洲大片精品免费| 精品在线欧美视频| 久久精品成人av| 蜜桃a∨噜噜一区二区三区| 日韩电影网在线| 亚洲最大的黄色网| 亚洲aa在线| 亚洲男人天堂网站| 国产精品天天干| 日韩黄色大片网站| 啊v视频在线一区二区三区| 特级西西人体高清大胆| 国产精品精品国产一区二区| 久久久精品久久久久| 婷婷在线精品视频| 亚洲国产第一| 欧美在线视频免费| 国产免费一区二区三区四区五区| 日韩精品乱码av一区二区| 国产精品色婷婷视频| 91女人18毛片水多国产| 国产乱子伦一区二区三区国色天香| 91一区二区三区| 欧美一区二区公司| 久久久噜噜噜久噜久久综合| 色阁综合av| a天堂中文在线官网在线| 亚洲高清不卡在线| 精品人妻一区二区三区四区在线 | 日本美女一级片| 久久这里都是精品| 亚洲图色在线| 欧美四级在线| 日韩欧美主播在线| 思思久久精品视频| 国产日韩三级| 亚洲人成网站免费播放| 91香蕉视频污在线观看| 亚洲性人人天天夜夜摸| 国产91热爆ts人妖在线| 国产欧美熟妇另类久久久 | 国产sm调教视频| 希岛爱理av一区二区三区| 欧美精品电影在线| 亚洲午夜在线播放| 成人免费高清在线观看| 日韩一二三区不卡在线视频| 羞羞电影在线观看www| 欧美视频免费在线观看| 激情黄色小视频| 久久免费视频66| 日韩中文字在线| 国产污污视频在线观看| 韩国毛片一区二区三区| 精品无码久久久久国产| 黄色一级片在线观看| 欧美日韩国产限制| 免费在线观看日韩av| 国产一区二区三区四区二区| 欧美激情手机在线视频 | 奇米综合一区二区三区精品视频| 成人黄视频免费| 日本在线天堂| 色综合久久九月婷婷色综合| 久久久久亚洲av成人网人人软件| 日产精品一区二区| 欧美综合一区第一页| 成人黄色免费视频| **网站欧美大片在线观看| 欧美日韩第二页| 福利在线一区| 不用播放器成人网| 在线观看免费视频一区| 久久综合资源网| 国内精品视频一区二区三区| 精品国产乱码一区二区三区| 在线观看不卡av| 国产精品va无码一区二区三区| 高清免费成人av| 神马午夜伦理影院| 伊人久久综合网另类网站| 亚洲天堂久久av| 中文字幕一区二区人妻电影| av电影在线观看一区| 黄网站色视频免费观看| 95精品视频| www.国产一区| 91在线公开视频| 国产精品久久久久一区二区三区 | 国产精区一区二区| 久久精品成人欧美大片| 7777久久亚洲中文字幕| 国产精品国产a| 一本色道久久亚洲综合精品蜜桃| 精品亚洲成人| 国产精品久久久久久搜索| 韩日在线视频| 欧美午夜理伦三级在线观看| 一级片久久久久| 日本女优在线视频一区二区| 日本一区二区精品| 成人精品动漫| 久久久精品免费视频| 国产口爆吞精一区二区| 亚洲乱码日产精品bd| 性一交一黄一片| 韩日欧美一区| 精品国产一区二区三| 一级毛片久久久| 中文国产亚洲喷潮| 国产又黄又爽视频| 一区二区在线观看视频在线观看| 欧美精品 - 色网| 亚洲性视频h| 欧美精品v日韩精品v国产精品| 欧美舌奴丨vk视频| 日韩在线视频网站| 亚洲av无码国产综合专区| 亚洲超碰精品一区二区| 中文字幕人妻一区二区| 免费人成精品欧美精品| 99热都是精品| 网友自拍一区| 国产精品丝袜白浆摸在线| av片在线观看永久免费| 日韩成人中文字幕在线观看| 无码人妻av免费一区二区三区| 国产精品久久久久国产精品日日| 国产chinesehd精品露脸| 一区二区日本视频| 日本在线观看一区二区| 99视频有精品高清视频| 91国产视频在线播放| 在线免费看黄| 亚洲成人精品视频在线观看| 天天干天天色综合| 亚洲人成网站影音先锋播放| 久久久国产精品无码| 免费观看在线综合色| 日本黄色片一级片| 欧美精品久久久久久| 波多野结衣成人在线| 日本成人三级电影| 色综合久久久888| 国产福利在线| 亚洲精品一线二线三线无人区| 啪啪小视频网站| 香蕉成人伊视频在线观看| 亚洲AV无码成人精品区明星换面| 国产精品亚洲成人| 日本熟妇人妻中出| 亚洲成色精品| 91社在线播放| 久久不见久久见国语| av日韩免费电影| 欧美日韩视频免费看| 1769国内精品视频在线播放| 成码无人av片在线观看网站| 一本色道久久88综合日韩精品| 亚洲成人久久精品| 欧美美女网站色| 免费精品一区二区| 精品国产鲁一鲁一区二区张丽| 国产免费一区二区三区四区| 国产日韩欧美a| 国产伦精品一区二区三区妓女 | 粉嫩老牛aⅴ一区二区三区| 色老板免费视频| 欧美极品另类videosde| 香蕉视频黄色在线观看| 成人国产精品免费| 国产黄色一区二区三区| 久久草av在线| 91看片在线免费观看| 欧美资源在线| 成人免费毛片网| 在线成人www免费观看视频| 黄色网络在线观看| 97视频精品| 亚洲欧洲一二三| 欧美综合在线视频观看| 日本在线视频一区| 精品欧美久久| 天天好比中文综合网| 日韩大片在线| 亚洲精品一区二区三| 精品大片一区二区| 日韩av电影在线观看| 九色成人国产蝌蚪91| 久久久久欧美| 免费av一区| 欧美国产综合视频| 九九综合在线| 亚洲欧美日韩国产yyy| 色135综合网| ijzzijzzij亚洲大全| 在线一区免费| 国产成人一区二区三区别| 狠狠久久婷婷| 欧美啪啪免费视频| 亚洲欧美日韩精品一区二区| 无码人妻丰满熟妇区96| 久久综合影音| 欧美第一页浮力影院| 国产一区二区三区香蕉| 少妇性l交大片7724com| 成人午夜在线免费| 少妇精品一区二区| 久久精品视频免费观看| 国产探花视频在线播放| 中文字幕一区日韩精品欧美| 在线看的片片片免费| 一区二区不卡在线播放| 国产精品久久久免费视频| 日本高清不卡aⅴ免费网站| 亚洲综合精品国产一区二区三区| 欧美一区三区四区| 欧美一级淫片aaaaaa| 国产性猛交xxxx免费看久久| 免费在线看黄网站| 久久久爽爽爽美女图片| 黑人巨大精品| 成人性生交大片免费看小说 | 亚洲国产精品系列| 精品99又大又爽又硬少妇毛片| 中文字幕国产精品| 自拍亚洲图区| 欧洲一区二区视频| 91精品麻豆| 精品久久中出| 欧美激情国产在线| 日韩五码在线观看| 日本不卡中文字幕| 久久久久久久久久影视| 久久久777精品电影网影网 | 欧美性xxxx18| 国产精品久久久久久久免费| 日韩欧美一二三四区| 欧洲亚洲在线| 欧美老肥婆性猛交视频| 欧美电影免费观看| 亚洲自拍欧美另类| 国产亚洲一区二区三区不卡| 视色,视色影院,视色影库,视色网| 亚洲在线观看| 中文字幕在线观看视频www| 久久先锋资源网| 欧美精品久久久久性色| 色婷婷久久久亚洲一区二区三区| av网站免费大全| 国产午夜精品视频| av老司机免费在线| 成人精品久久久| 国产麻豆精品久久| 成人午夜免费在线| 国产盗摄视频一区二区三区| 人妻视频一区二区| 欧美日韩加勒比精品一区| 国产999久久久| 日韩中文字幕亚洲| 日韩毛片在线| 麻豆蜜桃91| 精品91在线| 在线观看一区二区三区视频| 国产精品萝li| 中文字幕+乱码+中文字幕明步| 亚洲精品国产美女| 黑人玩欧美人三根一起进| 91精品视频在线| 欧美电影免费播放| 日本人视频jizz页码69| 久久美女艺术照精彩视频福利播放| 久久久久久久久97| 日韩欧美一级二级三级| a级影片在线| 成人午夜黄色影院| 999久久久亚洲| 欧美精品性生活| 国产欧美va欧美不卡在线 | 7777精品伊人久久久大香线蕉经典版下载| 十九岁完整版在线观看好看云免费| 九九热这里只有精品6| 欧美影院精品| 精品一区二区三区毛片| 国产福利91精品一区| 欧美大片xxxx| 91精品国产欧美一区二区成人| 日本中文字幕在线视频| 成人免费在线视频网站| 午夜国产一区二区| 中文字幕线观看| 亚洲欧美日本在线| 国产区精品在线| 欧美日韩不卡合集视频| 一区二区三区四区高清视频| 日本aa在线观看| 成人黄色大片在线观看| 日韩精品久久久久久久| 亚洲精品www久久久久久广东| 蜜桃av.网站在线观看| 欧美凹凸一区二区三区视频 | 亚洲一区二区三区四区在线| 成人黄色免费视频| 午夜免费在线观看精品视频| 欧美激情15p| 欧美成人黑人猛交| 国产精品网站在线播放| 国产孕妇孕交大片孕| 久久久久久久久亚洲| 欧美变态挠脚心| 中文字幕第80页| 亚洲视频小说图片| 日韩在线观看视频网站| 欧洲精品在线视频| 成人一区二区| 97超碰免费在线观看| 午夜不卡av在线| 高清av电影在线观看| 91免费人成网站在线观看18| 国产主播精品| 91激情视频在线观看| 91精品国产91久久综合桃花| www在线观看黄色| 日韩在线观看电影完整版高清免费| 精品一区二区三区久久| 日韩乱码一区二区| 亚洲最新视频在线| 国产精选久久| 国产综合免费视频| 综合久久一区二区三区| 手机在线观看免费av| 国产精品爽爽爽爽爽爽在线观看| 欧美三区美女| 日韩av片在线| 欧美精品一区二区三区高清aⅴ| 伊人久久综合一区二区| 日本成人性视频| 91蜜桃传媒精品久久久一区二区| 亚洲中文一区二区三区| 69影院欧美专区视频| 天天精品视频| 舐め犯し波多野结衣在线观看| 日韩西西人体444www| 国产亚洲一区二区手机在线观看|