成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > Tomcat 是如何管理Session的方法示例

Tomcat 是如何管理Session的方法示例

熱門標簽:江西外呼系統(tǒng) 湖北ai智能電銷機器人 AI電銷機器人 源碼 外呼系統(tǒng)打哪顯哪 高德地圖標注論壇 北海市地圖標注app 新科美甲店地圖標注 蘭州ai電銷機器人招商 新邵電銷機器人企業(yè)

學了 ConcurrentHashMap 卻不知如何應用?用了Tomcat的Session卻不知其是如何實現(xiàn)的,Session是怎么被創(chuàng)建和銷毀的?往下看你就知道了。

Session結(jié)構(gòu)

不多廢話,直接上圖

仔細觀察上圖,我們可以得出以下結(jié)論

  • HttpSession 是JavaEE標準中操作Session的接口類,因此我們實際上操作的是 StandardSessionFacade
  • Session 保存數(shù)據(jù)所使用的數(shù)據(jù)結(jié)構(gòu)是 ConcurrentHashMap , 如你在圖上看到的我們往 Session 中保存了一個msg

為什么需要使用 ConcurrentHashMap 呢?原因是,在處理Http請求并不是只有一個線程會訪問這個Session, 現(xiàn)代Web應用訪問一次頁面,通常需要同時執(zhí)行多次請求, 而這些請求可能會在同一時刻內(nèi)被Web容器中不同線程同時執(zhí)行,因此如果采用 HashMap 的話,很容易引發(fā)線程安全的問題。

讓我們先來看看HttpSession的包裝類。

StandardSessionFacade

在此類中我們可以學習到外觀模式(Facde)的實際應用。其定義如下所示。

public class StandardSessionFacade implements HttpSession 

那么此類是如何實現(xiàn)Session的功能呢?觀察以下代碼不難得出,此類并不是HttpSession的真正實現(xiàn)類,而是將真正的HttpSession實現(xiàn)類進行包裝,只暴露HttpSession接口中的方法,也就是設計模式中的外觀(Facde)模式。

 private final HttpSession session;
 public StandardSessionFacade(HttpSession session) {
 this.session = session;
 }

那么我們?yōu)槭裁床恢苯邮褂肏ttpSession的實現(xiàn)類呢?

根據(jù)圖1,我們可以知道HttpSession的真正實現(xiàn)類是 StandardSession ,假設在該類內(nèi)定義了一些本應由Tomcat調(diào)用而非由程序調(diào)用的方法,那么由于Java的類型系統(tǒng)我們將可以直接操作該類,這將會帶來一些不可預見的問題,如以下代碼所示。

而如果我們將 StandardSession 再包裝一層,上圖代碼執(zhí)行的時候?qū)l(fā)生錯誤。如下圖所示,將會拋出類型轉(zhuǎn)換的異常,從而阻止此處非法的操作。

再進一步,我們由辦法繞外觀類直接訪問 StandardSession 嗎?

事實上是可以的,我們可以通過反射機制來獲取 StandardSession ,但你最好清楚自己在干啥。代碼如下所示

 @GetMapping("/s")
 public String sessionTest(HttpSession httpSession) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
 StandardSessionFacade session = (StandardSessionFacade) httpSession;
 Class targetClass = Class.forName(session.getClass().getName());

 //修改可見性
 Field standardSessionField = targetClass.getDeclaredField("session");
 standardSessionField.setAccessible(true);
 //獲取
 StandardSession standardSession = (StandardSession) standardSessionField.get(session);
 
 return standardSession.getManager().toString();
 }

StandardSession

該類的定義如下

public class StandardSession implements 
HttpSession, Session, Serializable

通過其接口我們可以看出此類除了具有JavaEE標準中 HttpSession 要求實現(xiàn)的功能之外,還有序列化的功能。

在圖1中我們已經(jīng)知道 StandardSession 是用 ConcurrentHashMap 來保存的數(shù)據(jù),因此接下來我們主要關注 StandardSession 的序列化以及反序列化的實現(xiàn),以及監(jiān)聽器的功能。

序列化

