1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        從零搭建SpringCloud服務(wù)(史上最詳細(xì))

        共 15354字,需瀏覽 31分鐘

         ·

        2021-04-06 18:39

        來自:CSDN,作者:Anakki

        鏈接:https://blog.csdn.net/qq_29519041/article/details/85238270

        一、微服務(wù)基礎(chǔ)

        1.什么是SpringCloud?

        SpringCloud官網(wǎng):https://spring.io/projects/spring-cloud(個(gè)人建議是用谷歌瀏覽器訪問官網(wǎng)打開中文翻譯粗略把官網(wǎng)讀一遍)

        個(gè)人理解:

        以前的服務(wù)器就好像,一個(gè)會(huì)語數(shù)外全能的老師,為學(xué)生提供服務(wù),這個(gè)老師生病了,那全校停課。現(xiàn)在微服務(wù)流行后,學(xué)校有了數(shù)學(xué)教研組,語文教研組,外語教研組,每個(gè)教研組有一群老師具體負(fù)責(zé)某科的教學(xué),缺了誰,學(xué)校都照樣運(yùn)轉(zhuǎn)。

        而這個(gè)變化中,那些改變歷史的程序員就是把一個(gè)服務(wù)器中的眾多服務(wù),或好幾臺(tái)服務(wù)器中的眾多服務(wù),分類出來,解耦合出來,把他們類似的功能交給同一個(gè)集群來做,把互相耦合在一起的功能剝離出來,按業(yè)務(wù),按功能來把他們作為一個(gè)個(gè)微服務(wù)放在服務(wù)器上,而這個(gè)服務(wù)器就只提供一個(gè)服務(wù),或較少的服務(wù)。讓一個(gè)超大的服務(wù)邏輯,解耦合為一個(gè)個(gè)小服務(wù),均勻的分布在各自的服務(wù)器中。微服務(wù)就微在這。

        每個(gè)教研組就是一個(gè)微服務(wù)集群。他們提供同樣的服務(wù),而注冊(cè)中心Eureka就是這個(gè)存放這個(gè)教研組老師名單的地方,學(xué)生們想先訪問這個(gè)注冊(cè)中心獲取教師名單,然后根據(jù)相應(yīng)的負(fù)載方法去訪問各自老師。不至于讓集群中某一老師累死也不至于讓某一老師閑死。

        而Zuul網(wǎng)關(guān)呢,就是學(xué)校的門衛(wèi),某些學(xué)生來學(xué)校找誰,它負(fù)責(zé)指引(路由),并且通過一些非常簡單的配置,達(dá)到阻攔一些人進(jìn)入(身份驗(yàn)證),或者控制想學(xué)數(shù)學(xué)的人只能去數(shù)學(xué)教研組,不能去核能教研組學(xué)怎么造原子彈(權(quán)限驗(yàn)證)。

        那Hystrix熔斷器呢,可以把它當(dāng)成學(xué)校的志愿者,當(dāng)一個(gè)教研組集體罷課后,學(xué)生找不到老師了,這些志愿者及時(shí)的告訴來訪問的學(xué)生,相應(yīng)的結(jié)果,異常信息等,免得大量的學(xué)生在學(xué)校等待,這些志愿者趕快把這些等待的學(xué)生梳理出去,學(xué)生一直在學(xué)校等待,那其他需要學(xué)生的學(xué)校,也會(huì)等待學(xué)生,最后造成大面積的學(xué)校癱瘓。這里學(xué)生我們看成一個(gè)個(gè)請(qǐng)求。熔斷器就是把某事故的蔓延即使熔斷了。

        當(dāng)然這些組件也是微服務(wù)需要注冊(cè)到Eureka注冊(cè)中心

        那SpringCloud就可以看成是這個(gè)學(xué)校了。眾多上面提到的組件相當(dāng)于都是這個(gè)學(xué)校的各職能部門。

        二、微服務(wù)的搭建

        ps:  博主基于Maven+idea搭建。

        另外SpringCloud需要基于springboot搭建。

        引入Spring Boot相關(guān)依賴:這里的springboot用的是1.5.7版本;引入Spring Cloud相關(guān)依賴:這里為 Edgware.SR5

        2.1 工程初始化配置

        在Idea中創(chuàng)建工程:File -> New ->Project

        點(diǎn)擊   Empty Project -> Next

        項(xiàng)目命名 -> 項(xiàng)目位置

        選擇模組 modules ->next

        進(jìn)入新的窗口后,開始配置Maven,打開設(shè)置 setting

        因?yàn)槲抑白鲞^配置,因此只需要改變框1的路徑,如第一次配置需要自己找到你maven放置的位置,以及settings.xml,repository的位置,實(shí)在不會(huì)的百度  maven集成idea

        3個(gè)框選擇完畢后點(diǎn)擊 ok

        接下來新建module

        這里可能會(huì)出現(xiàn)加載不出archetype list的問題

        用了網(wǎng)上的所有解決辦法花了3個(gè)小時(shí)解決都沒用,重啟之后竟然可以了····你敢信?????小時(shí)候網(wǎng)吧網(wǎng)管的至理名言都忘了??!重啟一下嘛??!

        出來之后 選擇quickstart ->下一步

        名字自己想 想好后,復(fù)制一下你想好的  ArtifactId點(diǎn)擊Next,groupId為組織名 也是自己想一個(gè),一般為公司網(wǎng)址反寫。

        粘貼后下一步


        提供注冊(cè)服務(wù)的服務(wù)器pom.xml配置如下:

        <?xml version="1.0" encoding="UTF-8"?>
         
        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

          <modelVersion>4.0.0</modelVersion>
         
          <groupId>com.yun</groupId>
          <artifactId>springcloud-eureka-server</artifactId>
          <version>1.0-SNAPSHOT</version>
         
          <name>springcloud-eureka-server</name>
          <!-- FIXME change it to the project's website -->
          <url>http://www.example.com</url>
         
          <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.7</maven.compiler.source>
            <maven.compiler.target>1.7</maven.compiler.target>
          </properties>
         
          <!--引入springboot-parent父項(xiàng)目-->
          <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.7.RELEASE</version>
          </parent>
         
          <dependencies>
            <!--引入springcloud的euekea server依賴-->
            <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
         
          </dependencies>
         
         
          <!--指定下載源和使用springcloud的版本-->
          <dependencyManagement>
            <dependencies>
              <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.SR5</version>
                <type>pom</type>
                <scope>import</scope>
              </dependency>
            </dependencies>
          </dependencyManagement>
        </project>

        點(diǎn)擊Import Changes

        等待右下角加載springcloud的依賴

        2.2 Springboot的搭建 以及提供注冊(cè)服務(wù) 的 服務(wù)配置

        創(chuàng)建resources文件夾

        并設(shè)置作為資源根目錄,之后文件變成這樣之后文件夾變成有黃色的橫杠

        在resources下新建文件,文件名為application.yml    (對(duì)是yml  不是xml ,博主第一次學(xué)習(xí)時(shí),還以為是其他博主打錯(cuò)了,踩了一個(gè)小坑)

        配置yml,注意:如果只配置前兩行端口號(hào)信息會(huì)報(bào)錯(cuò)

        server:
          port: 8700 # 端口自己決定
          
        # 指定當(dāng)前eureka客戶端的注冊(cè)地址,也就是eureka服務(wù)的提供方,當(dāng)前配置的服務(wù)的注冊(cè)服務(wù)方
        eureka:
          client:
            service-url:
              defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
            register-with-eureka: false #自身 不在向eureka注冊(cè)
            fetch-registry: false  #啟動(dòng)時(shí)禁用client的注冊(cè)
          instance:
            hostname: localhost
         
        #指定應(yīng)用名稱
        spring:
          application:
            name: eureka-server

        知識(shí)補(bǔ)充:

        開發(fā)springboot的入口類 EurekaServerApplication.java

        EurekaServerApplication.java

        package com.yun;
         
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
         
        @SpringBootApplication
        @EnableEurekaServer //當(dāng)前使用eureka的server
        public class EurekaServerApplication {
            public static void main(String[] args) {
                SpringApplication.run(EurekaServerApplication.class,args);
            }
        }

        右鍵運(yùn)行當(dāng)前類:

        運(yùn)行成功console畫面

        嘗試進(jìn)入eureka管理界面 端口號(hào)為 yml里配置的(端口號(hào)自己設(shè)置 需要大于公用和保留的端口號(hào))1024~65535

        一般我喜歡設(shè)置為 8700到8800之間

        如下  管理界面已經(jīng)可以登錄了。搜索Java知音公眾號(hào),回復(fù)“后端面試”,送你一份Java面試題寶典.pdf

        2.3 客戶端client  提供真正服務(wù)的角色的配置, 它提供服務(wù) 在 服務(wù)注冊(cè)方server (注冊(cè)中心)進(jìn)行注冊(cè)

        同樣新建module,選擇quickstart點(diǎn)擊下一步

        兩個(gè)位置 置空

        取名 下一步

        注意這里要在根目錄springcloud 下創(chuàng)建模組,content root 會(huì)默認(rèn)在之前的模組之下創(chuàng)建模組 這樣創(chuàng)建模組會(huì)出現(xiàn)問題并報(bào)錯(cuò)

        推薦這種配置方法  在content root下springcloud后改名字   如下圖配置點(diǎn)下一步,紅框處一般默認(rèn)為上一個(gè)模組的文件目錄名,需要改為你的模組名

        成功后為并列狀態(tài),如不為并列或報(bào)錯(cuò)請(qǐng)重新配置

        配置servicesupport的pom,與server的pom配置相同,只需要把第一個(gè)pom的1的方框處server改為client

        和第一個(gè)微服務(wù)同理 我們需要配置入口類 pom.xml  application.yml,因?yàn)槭欠?wù)提供者,這里還需編寫服務(wù)類controller

        application.yml

        server:
          port: 8701 # 服務(wù)提供方
         
        # 指定當(dāng)前eureka客戶端的注冊(cè)地址,
        eureka:
          client:
            service-url:
              defaultZone: http://${eureka.instance.hostname}:8700/eureka
          instance:
            hostname: localhost
         
        #當(dāng)前服務(wù)名稱
        spring:
          application:
            name: eureka-service

        pom.xml:

        編寫所提供的 服務(wù)controller:

        package com.yun;
         
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
         
        @RestController
        @RequestMapping("/Hello")
        public class Controller {
            @RequestMapping("/World")
            public String helloWorld(String s){
                System.out.println("傳入的值為:"+s);
                return "傳入的值為:"+s;
            }
        }

        入口類 并運(yùn)行此微服務(wù):

        package com.yun;
         
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
         
        @SpringBootApplication
        @EnableDiscoveryClient//代表自己是一個(gè)服務(wù)提供方
        public class EurekaServiceApplication {
            public static void main(String[] args) {
                SpringApplication.run(EurekaServiceApplication.class,args);
            }
        }

        右鍵入口類名點(diǎn)擊 run(當(dāng)然開啟此服務(wù)時(shí)需要先開啟server服務(wù) 就是我們第一個(gè)編寫的微服務(wù))

        此時(shí)再進(jìn)入服務(wù)注冊(cè)的頁面 http://localhost:8700/

        可以看見服務(wù)提供者已被注冊(cè)進(jìn) 服務(wù)注冊(cè)者

        在直接訪問一下服務(wù)提供者的 網(wǎng)絡(luò)位置http://localhost:8701/Hello/World?s=小沛

        我們已經(jīng)看見 可以訪問了,證明此微服務(wù)可用。

        但是我們一般不直接調(diào)用所需的微服務(wù),而是經(jīng)過提供注冊(cè)服務(wù)的服務(wù)器server,獲取所需的服務(wù)提供者列表(為一個(gè)列表,此列表包含了能提供相應(yīng)服務(wù)的服務(wù)器),他們也許是個(gè)集群,因此server會(huì)返回一個(gè) ip+端口號(hào)的表,服務(wù)消費(fèi)者通過相應(yīng)算法訪問這表上的不同服務(wù)器,這些服務(wù)器提供的是相同的服務(wù),這種在服務(wù)消費(fèi)者一方挑選服務(wù)器為自己服務(wù)的方式是一種客戶端的負(fù)載均衡。

        目前博主所知的有 輪詢和隨機(jī)兩種方式 訪問這些服務(wù)器,輪詢就是循環(huán)的意思,假如有3臺(tái)服務(wù)器,訪問方式就是1,2,3,1,2,3,1,2,3····,隨機(jī)就是隨機(jī),回想一下random方法,一種無規(guī)律的方式。這兩種方式都是為了,訪問每個(gè)服務(wù)器的可能性盡量的相同。還有權(quán)重負(fù)載這種算法,意思就是 根據(jù)服務(wù)器負(fù)載能力的分配相應(yīng)的服務(wù)。能力大的干得多。能力小的干得少。

        搜索Java知音公眾號(hào),回復(fù)“后端面試”,送你一份Java面試題寶典.pdf

        2.4 服務(wù)的調(diào)用方式

        第一種調(diào)用方式:restTemplate+ribbon

        第二種調(diào)用方式:feign

        2.4.1 restTemplate+ribbon

        ribbon是一種負(fù)載均衡的客戶端,它是什么呢?請(qǐng)?jiān)斪xhttps://www.jianshu.com/p/1bd66db5dc46

        可以看見其中的一段如下:

        而客戶端負(fù)載均衡和服務(wù)端負(fù)載均衡最大的不同點(diǎn)在于上面所提到服務(wù)清單所存儲(chǔ)的位置。在客戶端負(fù)載均衡中,所有客戶端節(jié)點(diǎn)都維護(hù)著自己要訪問的服務(wù)端清單,而這些服務(wù)端端清單來自于服務(wù)注冊(cè)中心,比如上一章我們介紹的Eureka服務(wù)端。同服務(wù)端負(fù)載均衡的架構(gòu)類似,在客戶端負(fù)載均衡中也需要心跳去維護(hù)服務(wù)端清單的健康性,默認(rèn)會(huì)創(chuàng)建針對(duì)各個(gè)服務(wù)治理框架的Ribbon自動(dòng)化整合配置,比如Eureka中的org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,Consul中的org.springframework.cloud.consul.discovery.RibbonConsulAutoConfiguration。在實(shí)際使用的時(shí)候,我們可以通過查看這兩個(gè)類的實(shí)現(xiàn),以找到它們的配置詳情來幫助我們更好地使用它。

        接下來我們來搭建基于ribbon的客戶端,他用于消費(fèi)服務(wù)。

        同理先搭建springboot的環(huán)境

        與之前搭建servicesupport不同的是:

        第一步:現(xiàn)在pom中需要在dependencies中添加ribbon依賴

                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-ribbon</artifactId>
                </dependency>

        第二步:yml如下配置:

        server:
          port: 8702 # 服務(wù)消費(fèi)方
         
        # 指定當(dāng)前eureka客戶端的注冊(cè)地址,
        eureka:
          client:
            service-url:
              defaultZone: http://${eureka.instance.hostname}:8700/eureka
          instance:
            hostname: localhost
         
        #當(dāng)前服務(wù)名稱
        spring:
          application:
            name: eureka-consumer

        服務(wù)的消費(fèi)方依舊需要在注冊(cè)方8700端口去注冊(cè)。配置當(dāng)前服務(wù)消費(fèi)方的端口8072,名字為eureka-consumer

        第三步:依舊需要啟動(dòng)類,因?yàn)樗且粋€(gè)springboot的架構(gòu):

        package com.yun;
         
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
         
         
        @SpringBootApplication
        @EnableDiscoveryClient //當(dāng)前使用eureka的server
        public class EurekaConsumerApplication {
            public static void main(String[] args) {
                SpringApplication.run(EurekaConsumerApplication.class,args);
            }
        }

        如上圖:

        我們需要一個(gè)controller類來編寫ribbon的代碼。

        package com.yun.controller;
         
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.cloud.client.ServiceInstance;
        import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        import org.springframework.web.client.RestTemplate;
         
        @RestController
        @RequestMapping("/Hello")
        class ConsumerController {
            @Autowired
            private LoadBalancerClient loadBalancerClient;
            @Autowired
            private RestTemplate restTemplate;
            @RequestMapping("/Consumer")
            public String helloWorld(String s){
                System.out.println("傳入的值為:"+s);
                //第一種調(diào)用方式
                //String forObject = new RestTemplate().getForObject("http://localhost:8071/Hello/World?s=" + s, String.class);
         
                //第二種調(diào)用方式
                //根據(jù)服務(wù)名 獲取服務(wù)列表 根據(jù)算法選取某個(gè)服務(wù) 并訪問某個(gè)服務(wù)的網(wǎng)絡(luò)位置。
                //ServiceInstance serviceInstance = loadBalancerClient.choose("EUREKA-SERVICE");
                //String forObject = new RestTemplate().getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/Hello/World?s="+s,String.class);
         
                //第三種調(diào)用方式 需要restTemplate注入的方式
                String forObject = restTemplate.getForObject("http://EUREKA-SERVICE/Hello/World?s=" + s, String.class);
                return forObject;
            }
        }

        我們常用第三種調(diào)用方式。

        第一種是直接調(diào)用:不經(jīng)過注冊(cè)中心那服務(wù)列表,直接訪問的servicesupport

        第二種:是根據(jù)服務(wù)名選擇調(diào)用,如上圖需要做如下注入

        @Autowired
            private LoadBalancerClient loadBalancerClient;

        如上圖代碼中第二種調(diào)用方法的代碼所示。

        用服務(wù)名去注冊(cè)中心獲取服務(wù)列表,當(dāng)前客戶端底層會(huì)做隨機(jī)算法的選取獲得服務(wù)并訪問。

        第三種需要一個(gè)@Bean的注解自動(dòng)注入并直接調(diào)用restTemplate對(duì)象調(diào)用服務(wù)。底層調(diào)用模式與第二種調(diào)用方式一樣。如下:

        package com.yun.beans;
         
        import org.springframework.cloud.client.loadbalancer.LoadBalanced;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.client.RestTemplate;
         
        @Configuration
        public class Beans {
            //管理簡單對(duì)象
            @Bean
            @LoadBalanced
            public RestTemplate getRestTemplate(){
                return new RestTemplate();
            }
        }

        @Bean注解告訴工廠,這個(gè)方法需要自動(dòng)注入。

        @LoadBalanced,表示需要做負(fù)載勻衡。

        然后如controller中一樣注入一下restTemplate,并且使用他,區(qū)別是可以直接使用服務(wù)名訪問了

        String forObject = restTemplate.getForObject("http://EUREKA-SERVICE/Hello/World?s=" + s, String.class);

        開始測(cè)試:

        1.運(yùn)行server的啟動(dòng)類:

        2.運(yùn)行servicesupport的啟動(dòng)類:

        3.運(yùn)行serviceconsume的啟動(dòng)類:

        瀏覽器訪問:

        8072為服務(wù)消費(fèi)方的端口

        訪問方法解析:

        • 訪問服務(wù)消費(fèi)方@RequestMapping指定的路徑及消費(fèi)方的端口來訪問消費(fèi)方的controller

        • controller根據(jù)服務(wù)名去server方獲取獲取服務(wù)列表,獲取服務(wù)列表后根據(jù)隨機(jī)的模式負(fù)載勻衡后去選擇服務(wù)地址去訪問servicesupport:如下圖

        ----------    更新于星期日2018年12月30日 20:02    待續(xù)....---------

        待續(xù)...

        2.5   Eureka server的高可用配置

        點(diǎn)擊下圖配置

        接下來配置三臺(tái)01,02,03的虛擬機(jī)參數(shù)

        01:8699

        02:8698

        03:8697

        之后點(diǎn)ok保存,可看見多出三個(gè)啟動(dòng)項(xiàng)

        接下來分別改注冊(cè)端口號(hào),defaultZone分別啟動(dòng)三個(gè)啟動(dòng)項(xiàng)

        打開server的yml配置,刪掉前兩行端口號(hào)配置(圖中有錯(cuò),請(qǐng)把instance 和hostname那兩行刪掉)

        配置好yml后點(diǎn)擊啟動(dòng)

        同理,我們?cè)俅胃膭?dòng)端口號(hào)為8699和8697后,把啟動(dòng)項(xiàng)改為02,之后啟動(dòng)(圖中有錯(cuò),請(qǐng)把instance 和hostname那兩行刪掉)

        同理把yml端口改為8699 和 8698后,把啟動(dòng)項(xiàng)改為03,之后啟動(dòng)(圖中有錯(cuò),請(qǐng)把instance 和hostname那兩行刪掉)

        啟動(dòng)后分別訪問三個(gè)01,02,03端口,已經(jīng)可以看見可以訪問了。

        打開服務(wù)提供方的yml配置如下,把端口號(hào)改為三個(gè)中其中的一個(gè)。

        啟動(dòng)服務(wù)提供方之后,再次訪問三個(gè)01,02,03我們會(huì)發(fā)現(xiàn)

        重點(diǎn):即使服務(wù)提供方只注冊(cè)了一個(gè)端口號(hào)8699,但是另外兩個(gè)端口號(hào),也能感知到服務(wù)提供方8701的存在了。如下圖:

        接下來像服務(wù)消費(fèi)方中添加服務(wù)注冊(cè)者的端口號(hào),這樣在server掛掉任何一個(gè)的時(shí)候,都能有其他的server也能獲取服務(wù)列表

        訪問以下服務(wù)消費(fèi)方,發(fā)現(xiàn)可以通過消費(fèi)方調(diào)用server服務(wù)列表并且訪問service了

        我么隨便關(guān)閉其中兩個(gè)server的副本,重啟serviceconsume,再進(jìn)行訪問。必須重啟serviceconsume才能清空緩存,清掉consume里面有的服務(wù)列表。

        上圖發(fā)現(xiàn)即使關(guān)閉兩臺(tái)server后依舊可以訪問,如下圖,依舊從server中獲取了服務(wù)列表,從中也能看見之后不用再獲取服務(wù)列表了。

        但是當(dāng)我們關(guān)掉所有server后。訪問還是沒問題,因?yàn)榫彺媪朔?wù)列表。

        但是讓我們來重啟一下serviceconsume,再訪問就不行了。

        綜上我們就完成了springcloud中server的高可用配置

        搭好了別忘點(diǎn)贊呀~

        --完--
        推薦閱讀:
        怎么接私貨?這個(gè)渠道你100%有用!請(qǐng)收藏!

        點(diǎn)個(gè)在看 
        瀏覽 29
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产高清码 在线观看 | 欧美性爱人人操 | 欧美性爱无码在线 | 国产按摩店一级毛片 | 高h男女邻居1v1 | 国产成人午夜精品A片21p漫画 | 一级片视频免费 | 水果派解说AV无码一区 | 欧美一级婬片免费视频日日木 | 免费啪啪网 |