<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          限流神器Sentinel,不了解一下嗎?

          共 13808字,需瀏覽 28分鐘

           ·

          2021-07-17 13:56

          Sentinel 是啥?

          分布式系統(tǒng)的流量防衛(wèi)兵

          引用一下之前我畫的圖:

          image.png

          流量防衛(wèi)兵 它具備了哪些能力?

          image.png

          Sentinel 的生態(tài)環(huán)境

          隨著 Alibaba 的 Java 生態(tài)建設(shè),包括 Spring Cloud Alibaba,Rocket,Nacos等多項(xiàng)開源技術(shù)的貢獻(xiàn),目前Sentinel 對(duì)分布式的各種應(yīng)用場景都有了良好的支持和適配,這也是為什么我們選擇 Sentinel 學(xué)習(xí)的原因之一(學(xué)習(xí)成本低,應(yīng)用場景多)

          image.png

          Sentinel 核心概念

          1、資源

          資源Sentinel 中的核心概念之一。最常用的資源是我們代碼中的 Java 方法,一段代碼,或者一個(gè)接口

          Java方法:

          @SentinelResource("HelloWorld")
          public void helloWorld() {
              // 資源中的邏輯
              System.out.println("hello world");
          }

          一段代碼:

                  // 1.5.0 版本開始可以直接利用 try-with-resources 特性,自動(dòng) exit entry
          try (Entry entry = SphU.entry("HelloWorld")) {
                      // 被保護(hù)的邏輯
                      System.out.println("hello world");
           } catch (BlockException ex) {
                      // 處理被流控的邏輯
               System.out.println("blocked!");
           }

          一個(gè)接口:

          @RestController
          public class TestController {
              @GetMapping("/test")
              public String test(){
                  return "test";
              }
          }

          配合控制臺(tái)使用:

          image.png

          2、規(guī)則

          Sentinel 中的規(guī)則 提供給用戶,針對(duì)不同的場景而制定不同的保護(hù)動(dòng)作,規(guī)則的類型包括:

          • 流量控制規(guī)則
          • 熔斷降級(jí)規(guī)則
          • 系統(tǒng)保護(hù)規(guī)則
          • 來源訪問控制規(guī)則
          • 熱點(diǎn)參數(shù)規(guī)則

          本文主要會(huì)講解 流量熔斷系統(tǒng)保護(hù)這三個(gè)規(guī)則。

          定義規(guī)則:

              private static void initFlowRules(){
                  List<FlowRule> rules = new ArrayList<>();
                  FlowRule rule = new FlowRule();
                  //綁定資源
                  rule.setResource("HelloWorld");
                  //限流閾值類型
                  rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
                  //數(shù)量級(jí)別
                  rule.setCount(20);
                  //添加到本地內(nèi)存
                  rules.add(rule);
                  FlowRuleManager.loadRules(rules);
              }

          限流規(guī)則重要屬性說明:

          Field說明默認(rèn)值
          resource資源名,資源名是限流規(guī)則的作用對(duì)象
          count限流閾值
          grade限流閾值類型,QPS 模式(1)或并發(fā)線程數(shù)模式(0)QPS 模式
          limitApp流控針對(duì)的調(diào)用來源default,代表不區(qū)分調(diào)用來源
          strategy調(diào)用關(guān)系限流策略:直接、鏈路、關(guān)聯(lián)根據(jù)資源本身(直接)
          controlBehavior流控效果(直接拒絕/WarmUp/勻速+排隊(duì)等待),不支持按調(diào)用關(guān)系限流直接拒絕
          clusterMode是否集群限流

          Sentinel 限流

          1、單機(jī)限流

          1.1、引入依賴

          在上一篇文章中,有提到過 RateLimiter  實(shí)現(xiàn)的單機(jī)限流, 這里介紹一下,使用 Sentinel 實(shí)現(xiàn)的單機(jī)限流

          //項(xiàng)目中引入 sentinel-core 依賴
          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>sentinel-core</artifactId>
              <version>1.8.1</version>
          </dependency>

          1.2、定義限流規(guī)則

          定義保護(hù)規(guī)則:

              private static void initFlowRules(){
                  List<FlowRule> rules = new ArrayList<>();
                  FlowRule rule = new FlowRule();
                  //綁定資源
                  rule.setResource("HelloWorld");
                  //限流閾值類型
                  rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
                  //數(shù)量級(jí)別
                  rule.setCount(20);
                  //添加到本地內(nèi)存
                  rules.add(rule);
                  FlowRuleManager.loadRules(rules);
              }

          1.3、定義限流資源

          根據(jù)上面描述的 資源劃分, 我們這里主要將 代碼塊  定義為資源。

          public static void main(String[] args) {
              // 配置規(guī)則.
              initFlowRules();

              while (true) {
                  // 1.5.0 版本開始可以直接利用 try-with-resources 特性,自動(dòng) exit entry
                  try (Entry entry = SphU.entry("HelloWorld")) {
                      // 被保護(hù)的邏輯
                      System.out.println("hello world");
           } catch (BlockException ex) {
                      // 處理被流控的邏輯
               System.out.println("blocked!");
           }
              }
          }

          1.4、運(yùn)行結(jié)果

          Demo 運(yùn)行之后,我們可以在日志 ~/logs/csp/${appName}-metrics.log.xxx 里看到下面的輸出:

          image.png
          ?  csp cat com-jaycekon-sentinel-demo-FlowRuleDemo-metrics.log.2021-07-03

          |--timestamp-|------date time----|-resource-|p |block|s |e|rt
          1625294582000|2021-07-03 14:43:02|HelloWorld|20|1720|20|0|2|0|0|0
          1625294583000|2021-07-03 14:43:03|HelloWorld|20|5072|20|0|0|0|0|0
          1625294584000|2021-07-03 14:43:04|HelloWorld|20|6925|20|0|0|0|0|0
          • p 代表通過的請求
          • block 代表被阻止的請求
          • s 代表成功執(zhí)行完成的請求個(gè)數(shù)
          • e 代表用戶自定義的異常
          • rt 代表平均響應(yīng)時(shí)長

          Sentinel 的單機(jī)限流 ,和 RateLimiter 有什么區(qū)別呢?

          Field分布式環(huán)境下實(shí)現(xiàn)難度空間復(fù)雜度時(shí)間復(fù)雜度限制突發(fā)流量平滑限流
          令牌桶低O(1)高O(N)
          滑動(dòng)窗口高O(N)中O(N)相對(duì)實(shí)現(xiàn)

          附錄:《Sentinel - 滑動(dòng)窗口實(shí)現(xiàn)原理》

          2、控制臺(tái)限流

          2.1、客戶端接入控制臺(tái)

          超詳細(xì)文檔,參考:《Sentinel - 控制臺(tái)》

          Sentinel 提供一個(gè)輕量級(jí)的開源控制臺(tái),它提供機(jī)器發(fā)現(xiàn)以及健康情況管理、監(jiān)控(單機(jī)和集群),規(guī)則管理和推送的功能。

          下載Jar 包(21M),或者下載源碼(4M) 后自行進(jìn)行編譯(不建議,編譯花的時(shí)間比直接下載jar包還要久)

          https://github.com/alibaba/Sentinel/releases

          編譯后,啟動(dòng)命令

          java -Dserver.port=8000 -Dcsp.sentinel.dashboard.server=localhost:8000 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar
          8608912f0070c8c93df53f6c3cb21952.gif

          進(jìn)入控制臺(tái)

          image.png

          2.2、引入依賴

          客戶端需要引入 Transport 模塊來與 Sentinel 控制臺(tái)進(jìn)行通信。您可以通過 pom.xml 引入 JAR 包

          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>sentinel-transport-simple-http</artifactId>
              <version>1.8.1</version>
          </dependency>

          //重要的依賴,還是提前先寫上吧,避免小伙伴找不到了
          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>sentinel-web-servlet</artifactId>
              <version>1.8.1</version>
          </dependency>

          然后?。。┝宋乙幌挛绲牡胤絹砹耍。≡诠俜轿臋n中,指出了需要引入對(duì)應(yīng)的依賴配置 , 好家伙,那么重要的話,你如此輕描淡寫,腦殼疼?。。。?/p>

          image.png

          對(duì)應(yīng)的適配依賴有

          • 云原生微服務(wù)體系
          • Web 適配
          • RPC 適配
          • HTTP client 適配
          • Reactive 適配
          • Reactive 適配
          • Apache RocketMQ

          好家伙,基本上所有業(yè)務(wù)場景都覆蓋到了!由于我的Demo 項(xiàng)目是基于 SpringBoot ,然后想看看 云原生微服務(wù)體系下的視頻,好家伙,要用 SpringCloud , 想要了解的,可以參考:  《Spring-Cloud-Sentinel》

          2.3、定義資源

          @SpringBootApplication
          @Configuration
          @RestController
          public class SpringBootSentinelApplication {

              public static void main(String[] args) {
                  SpringApplication.run(SpringBootSentinelApplication.classargs);
              }

              @Bean
              public FilterRegistrationBean sentinelFilterRegistration() {
                  FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
                  registration.setFilter(new CommonFilter());
                  registration.addUrlPatterns("/*");
                  registration.setName("sentinelFilter");
                  registration.setOrder(1);

                  return registration;
              }
              
              @RequestMapping("/index")
              public String index(){
                  return "hello index";
              }
              
          }

          在概述中,我們有提到過,需要被保護(hù)的資源,可以是 一個(gè)代碼塊一個(gè)方法或者一個(gè)接口。這里通過 Filter 的 方式,將所有請求都定義為資源 (/*), 那么我們在請求的過程就會(huì)變成這樣子:

          image.png

          2.4 運(yùn)行結(jié)果

          添加啟動(dòng)參數(shù)

          -Dserver.port=8088 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=jaycekon-sentinel

          參數(shù)說明:

          • server.port : 服務(wù)啟動(dòng)端口
          • csp.sentinel.dashboard.server : 狀態(tài)上報(bào)機(jī)器ip:端口
          • project.name : 監(jiān)控項(xiàng)目名稱
          image.png

          運(yùn)行結(jié)果:

          2.5 限流配置

          image.png

          流控效果

          • 1、快速失?。褐苯邮?/section>
          • 2、Warm Up:預(yù)熱模式,根據(jù)codeFactory的值(默認(rèn)3),從閾值/codeFactory,經(jīng)過預(yù)熱時(shí)長,才達(dá)到設(shè)置的QPS閾值。比如設(shè)置QPS為90,設(shè)置預(yù)熱為10秒,則最初的閾值為90/3=30,經(jīng)過10秒后才達(dá)到90。
          • 3、排隊(duì)等待:比如設(shè)置閾值為10,超時(shí)時(shí)間為500毫秒,當(dāng)?shù)?1個(gè)請求到的時(shí)候,不會(huì)直接報(bào)錯(cuò),而是等待500毫秒,如果之后閾值還是超過10,則才會(huì)被限流。

          運(yùn)行結(jié)果:

          image.png
          image.png

          3、集群限流

          講了那么多,終于要到核心的 集群限流方案了, 在秒殺系統(tǒng)設(shè)計(jì)中,我們談到很多場景都是以單機(jī)作為具體案例進(jìn)行分析,如果我們的系統(tǒng)要擴(kuò)容,那么如何做好限流方案。假設(shè)集群中有 10 臺(tái)機(jī)器,我們給每臺(tái)機(jī)器設(shè)置單機(jī)限流閾值為10 QPS,理想情況下整個(gè)集群的限流閾值就為100 QPS。不過實(shí)際情況下流量到每臺(tái)機(jī)器可能會(huì)不均勻,會(huì)導(dǎo)致總量沒有到的情況下某些機(jī)器就開始限流。因此僅靠單機(jī)維度去限制的話會(huì)無法精確地限制總體流量。而集群流控可以精確地控制整個(gè)集群的調(diào)用總量,結(jié)合單機(jī)限流兜底,可以更好地發(fā)揮流量控制的效果。

          介紹一下集群限流的核心角色:

          • Token Client:集群流控客戶端,用于向所屬 Token Server 通信請求 token。集群限流服務(wù)端會(huì)返回給客戶端結(jié)果,決定是否限流。
          • Token Server:即集群流控服務(wù)端,處理來自 Token Client 的請求,根據(jù)配置的集群規(guī)則判斷是否應(yīng)該發(fā)放 token(是否允許通過)。

          在嵌入模式下的結(jié)構(gòu)圖:

          image.png

          在獨(dú)立模式下的結(jié)構(gòu)圖:

          image.png

          內(nèi)嵌模式,即 發(fā)Token 的操作,有其中某一個(gè)實(shí)例完成,其他 Client 通過向 Server 請求,獲取訪問許可。

          獨(dú)立模式,即作為獨(dú)立的 token server 進(jìn)程啟動(dòng),獨(dú)立部署,隔離性好,但是需要額外的部署操作。

          3.1、阿里云AHAS

          在上述示例代碼中,使用了本地模式的 Demo, 在集群限流的場景,這里用一下 阿里云提供的 AHAS 服務(wù)。

          控制臺(tái)地址:https://ahas.console.aliyun.com/index?ns=default&region=public

          引入依賴:

          //sentinel ahas 依賴,包括了sentinel的使用依賴
          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>ahas-sentinel-client</artifactId>
              <version>1.8.8</version>
          </dependency>

          這里有個(gè)要注意的點(diǎn), AHAS 的依賴,包含了 Sentinel ,所需要使用到的依賴,包括 sentinel-core,sentinel-web-servletsentinel-transport-simple-http

          否則會(huì)出現(xiàn) Spi 異常 , 如果對(duì) Spi 不太了解,建議加群提問,嘿嘿~

          com.alibaba.csp.sentinel.spi.SpiLoaderException

          image.png
          image.png

          3.2、開啟阿里云AHAS 服務(wù)

          這里有官方的開通文檔,我就不贅述了,文檔地址

          在應(yīng)用防護(hù)這里找到 Lincense ,然后添加啟動(dòng)參數(shù):

          -Dserver.port=8092 -Dproject.name=jaycekon-sentinel -Dahas.license=d1e21b0c8f2e4d87b5ac460b118dc58d -Dcsp.sentinel.log.use.pid=true

          image.png

          由于我們要本地啟動(dòng)多實(shí)例, 因此需要修改服務(wù)的多個(gè)端口:

          java -Dserver.port=8090 -Dproject.name=jaycekon-sentinel -Dahas.license=d1e21b0c8f2e4d87b5ac460b118dc58d  -Dcsp.sentinel.log.use.pid=true -jar sentinel-ahas-0.0.1-SNAPSHOT.jar

          java -Dserver.port=8091 -Dproject.name=jaycekon-sentinel -Dahas.license=d1e21b0c8f2e4d87b5ac460b118dc58d  -Dcsp.sentinel.log.use.pid=true -jar sentinel-ahas-0.0.1-SNAPSHOT.jar

          java -Dserver.port=8092 -Dproject.name=jaycekon-sentinel -Dahas.license=d1e21b0c8f2e4d87b5ac460b118dc58d  -Dcsp.sentinel.log.use.pid=true -jar sentinel-ahas-0.0.1-SNAPSHOT.jar

          產(chǎn)生訪問流量后,可以在大盤看到機(jī)器的鏈接狀態(tài):

          http://localhost:8092/index

          image.png

          3.3、集群流控規(guī)則配置

          image.png

          這里有個(gè)兩個(gè)概念:

          • 集群閥值:指的是,我們集群總體能通過的訪問量,可能存在分配不均的情況(能避免單機(jī)誤限)。
          • 退化單機(jī):當(dāng) Token Server 訪問超時(shí),即無法從遠(yuǎn)端獲取令牌時(shí),回退到單機(jī)限流

          測試限流, 只訪問 http://localhost:8092/index

          通過手刷(手速過硬~),觸碰到限流的臨界值,然后整體限流跟我們預(yù)期一致。

          image.png

          退化單機(jī)

          在集群流控這里,有個(gè) Token 請求超時(shí)時(shí)間,Client 請求 Server ,然后返回?cái)?shù)據(jù)結(jié)果。整個(gè)流程會(huì)有網(wǎng)絡(luò)請求的耗時(shí),在上面的測試流程中,我將超時(shí)時(shí)間調(diào)大了,每次請求都能拿到Token, 通過修改請求超時(shí)時(shí)間,觸發(fā)退化 單機(jī)限流 。

          image.png

          運(yùn)行結(jié)果:

          image.png

          3.4、Server 角色轉(zhuǎn)換

          在內(nèi)嵌模式下,通過 HTTP API的方式,將角色轉(zhuǎn)換為 Serverclient

          http://<ip>:<port>/setClusterMode?mode=<xxx>

          其中 mode 為 0 代表 client,1 代表 server,-1 代表關(guān)閉。注意應(yīng)用端需要引入集群限流客戶端或服務(wù)端的相應(yīng)依賴。

          在獨(dú)立模式下,我們可以直接創(chuàng)建對(duì)應(yīng)的 ClusterTokenServer 實(shí)例并在 main 函數(shù)中通過 start 方法啟動(dòng) Token Server。

          Sentinel 熔斷

          秒殺系統(tǒng) 的案例中,一個(gè)完整的鏈路可能包含了 下訂單,支付物流對(duì)接等多個(gè)服務(wù)(實(shí)際上不止那么少)。在一個(gè)完整的鏈路中,各個(gè)系統(tǒng)通過 rpc/http的形式進(jìn)行交互,在下面的鏈路圖中,如果用戶選擇的 支付方式,存在延時(shí)過高,服務(wù)不穩(wěn)定,或服務(wù)異常等情況,會(huì)導(dǎo)致整個(gè)鏈路沒辦法完成。最終的結(jié)果就是,用戶明明搶到了,但是沒辦法支付,導(dǎo)致訂單丟失。

          image.png

          現(xiàn)代微服務(wù)架構(gòu)都是分布式的,由非常多的服務(wù)組成。不同服務(wù)之間相互調(diào)用,組成復(fù)雜的調(diào)用鏈路。以上的問題在鏈路調(diào)用中會(huì)產(chǎn)生放大的效果。復(fù)雜鏈路上的某一環(huán)不穩(wěn)定,就可能會(huì)層層級(jí)聯(lián),最終導(dǎo)致整個(gè)鏈路都不可用。因此我們需要對(duì)不穩(wěn)定的弱依賴服務(wù)調(diào)用進(jìn)行熔斷降級(jí),暫時(shí)切斷不穩(wěn)定調(diào)用,避免局部不穩(wěn)定因素導(dǎo)致整體的雪崩。熔斷降級(jí)作為保護(hù)自身的手段,通常在客戶端(調(diào)用端)進(jìn)行配置。

          1、熔斷降級(jí)

          添加測試代碼

              @RequestMapping("/myError")
              public String error(){
                  if (true){
                      throw new RuntimeException("sentinel run error");
                  }
                  return "error";
              }

          Sentinel-Dashboard中配置降級(jí)規(guī)則

          ![image-20210706005136317](/Users/huangweijie/Library/Application Support/typora-user-images/image-20210706005136317.png)

          ![image-20210706005159415](/Users/huangweijie/Library/Application Support/typora-user-images/image-20210706005159415.png)

          降級(jí)保護(hù)效果:

          用戶通過訪問接口 /myError , 出現(xiàn)一次異常后,在接下來的10秒 ,都會(huì)走降級(jí)策略,直接返回。能夠很好的保護(hù)服務(wù)端避免異常過多,占用機(jī)器資源。同時(shí)快速響應(yīng)用戶請求。

          2、熔斷策略

          Sentinel 提供以下幾種熔斷策略:

          • 慢調(diào)用比例 (SLOW_REQUEST_RATIO):選擇以慢調(diào)用比例作為閾值,需要設(shè)置允許的慢調(diào)用 RT(即最大的響應(yīng)時(shí)間),請求的響應(yīng)時(shí)間大于該值則統(tǒng)計(jì)為慢調(diào)用。當(dāng)單位統(tǒng)計(jì)時(shí)長(statIntervalMs)內(nèi)請求數(shù)目大于設(shè)置的最小請求數(shù)目,并且慢調(diào)用的比例大于閾值,則接下來的熔斷時(shí)長內(nèi)請求會(huì)自動(dòng)被熔斷。經(jīng)過熔斷時(shí)長后熔斷器會(huì)進(jìn)入探測恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個(gè)請求響應(yīng)時(shí)間小于設(shè)置的慢調(diào)用 RT 則結(jié)束熔斷,若大于設(shè)置的慢調(diào)用 RT 則會(huì)再次被熔斷。
          • 異常比例 (ERROR_RATIO):當(dāng)單位統(tǒng)計(jì)時(shí)長(statIntervalMs)內(nèi)請求數(shù)目大于設(shè)置的最小請求數(shù)目,并且異常的比例大于閾值,則接下來的熔斷時(shí)長內(nèi)請求會(huì)自動(dòng)被熔斷。經(jīng)過熔斷時(shí)長后熔斷器會(huì)進(jìn)入探測恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個(gè)請求成功完成(沒有錯(cuò)誤)則結(jié)束熔斷,否則會(huì)再次被熔斷。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%。
          • 異常數(shù) (ERROR_COUNT):當(dāng)單位統(tǒng)計(jì)時(shí)長內(nèi)的異常數(shù)目超過閾值之后會(huì)自動(dòng)進(jìn)行熔斷。經(jīng)過熔斷時(shí)長后熔斷器會(huì)進(jìn)入探測恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來的一個(gè)請求成功完成(沒有錯(cuò)誤)則結(jié)束熔斷,否則會(huì)再次被熔斷。

          總結(jié)

          本文主要詳細(xì)講解了一下 如何通過 Sentinel 去實(shí)際接觸 限流和熔斷,對(duì)于限流的底層實(shí)現(xiàn),后續(xù)會(huì)有專門的源碼分析篇。對(duì)于熔斷,本文也沒有細(xì)說個(gè)究竟,下一篇文章會(huì)給大家?guī)恚蹟嗍鞘裁?,在系統(tǒng)中到底是怎么實(shí)際使用,以及常見的熔斷策略。


          項(xiàng)目源碼地址:https://github.com/jaycekon/SpringBoot 
          歡迎  Star  和 Fork 

          點(diǎn)關(guān)注,不迷路

          好了各位,以上就是這篇文章的全部內(nèi)容了,我后面會(huì)每周都更新幾篇高質(zhì)量的大廠面試和常用技術(shù)棧相關(guān)的文章。感謝大伙能看到這里,如果這個(gè)文章寫得還不錯(cuò),  求三連?。?!創(chuàng)作不易,感謝各位的支持和認(rèn)可,我們下篇文章見!

          我是 九靈 ,有需要交流的童鞋可以 加我wx,Jayce-K,關(guān)注公眾號(hào):Java 補(bǔ)習(xí)課,掌握第一手資料!

          如果本篇博客有任何錯(cuò)誤,請批評(píng)指教,不勝感激 !


          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美另类成人在线 | 丁香花五月激 | 后入少妇正在播放 | 国产成人AV电影在线观看 | 中文字幕第7页 |