還記得上一節(jié)我們通過反射機制獲取到了 StandardSession 嗎?利用以下代碼我們可以直接觀察到反序列化出來的 StandardSession 是咋樣的。

 @GetMapping("/s")
 public void sessionTest(HttpSession httpSession, HttpServletResponse response) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, IOException {
 StandardSessionFacade session = (StandardSessionFacade) httpSession;
 Class targetClass = Class.forName(session.getClass().getName());

 //修改可見性
 Field standardSessionField = targetClass.getDeclaredField("session");
 standardSessionField.setAccessible(true);
 //獲取
 StandardSession standardSession = (StandardSession) standardSessionField.get(session);
 
 //存點數(shù)據(jù)以便觀察
 standardSession.setAttribute("msg","hello,world");
 standardSession.setAttribute("user","kesan");
 standardSession.setAttribute("password", "點贊");
 standardSession.setAttribute("tel", 10086L);
 //將序列化的結(jié)果直接寫到Http的響應中
 ObjectOutputStream objectOutputStream = new ObjectOutputStream(response.getOutputStream());
 
 standardSession.writeObjectData(objectOutputStream);
 }

如果不出意外,訪問此接口瀏覽器將會執(zhí)行下載操作,最后得到一個文件

使用 WinHex 打開分析,如圖所示為序列化之后得結(jié)果,主要是一大堆分隔符,以及類型信息和值,如圖中紅色方框標準的信息。

不建議大家去死磕序列化文件是如何組織數(shù)據(jù)的,因為意義不大

如果你真的有興趣建議你閱讀以下代碼 org.apache.catalina.session.StandardSession.doWriteObject

監(jiān)聽器

在JavaEE的標準中,我們可以通過配置 HttpSessionAttributeListener 來監(jiān)聽Session的變化,那么在 StandardSession 中是如何實現(xiàn)的呢,如果你了解觀察者模式,那么想必你已經(jīng)知道答案了。 以setAttribute為例,在調(diào)用此方法之后會立即在本線程調(diào)用監(jiān)聽器的方法進行處理,這意味著我們不應該在監(jiān)聽器中執(zhí)行阻塞時間過長的操作。

 public void setAttribute(String name, Object value, boolean notify) {
 //省略無關代碼
  //獲取上文中配置的事件監(jiān)聽器
 Object listeners[] = context.getApplicationEventListeners();
 if (listeners == null) {
  return;
 }
 for (int i = 0; i < listeners.length; i++) {
  //只有HttpSessionAttributeListener才可以執(zhí)行
  if (!(listeners[i] instanceof HttpSessionAttributeListener)) {
  continue;
  }
  HttpSessionAttributeListener listener = (HttpSessionAttributeListener) listeners[i];
  try {
  //在當前線程調(diào)用監(jiān)聽器的處理方法
  if (unbound != null) {
   if (unbound != value || manager.getNotifyAttributeListenerOnUnchangedValue()) {
   //如果是某個鍵的值被修改則調(diào)用監(jiān)聽器的attributeReplaced方法
   context.fireContainerEvent("beforeSessionAttributeReplaced", listener);
   if (event == null) {
    event = new HttpSessionBindingEvent(getSession(), name, unbound);
   }
   listener.attributeReplaced(event);
   context.fireContainerEvent("afterSessionAttributeReplaced", listener);
   }
  } else {
   //如果是新添加某個鍵則執(zhí)行attributeAdded方法
   context.fireContainerEvent("beforeSessionAttributeAdded", listener);
   if (event == null) {
   event = new HttpSessionBindingEvent(getSession(), name, value);
   }
   listener.attributeAdded(event);
   context.fireContainerEvent("afterSessionAttributeAdded", listener);
  }
  } catch (Throwable t) {
  //異常處理
  }
 }
 }

Sesssion生命周期

如何保存Session

在了解完Session的結(jié)構(gòu)之后,我們有必要明確 StandardSession 是在何時被創(chuàng)建的,以及需要注意的點。

首先我們來看看 StandardSession 的構(gòu)造函數(shù), 其代碼如下所示。

 public StandardSession(Manager manager) {
 //調(diào)用Object類的構(gòu)造方法,默認已經(jīng)調(diào)用了
 //此處再聲明一次,不知其用意,或許之前此類有父類?
 super();
 
 this.manager = manager;
 //是否開啟訪問計數(shù)
 if (ACTIVITY_CHECK) {
  accessCount = new AtomicInteger();
 }
 }

在創(chuàng)建 StandardSession 的時候都必須傳入 Manager 對象以便與此 StandardSession 關聯(lián),因此我們可以將目光轉(zhuǎn)移到 Manager ,而 Manager 與其子類之間的關系如下圖所示。

我們將目光轉(zhuǎn)移到 ManagerBase中可以發(fā)現(xiàn)以下代碼。

protected Map<String, Session> sessions = new ConcurrentHashMap<>();

Session 是Tomcat自定義的接口, StandardSession 實現(xiàn)了 HttpSession 以及 Session 接口,此接口功能更加豐富,但并不向程序員提供。

查找此屬性可以發(fā)現(xiàn),與Session相關的操作都是通過操作 sessions 來實現(xiàn)的,因此我們可以明確保存Session的數(shù)據(jù)結(jié)構(gòu)是 ConcurrentHashMap 。

如何創(chuàng)建Session

那么Session到底是如何創(chuàng)建的呢?我找到了以下方法 ManagerBase.creaeSession , 總結(jié)其流程如下。

  • 檢查session數(shù)是否超過限制,如果有就拋出異常
  • 創(chuàng)建StandardSession對象
  • 設置session各種必須的屬性(合法性, 最大超時時間, sessionId)
  • 生成SessionId, Tomcat支持不同的SessionId算法,本人調(diào)試過程其所使用的SessionId生成算法是LazySessionIdGenerator(此算法與其他算法不同之處就在于并不會在一開始就加載隨機數(shù)數(shù)組,而是在用到的時候才加載,此處的隨機數(shù)組并不是普通的隨機數(shù)組而是SecureRandom,相關信息可以閱讀大佬的文章)
  • 增加session的計數(shù),由于Tomcat的策略是只計算100個session的創(chuàng)建速率,因此sessionCreationTiming是固定大小為100的鏈表(一開始為100個值為null的元素),因此在將新的數(shù)據(jù)添加到鏈表中時必須要將舊的數(shù)據(jù)移除鏈表以保證其固定的大小。session創(chuàng)建速率計算公式如下

(1000*60*counter)/(int)(now - oldest)
其中

  • now為獲取統(tǒng)計數(shù)據(jù)時的時間System.currentTimeMillis()
  • oldest為隊列中最早創(chuàng)建session的時間
  • counter為隊列中值不為null的元素的數(shù)量
  • 由于計算的是每分鐘的速率因此在此處必須將1000乘以60(一分鐘內(nèi)有60000毫秒)
 public Session createSession(String sessionId) {
 //檢查Session是否超過限制,如果是則拋出異常
 if ((maxActiveSessions >= 0) &&
  (getActiveSessions() >= maxActiveSessions)) {
  rejectedSessions++;
  throw new TooManyActiveSessionsException(
   sm.getString("managerBase.createSession.ise"),
   maxActiveSessions);
 }

 //該方法會創(chuàng)建StandardSession對象
 Session session = createEmptySession();

 //初始化Session中必要的屬性
 session.setNew(true);
 //session是否可用
 session.setValid(true);
 //創(chuàng)建時間
 session.setCreationTime(System.currentTimeMillis());
 //設置session最大超時時間
 session.setMaxInactiveInterval(getContext().getSessionTimeout() * 60);
 String id = sessionId;
 if (id == null) {
  id = generateSessionId();
 }
 session.setId(id);
 sessionCounter++;
 //記錄創(chuàng)建session的時間,用于統(tǒng)計數(shù)據(jù)session的創(chuàng)建速率
 //類似的還有ExpireRate即Session的過期速率
 //由于可能會有其他線程對sessionCreationTiming操作因此需要加鎖
 SessionTiming timing = new SessionTiming(session.getCreationTime(), 0);
 synchronized (sessionCreationTiming) {
  //sessionCreationTiming是LinkedList
  //因此poll會移除鏈表頭的數(shù)據(jù),也就是最舊的數(shù)據(jù)
  sessionCreationTiming.add(timing);
  sessionCreationTiming.poll();
 }
 return session;
 }

Session的銷毀

要銷毀Session,必然要將Session從 ConcurrentHashMap 中移除,順藤摸瓜我們可以發(fā)現(xiàn)其移除session的代碼如下所示。

 @Override
 public void remove(Session session, boolean update) {
 //檢查是否需要將統(tǒng)計過期的session的信息
 if (update) {
  long timeNow = System.currentTimeMillis();
  int timeAlive =
  (int) (timeNow - session.getCreationTimeInternal())/1000;
  updateSessionMaxAliveTime(timeAlive);
  expiredSessions.incrementAndGet();
  SessionTiming timing = new SessionTiming(timeNow, timeAlive);
  synchronized (sessionExpirationTiming) {
  sessionExpirationTiming.add(timing);
  sessionExpirationTiming.poll();
  }
 }
 //將session從Map中移除
 if (session.getIdInternal() != null) {
  sessions.remove(session.getIdInternal());
 }
 }

被銷毀的時機

主動銷毀

我們可以通過調(diào)用 HttpSession.invalidate() 方法來執(zhí)行session銷毀操作。此方法最終調(diào)用的是 StandardSession.invalidate() 方法,其代碼如下,可以看出使 session 銷毀的關鍵方法是 StandardSession.expire()

 public void invalidate() {

 if (!isValidInternal())
  throw new IllegalStateException
  (sm.getString("standardSession.invalidate.ise"));

 // Cause this session to expire
 expire();
 }

expire 方法的代碼如下

 @Override
 public void expire() {

 expire(true);

 }
 public void expire(boolean notify) {
  //省略代碼
  //將session從ConcurrentHashMap中移除
  manager.remove(this, true);
  //被省略的代碼主要是將session被銷毀的消息通知
  //到各個監(jiān)聽器上
 }

超時銷毀

除了主動銷毀之外,我們可以為session設置一個過期時間,當時間到達之后session會被后臺線程主動銷毀。我們可以為session設置一個比較短的過期時間,然后通過 JConsole 來追蹤其調(diào)用棧,其是哪個對象哪個線程執(zhí)行了銷毀操作。

如下圖所示,我們?yōu)閟ession設置了一個30秒的超時時間。

然后我們在 ManagerBase.remove

方法上打上斷點,等待30秒之后,如下圖所示

Tomcat會開啟一個后臺線程,來定期執(zhí)行子組件的 backgroundProcess 方法(前提是子組件被Tomcat管理且實現(xiàn)了 Manager接口)

 @Override
 public void backgroundProcess() {
 count = (count + 1) % processExpiresFrequency;
 if (count == 0)
  processExpires();
 }

 public void processExpires() {

 long timeNow = System.currentTimeMillis();
 Session sessions[] = findSessions();
 int expireHere = 0 ;

 if(log.isDebugEnabled())
  log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length);
 //從JConsole的圖中可以看出isValid可能導致expire方法被調(diào)用
 for (int i = 0; i < sessions.length; i++) {
  if (sessions[i]!=null && !sessions[i].isValid()) {
  expireHere++;
  }
 }
 long timeEnd = System.currentTimeMillis();
 if(log.isDebugEnabled())
  log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere);
 processingTime += ( timeEnd - timeNow );

 }

我們可以來看看接口中 Manager.backgroundProcess 中注釋,簡略翻譯一下就是 backgroundProcess 會被容器定期的執(zhí)行,可以用來執(zhí)行session清理任務等。

 /**
 * This method will be invoked by the context/container on a periodic
 * basis and allows the manager to implement
 * a method that executes periodic tasks, such as expiring sessions etc.
 */
 public void backgroundProcess();

總結(jié)

Session的數(shù)據(jù)結(jié)構(gòu)如下圖所示,簡單來說就是用 ConcurrentHashMap 來保存 Session ,而 Session 則用 ConcurrentHashMap 來保存鍵值對,其結(jié)構(gòu)如下圖所示。 .jpg

這意味著,不要拼命的往Session里面添加離散的數(shù)據(jù), 把離散的數(shù)據(jù)封裝成一個對象性能會更加好 如下所示

//bad
httpSession.setAttribute("user","kesan");
httpSession.setAttribute("nickname","點贊");
httpSession.setAttribute("sex","男");
....
//good
User kesan = userDao.getUser()
httpSession.setAttribute("user", kesan);

如果你為Session配置了監(jiān)聽器,那么對Session執(zhí)行任何變更都將直接在當前線程執(zhí)行監(jiān)聽器的方法, 因此最好不要在監(jiān)聽器中執(zhí)行可能會發(fā)生阻塞的方法

Tomcat會開啟一個后臺線程來定期執(zhí)行 ManagerBase.backgroundProcess 方法用來檢測過期的Session并將其銷毀。

思想遷移

對象生成速率算法此算法設計比較有趣,并且也可以應用到其他項目中,因此做如下總結(jié)。

首先生成一個固定大小的鏈表(比如說100),然后以null元素填充。 當創(chuàng)建新的對象時,將創(chuàng)建時間加入鏈表末尾中(當然是封裝后的對象),然后將鏈表頭節(jié)點移除,此時被移除的對象要么是null節(jié)點要么是最早加入鏈表的節(jié)點 當要計算對象生成速率時,統(tǒng)計鏈表中不為null的元素的數(shù)量除以當前的時間與最早創(chuàng)建對象的時間的差,便可以得出其速率。(注意時間單位的轉(zhuǎn)換)

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

標簽:南陽 阿克蘇 自貢 黃石 大理 黔東 海南 池州

巨人網(wǎng)絡通訊聲明:本文標題《Tomcat 是如何管理Session的方法示例》,本文關鍵詞  Tomcat,是,如何,管理,Session,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權(quán)與本站無關。
  • 相關文章
  • 下面列出與本文章《Tomcat 是如何管理Session的方法示例》相關的同類信息!
  • 本頁收集關于Tomcat 是如何管理Session的方法示例的相關信息資訊供網(wǎng)民參考!
  • 推薦文章
    欧美 中文字幕| 欧美啪啪小视频| 国产aa视频| 精品偷拍激情视频在线观看| 中国av一区| 欧美日韩一区在线视频| 操人视频在线播放| 欧美亚视频在线中文字幕免费| 色网综合在线观看| 日韩中文字幕一区二区高清99| 国产无套内射久久久国产| 亚洲精品aaaaa| 东方aⅴ免费观看久久av| 欧美午夜精品在线| 欧美激情免费观看| 自拍偷拍校园春色| 欧美日韩三级电影在线| 婷婷亚洲综合| 日韩vs国产vs欧美| 欧美日韩激情视频8区| 亚洲视频狠狠干| 国产嫩草影院久久久久| 最近中文字幕在线观看| 91精品国产高清自在线看超| 午夜影院免费视频| 影音先锋2020资源| 精品处破学生在线二十三| 国产精品久久久久久久久电影网| 亚洲成人天堂| 久久亚洲一区二区| 亚欧在线免费观看| 国严精品久久久久久亚洲影视| 亚洲啊v在线观看| 日本婷婷久久久久久久久一区二区| 日韩视频精品在线| 日韩在线视频免费观看高清中文| 色一情一区二区三区四区| 国产福利影院在线观看| 夜夜嗨av色综合久久久综合网| 国产精品久久久久久久久久久久午夜片| 成人av毛片在线观看| 欧美日韩精品免费观看视频| 亚洲卡一卡二卡三| 91在线视频观看免费| 在线观看中文字幕不卡| 日本精品在线视频| 日本综合精品一区| 美女搡bbb又爽又猛又黄www| 激情av在线播放| 荫蒂被男人添免费视频| 精品国产一区二区精华| 精品国产乱码久久久久软件| 日本三级一区二区三区| 亚洲国产成人在人网站天堂| 性欧美成人播放77777| 99九九99九九九视频精品| 国产精品美女呻吟| 亚洲精品中文字幕乱码| 国产呦萝稀缺另类资源| 一区二区三区四区五区视频在线观看| 国产伪娘ts一区| 日本国产一区二区三区| 苍井空张开腿实干12次| 欧美精品电影免费在线观看| 九色视频在线观看| 欧美精品一区二区不卡| 日韩免费观看高清完整版在线观看| 91看片就是不一样| 国产午夜亚洲精品不卡| 成年人性生活视频| 欧美精品momsxxx| 日本成人看片网址| 中国一级特黄毛片大片| 久久精品国产亚洲av麻豆色欲| 日韩视频一区在线| 亚洲国产精品视频在线观看| 亚洲三级小视频| 亚洲国产福利| 中文字幕无码日韩专区免费| 国产激情美女久久久久久吹潮| 日韩中文一区二区三区| 国产欧美一区二区精品婷婷| 亚洲精品va在线观看| 国产女主播喷水视频在线观看| 欧美精品福利在线| 永久免费毛片在线播放不卡| 国内免费精品永久在线视频| 在线播放免费视频| 日产精品99久久久久久| 福利视频导航大全| 国产农村妇女毛片精品久久麻豆| 青青草在线免费视频| 日日碰狠狠丁香久燥| 欧美狂欢多p性派对| videoxxxx另类日本极品| 日韩精品四区| 欧美 日韩 国产在线| 黄色污网站在线免费观看| 久久天天做天天爱综合色| 久久精品久久精品国产大片| 亚洲欧美另类久久久精品| 成人全视频在线观看在线播放高清| 久久精品免视看国产成人| 国产欧美成人xxx视频| 亚洲福利视频专区| 欧美成人片在线| 深夜做爰性大片蜜桃| 成人天堂yy6080亚洲高清| 欧美日本啪啪无遮挡网站| 国产一区二区视频网站| 亚洲欧美日本在线| 国产高清一区在线观看| 妖精视频一区二区三区免费观看| 99riav视频| 一卡二卡三卡四卡五卡| 最新av网址在线观看| 久久小说免费下载| 国产成人精品国内自产拍免费看| 国产精品无码一区二区三| 在线观看亚洲黄色| jizzjizz丝袜老师| 国产精品推荐精品| 黄频网站在线观看| 国产精品一区专区| 国产在线精品一区免费香蕉| 国产91在线播放九色| 高清毛片在线观看| 精品久久一二三区| 91精品国产91久久久| 成人午夜精品一区二区三区| 欧美伦理一区二区| 中文字幕亚洲欧美一区二区三区| 在线观看视频一区二区三区| 中国女人一级毛片| 欧美另类专区| 免费精品国产自产拍观看| 中文字幕精品三区| 日韩精品亚洲精品| 天堂在线网站| 一区av在线播放| 亚洲风情亚aⅴ在线发布| 国产精品久久久久无码av色戒| 精品免费av| 国产亚洲欧美日韩日本| 97久久精品人人爽人人爽蜜臀| 99久热在线精品视频| 可以在线观看的黄色| 日韩亚洲视频在线观看| 女女互磨互喷水高潮les呻吟| 视频一区免费观看| 狠狠色狠狠色合久久伊人| 日韩亚洲国产中文字幕| 欧美精品一区二区三区国产精品| 欧美特黄一级大片| 91av成人在线| 日本污视频在线观看| 国产免费无码一区二区视频| 91免费观看网站| 日本黄色免费视频| 免费看大片爽| 美女av免费看| 一区二区三区四区欧美日韩| 久久亚洲资源| 欧美久久久久久久久久| 中文字幕综合一区| 中文字幕国产精品一区二区| 日本在线天堂| 国产精品18久久久久久久久| 欧美性猛片xxxx免费看久爱| xxxxx91麻豆| 国产探花在线精品一区二区| 国内精品久久久久久99蜜桃| 郴州新闻综合频道在线直播| 神马电影网我不卡| 国产精品多人| 国产在线精品一区在线观看麻豆| 91精品国产综合久久久久久丝袜| 激情婷婷综合| 国产亚洲精久久久久久无码77777| 欧美亚洲免费电影| 91禁在线观看| 无套白嫩进入乌克兰美女| 欧美1区2区视频| 亚洲欧美久久婷婷爱综合一区天堂| 精品51国产黑色丝袜高跟鞋| 欧美超碰在线观看| 亚洲欧美自偷自拍另类| 亚洲精品91美女久久久久久久| 亚洲一区二区三区四区视频| 99中文字幕| 屁屁影院国产第一页| 久久精品视频免费| 欧美日韩不卡一区二区| 精品无人国产偷自产在线| 国产精品va在线播放| 国内精品伊人久久久久影院对白| 精品国产亚洲一区二区三区| 亚洲欧美国产精品专区久久| 亚洲中文字幕无码av| 波多野结衣爱爱视频| 欧美一区二区视频在线观看2022| 欧美无遮挡国产欧美另类| 亚洲国产美国国产综合一区二区| 国产人成一区二区三区影院| 欧美日韩在线播放三区四区| 制服丝袜亚洲播放| 91av视频在线免费观看| 2018中文字幕在线观看| 色婷婷一区二区三区av免费看| 亚洲国产日韩欧美综合久久| 自拍偷拍第1页| 久久久99国产精品免费| 国产在线观看a视频| 69日本xxxxxxxxx49| 在线xxxx| 国产91精品看黄网站在线观看| 亚洲免费精彩视频| 永久av免费网站| 水蜜桃一区二区| 毛片av中文字幕一区二区| 一级成人免费视频| 欧美体内she精视频在线观看| 春色校园综合激情亚洲| 四虎影视18库在线影院| 国产精品theporn| 国产精品对白一区二区三区| 97碰碰碰免费色视频| 久久er99热精品一区二区三区| 久久99日本精品| 亚洲网一区二区三区| 国内精品久久久久| 欧美日韩一区自拍| 四虎在线免费视频| a级在线观看视频| 伊人久久大香线蕉综合影院首页| 国产在线观看成人| h网站免费看| 日日骚av一区二区| 欧美一区二区三区| 中文字幕日韩欧美精品高清在线| 欧美精品生活片| 免费国产阿v视频在线观看| 欧美成a人免费观看久久| 亚洲精品视频导航| 人人九九精品视频| 国产不卡高清在线观看视频| 欧美色综合影院| 国产精品自产拍在线观看中文| 偷窥韩漫第三季| av一区二区三区四区| 久久成人综合网| 日韩在线视频播放| 久久久亚洲精品无码| 青青草社区在线| 国产精品日韩精品在线播放| 亚洲欧美日韩在线高清直播| 日本久久久久| 欧美一区二区三区粗大| 在线观看日本www| 欧美人成在线观看ccc36| 91国内产香蕉| 老牛影视av老牛影视av| 亚洲人成影视在线观看| 亚洲欧美日韩精品久久| 久久国产亚洲| 夜夜操com| 羞羞网站在线观看| 偷窥少妇高潮呻吟av久久免费| 在线视频国产福利| 久久久午夜视频| 韩国美女主播一区| 亚洲最快最全在线视频| 亚洲精品国产无天堂网2021| 日韩在线欧美| 99久久综合狠狠综合久久止| 欧美天堂一区二区| 国产精品区一区二区三| 国产成人无码精品久久二区三| 亚洲成人999| 免费啪视频在线观看| 中国av免费看| 国产成人av电影在线播放| 色伊人久久综合中文字幕| 成人免费视频app| 免费精品99久久国产综合精品| 日韩动漫一区| 成人偷拍自拍| 欧美一区二区三区婷婷| 国产精品嫩草影院久久久| 欧美日韩国产美| 青青视频在线播放| 免费h视频在线观看| 国产高潮呻吟久久久| 成人精品国产免费网站| 日韩女优在线观看| 欧美××××黑人××性爽| 日韩综合小视频| 玖玖爱视频在线| 手机av在线网站| 欧美三区在线观看| 粉嫩aⅴ一区二区三区四区五区| 天天操天天射天天色| 国产亚洲欧美日韩在线观看一区二区| 麻豆精品国产传媒av| 黄网站网址视频| 伊人色综合久久| 91中文在线视频| 91好色先生tv| 国产私拍福利精品视频二区| 成年人网站免费观看| 亚洲热线99精品视频| 蜜臀久久99精品久久久| 第一会所sis001亚洲| 人狥杂交一区欧美二区| 日韩欧美极品在线观看| 国产福利小视频在线观看| 小说区亚洲自拍另类图片专区| av一区二区三区黑人| 欧美性感美女h网站在线观看免费| 精品国产精品一区二区夜夜嗨| 日本精品网站| 日本欧美www| 在线视频一区二区免费| 无码人妻精品一区二区三区蜜桃91| 糖心vlog在线免费观看| wwwwxxxx在线观看| 成人av一区二区三区在线观看| 亚洲电影欧美电影有声小说|