日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringCloud(笔记)

發布時間:2023/12/3 javascript 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringCloud(笔记) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

學習前提

  • 熟練使用SpringBoot 微服務快速開發框架

  • 了解過Dubbo + Zookeeper 分布式基礎

  • 電腦配置內存不低于8G(我自己的是16G)

    • 給大家看下多個服務跑起來后的內存開銷圖:

文章大綱

微服務架構面臨的四個核心問題?

1.服務很多,客戶端應該如何訪問? API網關

2.這么多服務?服務之間如何通信? HTTP,RPC通信

3.這么多服務?如何治理? 服務注冊與發現

4.服務掛了怎么辦?熔斷機制

Spring Cloud 五大組件

  • 服務注冊與發現——Netflix Eureka
  • 負載均衡:
    • 客戶端負載均衡——Netflix Ribbon
    • 服務端負載均衡:——Feign(其也是依賴于Ribbon,只是將調用方式RestTemplete 更改成Service 接口)
  • 斷路器——Netflix Hystrix
  • 服務網關——Netflix Zuul
  • 分布式配置——Spring Cloud Config

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qZHjHspt-1610725250868)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210114163141181.png)]

1.3 常見面試題

1.1 什么是微服務?

1.2 微服務之間是如何獨立通訊的?

1.3 SpringCloud 和 Dubbo有那些區別?

1.4 SpringBoot 和 SpringCloud,請談談你對他們的理解

1.5 什么是服務熔斷?什么是服務降級?

1.6 微服務的優缺點分別是什么?說下你在項目開發中遇到的坑

1.7 你所知道的微服務技術棧有哪些?列舉一二

1.8 Eureka和Zookeeper都可以提供服務注冊與發現的功能,請說說兩者的區別

微服務概述

什么是微服務?

什么是微服務?

微服務(Microservice Architecture) 是近幾年流行的一種架構思想,關于它的概念很難一言以蔽之。

究竟什么是微服務呢?我們在此引用ThoughtWorks 公司的首席科學家 Martin Fowler 于2014年提出的一段話:

原文:https://martinfowler.com/articles/microservices.html

漢化:https://www.cnblogs.com/liuning8023/p/4493156.html

  • 就目前而言,對于微服務,業界并沒有一個統一的,標準的定義。
  • 但通常而言,微服務架構是一種架構模式,或者說是一種架構風格,它體長將單一的應用程序劃分成一組小的服務,每個服務運行在其獨立的自己的進程內,服務之間互相協調,互相配置,為用戶提供最終價值,服務之間采用輕量級的通信機制(HTTP)互相溝通,每個服務都圍繞著具體的業務進行構建,并且能狗被獨立的部署到生產環境中,另外,應盡量避免統一的,集中式的服務管理機制,對具體的一個服務而言,應該根據業務上下文,選擇合適的語言,工具(Maven)對其進行構建,可以有一個非常輕量級的集中式管理來協調這些服務,可以使用不同的語言來編寫服務,也可以使用不同的數據存儲。

再來從技術維度角度理解下:

  • 微服務化的核心就是將傳統的一站式應用,根據業務拆分成一個一個的服務,徹底地去耦合,每一個微服務提供單個業務功能的服務,一個服務做一件事情,從技術角度看就是一種小而獨立的處理過程,類似進程的概念,能夠自行單獨啟動或銷毀,擁有自己獨立的數據庫。

微服務與微服務架構

微服務

強調的是服務的大小,它關注的是某一個點,是具體解決某一個問題/提供落地對應服務的一個服務應用,狹義的看,可以看作是IDEA中的一個個微服務工程,或者Moudel。IDEA 工具里面使用Maven開發的一個個獨立的小Moudel,它具體是使用SpringBoot開發的一個小模塊,專業的事情交給專業的模塊來做,一個模塊就做著一件事情。強調的是一個個的個體,每個個體完成一個具體的任務或者功能。

微服務架構

一種新的架構形式,Martin Fowler 于2014年提出。

微服務架構是一種架構模式,它體長將單一應用程序劃分成一組小的服務,服務之間相互協調,互相配合,為用戶提供最終價值。每個服務運行在其獨立的進程中,服務與服務之間采用輕量級的通信機制**(如HTTP)互相協作,每個服務都圍繞著具體的業務進行構建,并且能夠被獨立的部署到生產環境中,另外,應盡量避免統一的,集中式的服務管理機制,對具體的一個服務而言,應根據業務上下文,選擇合適的語言、工具(如Maven)**對其進行構建。

微服務優缺點

優點

  • 單一職責原則;
  • 每個服務足夠內聚,足夠小,代碼容易理解,這樣能聚焦一個指定的業務功能或業務需求;
  • 開發簡單,開發效率高,一個服務可能就是專一的只干一件事;
  • 微服務能夠被小團隊單獨開發,這個團隊只需2-5個開發人員組成;
  • 微服務是松耦合的,是有功能意義的服務,無論是在開發階段或部署階段都是獨立的;
  • 微服務能使用不同的語言開發;
  • 易于和第三方集成,微服務允許容易且靈活的方式集成自動部署,通過持續集成工具,如jenkins,Hudson,bamboo;
  • 微服務易于被一個開發人員理解,修改和維護,這樣小團隊能夠更關注自己的工作成果,無需通過合作才能體現價值;
  • 微服務允許利用和融合最新技術;
  • 微服務只是業務邏輯的代碼,不會和HTML,CSS,或其他的界面混合;
  • 每個微服務都有自己的存儲能力,可以有自己的數據庫,也可以有統一的數據庫;

缺點

  • 開發人員要處理分布式系統的復雜性;
  • 多服務運維難度,隨著服務的增加,運維的壓力也在增大;
  • 系統部署依賴問題;
  • 服務間通信成本問題;
  • 數據一致性問題;
  • 系統集成測試問題;
  • 性能和監控問題;

微服務技術棧有那些?

微服務技術條目落地技術
服務開發SpringBoot、Spring、SpringMVC等
服務配置與管理Netfix公司的Archaius、阿里的Diamond等
服務注冊與發現Eureka、Consul、Zookeeper等
服務調用Rest、PRC、gRPC
服務熔斷器Hystrix、Envoy等
負載均衡Ribbon、Nginx等
服務接口調用(客戶端調用服務的簡化工具)Fegin等
消息隊列Kafka、RabbitMQ、ActiveMQ等
服務配置中心管理SpringCloudConfig、Chef等
服務路由(API網關)Zuul等
服務監控Zabbix、Nagios、Metrics、Specatator等
全鏈路追蹤Zipkin、Brave、Dapper等
數據流操作開發包SpringCloud Stream(封裝與Redis,Rabbit,Kafka等發送接收消息)
時間消息總棧SpringCloud Bus
服務部署Docker、OpenStack、Kubernetes等

為什么選擇SpringCloud作為微服務架構

  • 選型依據

    • 整體解決方案和框架成熟度
    • 社區熱度
    • 可維護性
    • 學習曲線
  • 當前各大IT公司用的微服務架構有那些?

    • 阿里:dubbo+HFS

    • 京東:JFS

    • 新浪:Motan

    • 當當網:DubboX

  • 各微服務框架對比

  • 功能點/服務框架Netflix/SpringCloudMotangRPCThri tDubbo/DubboX
    功能定位完整的微服務框架RPC框架,但整合了ZK或Consul,實現集群環境的基本服務注冊發現RPC框架RPC框架服務框架
    支持Rest是,Ribbon支持多種可拔插的序列號選擇
    支持RPC是(Hession2)
    支持多語言是(Rest形式)
    負載均衡是(服務端zuul+客戶端Ribbon),zuul-服務,動態路由,云端負載均衡Eureka(針對中間層服務器)是(客戶端)是(客戶端)
    配置服務Netfix Archaius,Spring Cloud Config Server 集中配置是(Zookeeper提供)
    服務調用鏈監控是(zuul),zuul提供邊緣服務,API網關
    高可用/容錯是(服務端Hystrix+客戶端Ribbon)是(客戶端)是(客戶端)
    典型應用案例NetflixSinaGoogleFacebook
    社區活躍程度一般一般2017年后重新開始維護,之前中斷了5年
    學習難度中等
    文檔豐富程度一般一般一般
    其他Spring Cloud Bus為我們的應用程序帶來了更多管理端點支持降級Netflix內部在開發集成gRPCIDL定義實踐的公司比較多

    SpringCloud入門概述

    SpringCloud是什么?

    Spring官網:https://spring.io/

    SpringCloud和SpringBoot的關系

    • SpringBoot專注于開蘇方便的開發單個個體微服務;-jar
    • SpringCloud是關注全局的微服務協調整理治理框架,它將SpringBoot開發的一個個單體微服務,整合并管理起來,為各個微服務之間提供:配置管理、服務發現、斷路器、路由、為代理、事件總棧、全局鎖、決策競選、分布式會話等等集成服務;
    • SpringBoot可以離開SpringCloud獨立使用,開發項目,但SpringCloud離不開SpringBoot,屬于依賴關系;
    • SpringBoot專注于快速、方便的開發單個個體微服務,SpringCloud關注全局的服務治理框架;

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-thoChIwl-1610725250901)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210114165746964.png)]

    Dubbo 和 SpringCloud技術選型

  • 分布式+服務治理Dubbo
  • 目前成熟的互聯網架構,應用服務化拆分 + 消息中間件

  • Dubbo 和 SpringCloud對比
  • 可以看一下社區活躍度:

    https://github.com/dubbo

    https://github.com/spring-cloud

    對比結果:

    DubboSpringCloud
    服務注冊中心ZookeeperSpring Cloud Netfilx Eureka
    服務調用方式RPCREST API
    服務監控Dubbo-monitorSpring Boot Admin
    斷路器不完善Spring Cloud Netfilx Hystrix
    服務網關Spring Cloud Netfilx Zuul
    分布式配置Spring Cloud Config
    服務跟蹤Spring Cloud Sleuth
    消息總棧Spring Cloud Bus
    數據流Spring Cloud Stream
    批量任務Spring Cloud Task

    最大區別:Spring Cloud 拋棄了Dubbo的RPC通信,采用的是基于HTTP的REST方式

    嚴格來說,這兩種方式各有優劣。雖然從一定程度上來說,后者犧牲了服務調用的性能,但也避免了上面提到的原生RPC帶來的問題。而且REST相比RPC更為靈活,服務提供方和調用方的依賴只依靠一紙契約,不存在代碼級別的強依賴,這個優點在當下強調快速演化的微服務環境下,顯得更加合適。

    品牌機和組裝機的區別

    社區支持與更新力度的區別

    **總結:**二者解決的問題域不一樣:Dubbo的定位是一款RPC框架,而SpringCloud的目標是微服務架構下的一站式解決方案。

    SpringCloud作用

    • Distributed/versioned configuration 分布式/版本控制配置
    • Service registration and discovery 服務注冊與發現
    • Routing 路由
    • Service-to-service calls 服務到服務的調用
    • Load balancing 負載均衡配置
    • Circuit Breakers 斷路器
    • Distributed messaging 分布式消息管理

    3.5 SpringCloud下載

    官網:http://projects.spring.io/spring-cloud/

    版本號有點特別:

    SpringCloud沒有采用數字編號的方式命名版本號,而是采用了倫敦地鐵站的名稱,同時根據字母表的順序來對應版本時間順序,比如最早的Realse版本:Angel,第二個Realse版本:Brixton,然后是Camden、Dalston、Edgware,目前最新的是Hoxton SR4 CURRENT GA通用穩定版。

    自學參考書:

    • SpringCloud Netflix 中文文檔:https://springcloud.cc/spring-cloud-netflix.html
    • SpringCloud 中文API文檔(官方文檔翻譯版):https://springcloud.cc/spring-cloud-dalston.html
    • SpringCloud中國社區:http://springcloud.cn/
    • SpringCloud中文網:https://springcloud.cc

    Rest環境搭建:服務提供者和消費者

    4.1 介紹

    • 我們會使用一個Dept部門模塊做一個微服務通用案例Consumer消費者(Client)通過REST調用Provider提供者(Server)提供的服務。
    • 回顧Spring,SpringMVC,Mybatis等以往學習的知識。
    • Maven的分包分模塊架構復習。
    一個簡單的Maven模塊結構是這樣的:-- app-parent: 一個父項目(app-parent)聚合了很多子項目(app-util\app-dao\app-web...)|-- pom.xml||-- app-core||---- pom.xml||-- app-web||---- pom.xml......

    一個父工程帶著多個Moudule子模塊

    MicroServiceCloud父工程(Project)下初次帶著3個子模塊(Module)

    • microservicecloud-api 【封裝的整體entity/接口/公共配置等】
    • microservicecloud-consumer-dept-80 【服務消費者】
    • microservicecloud-provider-dept-8001 【服務提供者】

    版本選擇

    大版本說明

    SpringBootSpringCloud關系
    1.2.xAngel版本(天使)兼容SpringBoot1.2x
    1.3.xBrixton版本(布里克斯頓)兼容SpringBoot1.3x,也兼容SpringBoot1.4x
    1.4.xCamden版本(卡姆登)兼容SpringBoot1.4x,也兼容SpringBoot1.5x
    1.5.xDalston版本(多爾斯頓)兼容SpringBoot1.5x,不兼容SpringBoot2.0x
    1.5.xEdgware版本(埃奇韋爾)兼容SpringBoot1.5x,不兼容SpringBoot2.0x
    2.0.xFinchley版本(芬奇利)兼容SpringBoot2.0x,不兼容SpringBoot1.5x
    2.1.xGreenwich版本(格林威治)

    實際開發版本關系

    spring-boot-starter-parentspring-cloud-dependencles
    版本號發布日期版本號發布日期
    1.5.2.RELEASE2017-03Dalston.RC12017-x
    1.5.9.RELEASE2017-11Edgware.RELEASE2017-11
    1.5.16.RELEASE2018-04Edgware.SR52018-10
    1.5.20.RELEASE2018-09Edgware.SR52018-10
    2.0.2.RELEASE2018-05Fomchiey.BULD-SNAPSHOT2018-x
    2.0.6.RELEASE2018-10Fomchiey-SR22018-10
    2.1.4.RELEASE2019-04Greenwich.SR12019-03

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YQMJStT4-1610725250911)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210114191102105.png)]

    使用后兩個

    創建父工程

    • 新建父工程項目springcloud,切記Packageing是pom模式
    • 主要是定義POM文件,將后續各個子模塊公用的jar包等統一提取出來,類似一個抽象父類

    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.haust</groupId><artifactId>springcloud</artifactId><version>1.0-SNAPSHOT</version><modules><module>springcloud-api</module><module>springcloud-provider-dept-8001</module><module>springcloud-consumer-dept-80</module><module>springcloud-eureka-7001</module><module>springcloud-eureka-7002</module><module>springcloud-eureka-7003</module><module>springcloud-provider-dept-8002</module><module>springcloud-provider-dept-8003</module><module>springcloud-consumer-dept-feign</module><module>springcloud-provider-dept-hystrix-8001</module><module>springcloud-consumer-hystrix-dashboard</module><module>springcloud-zuul-9527</module><module>springcloud-config-server-3344</module><module>springcloud-config-client-3355</module><module>springcloud-config-eureka-7001</module><module>springcloud-config-dept-8001</module></modules><!--打包方式 pom--><packaging>pom</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><junit.version>4.12</junit.version><log4j.version>1.2.17</log4j.version><lombok.version>1.16.18</lombok.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>0.2.0.RELEASE</version><type>pom</type><scope>import</scope></dependency><!--springCloud的依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.SR1</version><type>pom</type><scope>import</scope></dependency><!--SpringBoot--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.1.4.RELEASE</version><type>pom</type><scope>import</scope></dependency><!--數據庫--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!--SpringBoot 啟動器--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><!--日志測試~--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency></dependencies></dependencyManagement></project>

    父工程為springcloud,其下有多個子mudule,詳情參考完整代碼了解

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HFnBrn3k-1610725250913)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210114203950885.png)]

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Rt1agP63-1610725250915)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210114205910420.png)]

    springcloud-provider-dept-8001(提供者)

    server:port: 8001 mybatis:type-aliases-package: com.kuang.springcloud.pojoconfig-location: classpath:mybatis/mapper-config.xmlmapper-locations: classpath:mybatis/mapper/*.xml# spring配置 spring:application:name: springcloud-provider-deptdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db01?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTCusername: rootpassword: 123456

    springcloud-consumer-dept-80訪問springcloud-provider-dept-8001下的controller使用REST方式

    springcloud-consumer-dept-80(消費者)

    80端口請求的時候不用帶端口號

    DeptConsumerController.java

    /*** @Auther: csp1999* @Date: 2020/05/17/22:44* @Description:*/ @RestController public class DeptConsumerController {/*** 理解:消費者,不應該有service層~* RestTemplate .... 供我們直接調用就可以了! 注冊到Spring中* (地址:url, 實體:Map ,Class<T> responseType)* <p>* 提供多種便捷訪問遠程http服務的方法,簡單的Restful服務模板~*/@Autowiredprivate RestTemplate restTemplate;/*** 服務提供方地址前綴* <p>* Ribbon:我們這里的地址,應該是一個變量,通過服務名來訪問*/private static final String REST_URL_PREFIX = "http://localhost:8001";//private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";/*** 消費方添加部門信息* @param dept* @return*/@RequestMapping("/consumer/dept/add")public boolean add(Dept dept) {// postForObject(服務提供方地址(接口),參數實體,返回類型.class)return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);}/*** 消費方根據id查詢部門信息* @param id* @return*/@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id) {// getForObject(服務提供方地址(接口),返回類型.class)return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);}/*** 消費方查詢部門信息列表* @return*/@RequestMapping("/consumer/dept/list")public List<Dept> list() {return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);} }

    RestTemplete

    使用RestTemplete先需要放入Spring容器中

    提供多種便捷訪問遠程http服務的方法,簡單的Restful服務模板~

    ConfigBean.java

    @Configuration public class ConfigBean {//@Configuration -- spring applicationContext.xml//配置負載均衡實現RestTemplate// IRule// RoundRobinRule 輪詢// RandomRule 隨機// AvailabilityFilteringRule : 會先過濾掉,跳閘,訪問故障的服務~,對剩下的進行輪詢~// RetryRule : 會先按照輪詢獲取服務~,如果服務獲取失敗,則會在指定的時間內進行,重試@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();} }

    springcloud-provider-dept-8001的dao接口調用springcloud-api模塊下的pojo,可使用在springcloud-provider-dept-8001的pom文件導入springcloud-api模塊依賴的方式:

    <!--我們需要拿到實體類,所以要配置api module--><dependency><groupId>com.haust</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency>

    springcloud-consumer-dept-80和springcloud-provider-dept-8001的pom.xml和父工程下的依賴基本一樣,直接看完整代碼即可,不再添加重復筆記。

    進行測試

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ccdx5yrc-1610725250918)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210114231512178.png)]

    Eureka服務注冊中心

    5.1 什么是Eureka

    • Netflix在涉及Eureka時,遵循的就是API原則.
    • Eureka是Netflix的有個子模塊,也是核心模塊之一。Eureka是基于REST的服務,用于定位服務,以實現云端中間件層服務發現和故障轉移,服務注冊與發現對于微服務來說是非常重要的,有了服務注冊與發現,只需要使用服務的標識符,就可以訪問到服務,而不需要修改服務調用的配置文件了,功能類似于Dubbo的注冊中心,比如Zookeeper.

    原理

    • Eureka基本的架構
      • Springcloud 封裝了Netflix公司開發的Eureka模塊來實現服務注冊與發現 (對比Zookeeper).
      • Eureka采用了C-S的架構設計,EurekaServer作為服務注冊功能的服務器,他是服務注冊中心.
      • 而系統中的其他微服務,使用Eureka的客戶端連接到EurekaServer并維持心跳連接。這樣系統的維護人員就可以通過EurekaServer來監控系統中各個微服務是否正常運行,Springcloud 的一些其他模塊 (比如Zuul) 就可以通過EurekaServer來發現系統中的其他微服務,并執行相關的邏輯.

    • 和Dubbo架構對比.

    • Eureka 包含兩個組件:Eureka ServerEureka Client.

    • Eureka Server 提供服務注冊,各個節點啟動后,回在EurekaServer中進行注冊,這樣Eureka Server中的服務注冊表中將會儲存所有課用服務節點的信息,服務節點的信息可以在界面中直觀的看到.

    • Eureka Client 是一個Java客戶端,用于簡化EurekaServer的交互,客戶端同時也具備一個內置的,使用輪詢負載算法的負載均衡器。在應用啟動后,將會向EurekaServer發送心跳 (默認周期為30秒) 。如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,EurekaServer將會從服務注冊表中把這個服務節點移除掉 (默認周期為90s).

    • 三大角色

      • Eureka Server:提供服務的注冊與發現
      • Service Provider:服務生產方,將自身服務注冊到Eureka中,從而使服務消費方能狗找到
      • Service Consumer:服務消費方,從Eureka中獲取注冊服務列表,從而找到消費服務
    • 目前工程狀況

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tJMcXLHL-1610725250919)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210114232936013.png)]

    eureka-server

  • springcloud-eureka-7001 模塊建立

  • pom.xml 配置

    <!--導包~--> <dependencies><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server --><!--導入Eureka Server依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.6.RELEASE</version></dependency><!--熱部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency> </dependencies>
  • application.yml

    server:port: 7001# Eureka配置 eureka:instance:# Eureka服務端的實例名字hostname: 127.0.0.1client:# 表示是否向 Eureka 注冊中心注冊自己(這個模塊本身是服務器,所以不需要)register-with-eureka: false# fetch-registry如果為false,則表示自己為注冊中心,客戶端的化為 turefetch-registry: false# Eureka監控頁面~service-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  • 源碼中Eureka的默認端口以及訪問路徑:

  • 主啟動類

    /*** @Auther: csp1999* @Date: 2020/05/18/10:26* @Description: 啟動之后,訪問 http://127.0.0.1:7001/*/ @SpringBootApplication // @EnableEurekaServer 服務端的啟動類,可以接受別人注冊進來~ @EnableEurekaServer public class EurekaServer_7001 {public static void main(String[] args) {SpringApplication.run(EurekaServer_7001.class,args);} }
  • 啟動成功后訪問 http://localhost:7001/ 得到以下頁面

  • eureka-client

    調整之前創建的springlouc-provider-dept-8001

  • 導入Eureca依賴

    <!--Eureka依賴--> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka --> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version> </dependency>
  • application中新增Eureca配置

    # Eureka配置:配置服務注冊中心地址 eureka:client:service-url:defaultZone: http://localhost:7001/eureka/
  • 為主啟動類添加@EnableEurekaClient注解

    /*** @Auther: csp1999* @Date: 2020/05/17/22:09* @Description: 啟動類*/ @SpringBootApplication // @EnableEurekaClient 開啟Eureka客戶端注解,在服務啟動后自動向注冊中心注冊服務 @EnableEurekaClient public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class,args);} }
  • 先啟動7001服務端后啟動8001客戶端進行測試,然后訪問監控頁http://localhost:7001/ 產看結果如圖,成功

  • 修改Eureka上的默認描述信息

    # Eureka配置:配置服務注冊中心地址 eureka:client:service-url:defaultZone: http://localhost:7001/eureka/instance:instance-id: springcloud-provider-dept-8001 #修改Eureka上的默認描述信息

    結果如圖:

    如果此時停掉springcloud-provider-dept-8001 等30s后 監控會開啟保護機制:

  • 配置關于服務加載的監控信息

  • 熱部署配置

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yMWwnCPJ-1610725250921)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115003227472.png)]

    完善監控信息(actuator)

    pom.xml中添加依賴

    <!--actuator完善監控信息--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency>

    application.yml中添加配置

    # info配置 info: # 項目的名稱app.name: haust-springcloud # 公司的名稱company.name: 河南科技大學西苑校區軟件學院

    此時刷新監控頁,點擊進入跳轉新頁面顯示如下內容:

    自我保護機制:好死不如賴活著

    一句話總結就是:某時刻某一個微服務不可用,eureka不會立即清理,依舊會對該微服務的信息進行保存!

    • 默認情況下,當eureka server在一定時間內沒有收到實例的心跳,便會把該實例從注冊表中刪除(默認是90秒),但是,如果短時間內丟失大量的實例心跳,便會觸發eureka server的自我保護機制,比如在開發測試時,需要頻繁地重啟微服務實例,但是我們很少會把eureka server一起重啟(因為在開發過程中不會修改eureka注冊中心),當一分鐘內收到的心跳數大量減少時,會觸發該保護機制。可以在eureka管理界面看到Renews threshold和Renews(last min),當后者(最后一分鐘收到的心跳數)小于前者(心跳閾值)的時候,觸發保護機制,會出現紅色的警告:EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.從警告中可以看到,eureka認為雖然收不到實例的心跳,但它認為實例還是健康的,eureka會保護這些實例,不會把它們從注冊表中刪掉。
    • 該保護機制的目的是避免網絡連接故障,在發生網絡故障時,微服務和注冊中心之間無法正常通信,但服務本身是健康的,不應該注銷該服務,如果eureka因網絡故障而把微服務誤刪了,那即使網絡恢復了,該微服務也不會重新注冊到eureka server了,因為只有在微服務啟動的時候才會發起注冊請求,后面只會發送心跳和服務列表請求,這樣的話,該實例雖然是運行著,但永遠不會被其它服務所感知。所以,eureka server在短時間內丟失過多的客戶端心跳時,會進入自我保護模式,該模式下,eureka會保護注冊表中的信息,不在注銷任何微服務,當網絡故障恢復后,eureka會自動退出保護模式。自我保護模式可以讓集群更加健壯。
    • 但是我們在開發測試階段,需要頻繁地重啟發布,如果觸發了保護機制,則舊的服務實例沒有被刪除,這時請求有可能跑到舊的實例中,而該實例已經關閉了,這就導致請求錯誤,影響開發測試。所以,在開發測試階段,我們可以把自我保護模式關閉,只需在eureka server配置文件中加上如下配置即可:eureka.server.enable-self-preservation=false【不推薦關閉自我保護機制】

    詳細內容可以參考下這篇博客內容:https://blog.csdn.net/wudiyong22/article/details/80827594

    注冊進來的微服務,獲取一些消息(團隊開發會用到)

    DeptController.java新增方法

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wDpAUERt-1610725250926)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115004810922.png)]

    /*** DiscoveryClient 可以用來獲取一些配置的信息,得到具體的微服務!*/ @Autowired private DiscoveryClient client;/*** 獲取一些注冊進來的微服務的信息~,** @return*/ @GetMapping("/dept/discovery") public Object discovery() {// 獲取微服務列表的清單List<String> services = client.getServices();System.out.println("discovery=>services:" + services);// 得到一個具體的微服務信息,通過具體的微服務id,applicaioinName;List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");for (ServiceInstance instance : instances) {System.out.println(instance.getHost() + "\t" + // 主機名稱instance.getPort() + "\t" + // 端口號instance.getUri() + "\t" + // uriinstance.getServiceId() // 服務id);}return this.client; }

    主啟動類中加入@EnableDiscoveryClient 注解

    @SpringBootApplication // @EnableEurekaClient 開啟Eureka客戶端注解,在服務啟動后自動向注冊中心注冊服務 @EnableEurekaClient // @EnableEurekaClient 開啟服務發現客戶端的注解,可以用來獲取一些配置的信息,得到具體的微服務 @EnableDiscoveryClient public class DeptProvider_8001 {... }

    結果如圖:

    集群環境配置

    1.初始化

    新建springcloud-eureka-7002、springcloud-eureka-7003 模塊

    1.為pom.xml添加依賴 (與springcloud-eureka-7001相同)

    <!--導包~--> <dependencies><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server --><!--導入Eureka Server依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.6.RELEASE</version></dependency><!--熱部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency> </dependencies>

    2.application.yml配置(與springcloud-eureka-7001相同)

    server:port: 7003# Eureka配置 eureka:instance:hostname: localhost # Eureka服務端的實例名字client:register-with-eureka: false # 表示是否向 Eureka 注冊中心注冊自己(這個模塊本身是服務器,所以不需要)fetch-registry: false # fetch-registry如果為false,則表示自己為注冊中心service-url: # 監控頁面~# 重寫Eureka的默認端口以及訪問路徑 --->http://localhost:7001/eureka/defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

    3.主啟動類(與springcloud-eureka-7001相同)

    /*** @Auther: csp1999* @Date: 2020/05/18/10:26* @Description: 啟動之后,訪問 http://127.0.0.1:7003/*/ @SpringBootApplication // @EnableEurekaServer 服務端的啟動類,可以接受別人注冊進來~ public class EurekaServer_7003 {public static void main(String[] args) {SpringApplication.run(EurekaServer_7003.class,args);} }

    2.集群成員相互關聯

    配置一些自定義本機名字,找到本機hosts文件并打開

    在hosts文件最后加上,要訪問的本機名稱,默認是localhost

    修改application.yml的配置,如圖為springcloud-eureka-7001配置,springcloud-eureka-7002/springcloud-eureka-7003同樣分別修改為其對應的名稱即可

    在集群中使springcloud-eureka-7001關聯springcloud-eureka-7002、springcloud-eureka-7003

    完整的springcloud-eureka-7001下的application.yml如下

    server:port: 7001#Eureka配置 eureka:instance:hostname: eureka7001.com #Eureka服務端的實例名字client:register-with-eureka: false #表示是否向 Eureka 注冊中心注冊自己(這個模塊本身是服務器,所以不需要)fetch-registry: false #fetch-registry如果為false,則表示自己為注冊中心service-url: #監控頁面~#重寫Eureka的默認端口以及訪問路徑 --->http://localhost:7001/eureka/# 單機: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/# 集群(關聯):7001關聯7002、7003defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

    同時在集群中使springcloud-eureka-7002關聯springcloud-eureka-7001、springcloud-eureka-7003

    完整的springcloud-eureka-7002下的application.yml如下

    server:port: 7002#Eureka配置 eureka:instance:hostname: eureka7002.com #Eureka服務端的實例名字client:register-with-eureka: false #表示是否向 Eureka 注冊中心注冊自己(這個模塊本身是服務器,所以不需要)fetch-registry: false #fetch-registry如果為false,則表示自己為注冊中心service-url: #監控頁面~#重寫Eureka的默認端口以及訪問路徑 --->http://localhost:7001/eureka/# 單機: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/# 集群(關聯):7002關聯7001、7003defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/

    springcloud-eureka-7003配置方式同理可得.

    通過springcloud-provider-dept-8001下的yml配置文件,修改Eureka配置:配置服務注冊中心地址

    # Eureka配置:配置服務注冊中心地址 eureka:client:service-url:# 注冊中心地址7001-7003defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance:instance-id: springcloud-provider-dept-8001 #修改Eureka上的默認描述信息

    這樣模擬集群就搭建號了,就可以把一個項目掛載到三個服務器上了

    對比和Zookeeper

    1. 回顧CAP原則

    RDBMS (MySQL\Oracle\sqlServer) ===> ACID

    NoSQL (Redis\MongoDB) ===> CAP

    ACID

    • A (Atomicity) 原子性
    • C (Consistency) 一致性
    • I (Isolation) 隔離性
    • D (Durability) 持久性

    CAP

    • C (Consistency) 強一致性
    • A (Availability) 可用性
    • P (Partition tolerance) 分區容錯性

    CAP的三進二:CA、AP、CP

    CAP理論的核心

    • 一個分布式系統不可能同時很好的滿足一致性,可用性和分區容錯性這三個需求
    • 根據CAP原理,將NoSQL數據庫分成了滿足CA原則,滿足CP原則和滿足AP原則三大類
      • CA:單點集群,滿足一致性,可用性的系統,通常可擴展性較差
      • CP:滿足一致性,分區容錯的系統,通常性能不是特別高
      • AP:滿足可用性,分區容錯的系統,通常可能對一致性要求低一些

    Eureka VS Zookeeper

    著名的CAP理論指出,一個分布式系統不可能同時滿足C (一致性) 、A (可用性) 、P (容錯性),由于分區容錯性P再分布式系統中是必須要保證的,因此我們只能再A和C之間進行權衡。

    • Zookeeper 保證的是 CP —> 滿足一致性,分區容錯的系統,通常性能不是特別高
    • Eureka 保證的是 AP —> 滿足可用性,分區容錯的系統,通常可能對一致性要求低一些

    Zookeeper保證的是CP

    當向注冊中心查詢服務列表時,我們可以容忍注冊中心返回的是幾分鐘以前的注冊信息,但不能接收服務直接down掉不可用。也就是說,服務注冊功能對可用性的要求要高于一致性。但zookeeper會出現這樣一種情況,當master節點因為網絡故障與其他節點失去聯系時,剩余節點會重新進行leader選舉。問題在于,選舉leader的時間太長,30-120s,且選舉期間整個zookeeper集群是不可用的,這就導致在選舉期間注冊服務癱瘓。在云部署的環境下,因為網絡問題使得zookeeper集群失去master節點是較大概率發生的事件,雖然服務最終能夠恢復,但是,漫長的選舉時間導致注冊長期不可用,是不可容忍的。

    Eureka保證的是AP

    Eureka看明白了這一點,因此在設計時就優先保證可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工作,剩余的節點依然可以提供注冊和查詢服務。而Eureka的客戶端在向某個Eureka注冊時,如果發現連接失敗,則會自動切換至其他節點,只要有一臺Eureka還在,就能保住注冊服務的可用性,只不過查到的信息可能不是最新的,除此之外,Eureka還有之中自我保護機制,如果在15分鐘內超過85%的節點都沒有正常的心跳,那么Eureka就認為客戶端與注冊中心出現了網絡故障,此時會出現以下幾種情況:

    • Eureka不在從注冊列表中移除因為長時間沒收到心跳而應該過期的服務
    • Eureka仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其他節點上 (即保證當前節點依然可用)
    • 當網絡穩定時,當前實例新的注冊信息會被同步到其他節點中

    因此,Eureka可以很好的應對因網絡故障導致部分節點失去聯系的情況,而不會像zookeeper那樣使整個注冊服務癱瘓

    負載均衡Ribbon和Feign

    Ribbon負載均衡(基于客戶端)

    6.1 負載均衡以及Ribbon

    Ribbon是什么?

    • Spring Cloud Ribbon 是基于Netflix Ribbon 實現的一套客戶端負載均衡的工具
    • 簡單的說,Ribbon 是 Netflix 發布的開源項目,主要功能是提供客戶端的軟件負載均衡算法,將 Netflix 的中間層服務連接在一起。Ribbon 的客戶端組件提供一系列完整的配置項,如:連接超時、重試等。簡單的說,就是在配置文件中列出 LoadBalancer (簡稱LB:負載均衡) 后面所有的及其,Ribbon 會自動的幫助你基于某種規則 (如簡單輪詢,隨機連接等等) 去連接這些機器。我們也容易使用 Ribbon 實現自定義的負載均衡算法!

    Ribbon能干嘛?

    • LB,即負載均衡 (LoadBalancer) ,在微服務或分布式集群中經常用的一種應用。
    • 負載均衡簡單的說就是將用戶的請求平攤的分配到多個服務上,從而達到系統的HA (高用)。
    • 常見的負載均衡軟件有 Nginx、Lvs 等等。
    • Dubbo、SpringCloud 中均給我們提供了負載均衡,SpringCloud 的負載均衡算法可以自定義

    負載均衡簡單分類

    • 集中式LB
      • 即在服務的提供方和消費方之間使用獨立的LB設施,如Nginx(反向代理服務器),由該設施負責把訪問請求通過某種策略轉發至服務的提供方!
    • 進程式 LB
      • 將LB邏輯集成到消費方,消費方從服務注冊中心獲知有哪些地址可用,然后自己再從這些地址中選出一個合適的服務器。
      • Ribbon 就屬于進程內LB,它只是一個類庫,集成于消費方進程,消費方通過它來獲取到服務提供方的地址!

    集成Ribbon

    springcloud-consumer-dept-80向pom.xml中添加Ribbon和Eureka依賴

    <!--Ribbon--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version> </dependency> <!--Eureka: Ribbon需要從Eureka服務中心獲取要拿什么--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version> </dependency>

    在application.yml文件中配置Eureka

    # Eureka配置 eureka:client:register-with-eureka: false # 不向 Eureka注冊自己service-url: # 從三個注冊中心中隨機取一個去訪問defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

    主啟動類加上@EnableEurekaClient注解,開啟Eureka

    //Ribbon 和 Eureka 整合以后,客戶端可以直接調用,不用關心IP地址和端口號 @SpringBootApplication @EnableEurekaClient //開啟Eureka 客戶端 public class DeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_80.class, args);} }

    自定義Spring配置類:ConfigBean.java 配置負載均衡實現RestTemplate

    @Configuration public class ConfigBean {//@Configuration -- spring applicationContext.xml@LoadBalanced //配置負載均衡實現RestTemplate@Beanpublic RestTemplate getRestTemplate() {return new RestTemplate();} }

    修改conroller:DeptConsumerController.java

    //Ribbon:我們這里的地址,應該是一個變量,通過服務名來訪問 //private static final String REST_URL_PREFIX = "http://localhost:8001"; private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";

    數據庫導出

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OxOU2SJU-1610725250930)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115135531598.png)]

    使用Ribbon實現負載均衡

    流程圖:

    1.新建兩個服務提供者Moudle:springcloud-provider-dept-8003、springcloud-provider-dept-8002

    2.參照springcloud-provider-dept-8001 依次為另外兩個Moudle添加pom.xml依賴 、resourece下的mybatis和application.yml配置,Java代碼

    3.啟動所有服務測試(根據自身電腦配置決定啟動服務的個數),訪問http://eureka7001.com:7002/查看結果

    測試訪問http://localhost/consumer/dept/list 這時候隨機訪問的是服務提供者8003

    再次訪問http://localhost/consumer/dept/list這時候隨機的是服務提供者8001

    以上這種每次訪問http://localhost/consumer/dept/list隨機訪問集群中某個服務提供者,這種情況叫做輪詢,輪詢算法在SpringCloud中可以自定義。

    自定義負載均衡

    在springcloud-provider-dept-80模塊下的ConfigBean中進行配置,切換使用不同的規則

    @Configuration public class ConfigBean {//@Configuration -- spring applicationContext.xml/*** IRule:* RoundRobinRule 輪詢策略* RandomRule 隨機策略* AvailabilityFilteringRule : 會先過濾掉,跳閘,訪問故障的服務~,對剩下的進行輪詢~* RetryRule : 會先按照輪詢獲取服務~,如果服務獲取失敗,則會在指定的時間內進行,重試*/@Beanpublic IRule myRule() {return new RandomRule();//使用隨機策略//return new RoundRobinRule();//使用輪詢策略//return new AvailabilityFilteringRule();//使用輪詢策略//return new RetryRule();//使用輪詢策略} }

    也可以自定義規則,在myRule包下自定義一個配置類MyRule.java,注意:該包不要和主啟動類所在的包同級,要跟啟動類所在包同級

    MyRule.java

    /*** @Auther: csp1999* @Date: 2020/05/19/11:58* @Description: 自定義規則*/ @Configuration public class MyRule {@Beanpublic IRule myRule(){return new MyRandomRule();//默認是輪詢RandomRule,現在自定義為自己的} }

    主啟動類開啟負載均衡并指定自定義的MyRule配置類

    //Ribbon 和 Eureka 整合以后,客戶端可以直接調用,不用關心IP地址和端口號 @SpringBootApplication @EnableEurekaClient //在微服務啟動的時候就能加載自定義的Ribbon類(自定義的規則會覆蓋原有默認的規則) @RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)//開啟負載均衡,并指定自定義的規則 public class DeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_80.class, args);} }

    自定義的規則(這里我們參考Ribbon中默認的規則代碼自己稍微改動):MyRandomRule.java

    public class MyRandomRule extends AbstractLoadBalancerRule {/*** 每個服務訪問5次則換下一個服務(總共3個服務)* <p>* total=0,默認=0,如果=5,指向下一個服務節點* index=0,默認=0,如果total=5,index+1*/private int total = 0;//被調用的次數private int currentIndex = 0;//當前是誰在提供服務//@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;}Server server = null;while (server == null) {if (Thread.interrupted()) {return null;}List<Server> upList = lb.getReachableServers();//獲得當前活著的服務List<Server> allList = lb.getAllServers();//獲取所有的服務int serverCount = allList.size();if (serverCount == 0) {/** No servers. End regardless of pass, because subsequent passes* only get more restrictive.*/return null;}//int index = chooseRandomInt(serverCount);//生成區間隨機數//server = upList.get(index);//從或活著的服務中,隨機獲取一個//=====================自定義代碼=========================if (total < 5) {server = upList.get(currentIndex);total++;} else {total = 0;currentIndex++;if (currentIndex > =upList.size()) {currentIndex = 0;}server = upList.get(currentIndex);//從活著的服務中,獲取指定的服務來進行操作}//======================================================if (server == null) {/** The only time this should happen is if the server list were* somehow trimmed. This is a transient condition. Retry after* yielding.*/Thread.yield();continue;}if (server.isAlive()) {return (server);}// Shouldn't actually happen.. but must be transient or a bug.server = null;Thread.yield();}return server;}protected int chooseRandomInt(int serverCount) {return ThreadLocalRandom.current().nextInt(serverCount);}@Overridepublic Server choose(Object key) {return choose(getLoadBalancer(), key);}@Overridepublic void initWithNiwsConfig(IClientConfig clientConfig) {// TODO Auto-generated method stub} }

    Feign負載均衡(基于服務端)

    7.1 Feign簡介

    Feign是聲明式Web Service客戶端,它讓微服務之間的調用變得更簡單,類似controller調用service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供負載均衡的http客戶端

    只需要創建一個接口,然后添加注解即可~

    Feign,主要是社區版,大家都習慣面向接口編程。這個是很多開發人員的規范。調用微服務訪問兩種方法

  • 微服務名字 【ribbon】
  • 接口和注解 【feign】
  • Feign能干什么?

    • Feign旨在使編寫Java Http客戶端變得更容易
    • 前面在使用Ribbon + RestTemplate時,利用RestTemplate對Http請求的封裝處理,形成了一套模板化的調用方法。但是在實際開發中,由于對服務依賴的調用可能不止一處,往往一個接口會被多處調用,所以通常都會針對每個微服務自行封裝一個客戶端類來包裝這些依賴服務的調用。所以,Feign在此基礎上做了進一步的封裝,由他來幫助我們定義和實現依賴服務接口的定義,在Feign的實現下,我們只需要創建一個接口并使用注解的方式來配置它 (類似以前Dao接口上標注Mapper注解,現在是一個微服務接口上面標注一個Feign注解),即可完成對服務提供方的接口綁定,簡化了使用Spring Cloud Ribbon 時,自動封裝服務調用客戶端的開發量。

    Feign默認集成了Ribbon

    • 利用Ribbon維護了MicroServiceCloud-Dept的服務列表信息,并且通過輪詢實現了客戶端的負載均衡,而與Ribbon不同的是,通過Feign只需要定義服務綁定接口且以聲明式的方法,優雅而簡單的實現了服務調用。

    Feign的使用

  • 創建springcloud-consumer-fdept-feign模塊

    拷貝springcloud-consumer-dept-80模塊下的pom.xml,resource,以及java代碼到springcloud-consumer-feign模塊,并添加feign依賴。

    <!--Feign的依賴--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId><version>1.4.6.RELEASE</version> </dependency>

    通過Ribbon實現:—原來的controller:DeptConsumerController.java

    /*** @Auther: csp1999* @Date: 2020/05/17/22:44* @Description:*/ @RestController public class DeptConsumerController {/*** 理解:消費者,不應該有service層~* RestTemplate .... 供我們直接調用就可以了! 注冊到Spring中* (地址:url, 實體:Map ,Class<T> responseType)* <p>* 提供多種便捷訪問遠程http服務的方法,簡單的Restful服務模板~*/@Autowiredprivate RestTemplate restTemplate;/*** 服務提供方地址前綴* <p>* Ribbon:我們這里的地址,應該是一個變量,通過服務名來訪問*/ // private static final String REST_URL_PREFIX = "http://localhost:8001";private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";/*** 消費方添加部門信息* @param dept* @return*/@RequestMapping("/consumer/dept/add")public boolean add(Dept dept) {// postForObject(服務提供方地址(接口),參數實體,返回類型.class)return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);}/*** 消費方根據id查詢部門信息* @param id* @return*/@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id) {// getForObject(服務提供方地址(接口),返回類型.class)return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);}/*** 消費方查詢部門信息列表* @return*/@RequestMapping("/consumer/dept/list")public List<Dept> list() {return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);} }

    通過Feign實現:—改造后controller:DeptConsumerController.java

    /*** @Auther: csp1999* @Date: 2020/05/17/22:44* @Description:*/ @RestController public class DeptConsumerController {@Autowiredprivate DeptClientService deptClientService;/*** 消費方添加部門信息* @param dept* @return*/@RequestMapping("/consumer/dept/add")public boolean add(Dept dept) {return deptClientService.addDept(dept);}/*** 消費方根據id查詢部門信息* @param id* @return*/@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id) {return deptClientService.queryById(id);}/*** 消費方查詢部門信息列表* @return*/@RequestMapping("/consumer/dept/list")public List<Dept> list() {return deptClientService.queryAll();} }

    Feign和Ribbon二者對比,前者顯現出面向接口編程特點,代碼看起來更清爽,而且Feign調用方式更符合我們之前在做SSM或者SprngBoot項目時,Controller層調用Service層的編程習慣!

    主配置類

    /*** @Auther: csp1999* @Date: 2020/05/17/22:47* @Description:*/ @SpringBootApplication @EnableEurekaClient // feign客戶端注解,并指定要掃描的包以及配置接口DeptClientService @EnableFeignClients(basePackages = {"com.haust.springcloud"}) // 切記不要加這個注解,不然會出現404訪問不到 //@ComponentScan("com.haust.springcloud") public class FeignDeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(FeignDeptConsumer_80.class, args);} }
  • 改造springcloud-api模塊

    pom.xml添加feign依賴

    <!--Feign的依賴--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId><version>1.4.6.RELEASE</version> </dependency>
  • 新建service包,并新建DeptClientService.java接口,

    package com.kuang.springcloud.controller;import com.kuang.springcloud.pojo.Dept;import com.kuang.springcloud.service.DeptClientService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** @Auther: csp1999* @Date: 2020/05/17/22:44* @Description:*/@RestControllerpublic class DeptConsumerController {@Autowiredprivate DeptClientService deptClientService=null;/*** 消費方添加部門信息* @param dept* @return*/@RequestMapping("/consumer/dept/add")public boolean add(Dept dept) {return deptClientService.addDept(dept);}/*** 消費方根據id查詢部門信息* @param id* @return*/@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id) {return deptClientService.queryById(id);}/*** 消費方查詢部門信息列表* @return*/@RequestMapping("/consumer/dept/list")public List<Dept> list() {return deptClientService.queryAll();}}

    Feign VS Ribbon

    根據個人習慣而定,如果喜歡REST風格使用Ribbon;如果喜歡社區版的面向接口風格使用Feign.

    Feign 本質上也是實現了 Ribbon,只不過后者是在調用方式上,為了滿足一些開發者習慣的接口調用習慣!

    下面我們關閉springcloud-consumer-dept-80 這個服務消費方,換用springcloud-consumer-dept-feign(端口還是80) 來代替:(依然可以正常訪問,就是調用方式相比于Ribbon變化了)

    Hystrix

    服務熔斷

    分布式系統面臨的問題

    復雜分布式體系結構中的應用程序有數十個依賴關系,每個依賴關系在某些時候將不可避免失敗!

    服務雪崩

    多個微服務之間調用的時候,假設微服務A調用微服務B和微服務C,微服務B和微服務C又調用其他的微服務,這就是所謂的“扇出”,如果扇出的鏈路上某個微服務的調用響應時間過長,或者不可用,對微服務A的調用就會占用越來越多的系統資源,進而引起系統崩潰,所謂的“雪崩效應”。

    對于高流量的應用來說,單一的后端依賴可能會導致所有服務器上的所有資源都在幾十秒內飽和。比失敗更糟糕的是,這些應用程序還可能導致服務之間的延遲增加,備份隊列,線程和其他系統資源緊張,導致整個系統發生更多的級聯故障,這些都表示需要對故障和延遲進行隔離和管理,以達到單個依賴關系的失敗而不影響整個應用程序或系統運行

    我們需要,棄車保帥

    Hystrix作用

    Hystrix是一個應用于處理分布式系統的延遲和容錯的開源庫,在分布式系統里,許多依賴不可避免的會調用失敗,比如超時,異常等,Hystrix 能夠保證在一個依賴出問題的情況下,不會導致整個體系服務失敗,避免級聯故障,以提高分布式系統的彈性。

    斷路器”本身是一種開關裝置,當某個服務單元發生故障之后,通過斷路器的故障監控 (類似熔斷保險絲) ,向調用方返回一個服務預期的,可處理的備選響應 (FallBack) ,而不是長時間的等待或者拋出調用方法無法處理的異常,這樣就可以保證了服務調用方的線程不會被長時間,不必要的占用,從而避免了故障在分布式系統中的蔓延,乃至雪崩。

    Hystrix能干嘛?

    • 服務降級
    • 服務熔斷
    • 服務限流
    • 接近實時的監控

    當一切正常時,請求流可以如下所示:

    當許多后端系統中有一個潛在阻塞服務時,它可以阻止整個用戶請求:

    隨著大容量通信量的增加,單個后端依賴項的潛在性會導致所有服務器上的所有資源在幾秒鐘內飽和。

    應用程序中通過網絡或客戶端庫可能導致網絡請求的每個點都是潛在故障的來源。比失敗更糟糕的是,這些應用程序還可能導致服務之間的延遲增加,從而備份隊列、線程和其他系統資源,從而導致更多跨系統的級聯故障。

    當使用Hystrix包裝每個基礎依賴項時,上面的圖表中所示的體系結構會發生類似于以下關系圖的變化。每個依賴項是相互隔離的,限制在延遲發生時它可以填充的資源中,并包含在回退邏輯中,該邏輯決定在依賴項中發生任何類型的故障時要做出什么樣的響應:

    官網資料:https://github.com/Netflix/Hystrix/wiki

    服務熔斷(服務端)

    什么是服務熔斷?

    熔斷機制是賭贏雪崩效應的一種微服務鏈路保護機制

    當扇出鏈路的某個微服務不可用或者響應時間太長時,會進行服務的降級,進而熔斷該節點微服務的調用,快速返回錯誤的響應信息。檢測到該節點微服務調用響應正常后恢復調用鏈路。在SpringCloud框架里熔斷機制通過Hystrix實現。Hystrix會監控微服務間調用的狀況,當失敗的調用到一定閥值缺省是5秒內20次調用失敗,就會啟動熔斷機制。熔斷機制的注解是:@HystrixCommand。

    服務熔斷解決如下問題:

    • 當所依賴的對象不穩定時,能夠起到快速失敗的目的;
    • 快速失敗后,能夠根據一定的算法動態試探所依賴對象是否恢復。

    案例

    新建springcloud-provider-dept-hystrix-8001模塊并拷貝springcloud-provider-dept–8001內的pom.xml、resource和Java代碼進行初始化并調整。

    導入hystrix依賴

    <!--導入Hystrix依賴--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version> </dependency>

    調整yml配置文件

    server:port: 8001# mybatis配置 mybatis:# springcloud-api 模塊下的pojo包type-aliases-package: com.haust.springcloud.pojo# 本模塊下的mybatis-config.xml核心配置文件類路徑config-location: classpath:mybatis/mybatis-config.xml# 本模塊下的mapper配置文件類路徑mapper-locations: classpath:mybatis/mapper/*.xml# spring配置 spring:application:#項目名name: springcloud-provider-deptdatasource:# 德魯伊數據源type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8username: rootpassword: root# Eureka配置:配置服務注冊中心地址 eureka:client:service-url:# 注冊中心地址7001-7003defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance:instance-id: springcloud-provider-dept-hystrix-8001 #修改Eureka上的默認描述信息prefer-ip-address: true #改為true后默認顯示的是ip地址而不再是localhost#info配置 info:app.name: haust-springcloud #項目的名稱company.name: com.haust #公司的名稱

    prefer-ip-address: false:

    prefer-ip-address: true

    修改controller

    /*** @Auther: csp1999* @Date: 2020/05/17/22:06* @Description: 提供Restful服務*/ @RestController public class DeptController {@Autowiredprivate DeptService deptService;/*** 根據id查詢部門信息* 如果根據id查詢出現異常,則走hystrixGet這段備選代碼* @param id* @return*/@HystrixCommand(fallbackMethod = "hystrixGet")@RequestMapping("/dept/get/{id}")//根據id查詢public Dept get(@PathVariable("id") Long id){Dept dept = deptService.queryById(id);if (dept==null){throw new RuntimeException("這個id=>"+id+",不存在該用戶,或信息無法找到~");}return dept;}/*** 根據id查詢備選方案(熔斷)* @param id* @return*/public Dept hystrixGet(@PathVariable("id") Long id){return new Dept().setDeptno(id).setDname("這個id=>"+id+",沒有對應的信息,null---@Hystrix~").setDb_source("在MySQL中沒有這個數據庫");} }

    為主啟動類添加對熔斷的支持注解@EnableCircuitBreaker

    /*** @Auther: csp1999* @Date: 2020/05/17/22:09* @Description: 啟動類*/ @SpringBootApplication @EnableEurekaClient // EnableEurekaClient 客戶端的啟動類,在服務啟動后自動向注冊中心注冊服務 @EnableDiscoveryClient // 服務發現~ @EnableCircuitBreaker // 添加對熔斷的支持注解 public class HystrixDeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(HystrixDeptProvider_8001.class,args);} }

    測試

    使用熔斷后,當訪問一個不存在的id時,前臺頁展示數據如下:

    而不適用熔斷的springcloud-provider-dept–8001模塊訪問相同地址會出現下面狀況:

    因此,為了避免因某個微服務后臺出現異常或錯誤而導致整個應用或網頁報錯,使用熔斷是必要的

    顯示服務的ip

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-POuM4oTq-1610725250931)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115162939925.png)]

    服務降級(客戶端)

    什么是服務降級?

    服務降級是指 當服務器壓力劇增的情況下,根據實際業務情況及流量,對一些服務和頁面有策略的不處理,或換種簡單的方式處理,從而釋放服務器資源以保證核心業務正常運作或高效運作。說白了,就是盡可能的把系統資源讓給優先級高的服務

    資源有限,而請求是無限的。如果在并發高峰期,不做服務降級處理,一方面肯定會影響整體服務的性能,嚴重的話可能會導致宕機某些重要的服務不可用。所以,一般在高峰期,為了保證核心功能服務的可用性,都要對某些服務降級處理。比如當雙11活動時,把交易無關的服務統統降級,如查看螞蟻深林,查看歷史訂單等等。

    服務降級主要用于什么場景呢?當整個微服務架構整體的負載超出了預設的上限閾值或即將到來的流量預計將會超過預設的閾值時,為了保證重要或基本的服務能正常運行,可以將一些 不重要 或 不緊急 的服務或任務進行服務的 延遲使用 或 暫停使用。

    降級的方式可以根據業務來,可以延遲服務,比如延遲給用戶增加積分,只是放到一個緩存中,等服務平穩之后再執行 ;或者在粒度范圍內關閉服務,比如關閉相關文章的推薦。

    由上圖可得,當某一時間內服務A的訪問量暴增,而B和C的訪問量較少,為了緩解A服務的壓力,這時候需要B和C暫時關閉一些服務功能,去承擔A的部分服務,從而為A分擔壓力,叫做服務降級

    服務降級需要考慮的問題

    • 1)那些服務是核心服務,哪些服務是非核心服務
    • 2)那些服務可以支持降級,那些服務不能支持降級,降級策略是什么
    • 3)除服務降級之外是否存在更復雜的業務放通場景,策略是什么?

    自動降級分類

    1)超時降級:主要配置好超時時間和超時重試次數和機制,并使用異步機制探測回復情況

    2)失敗次數降級:主要是一些不穩定的api,當失敗調用次數達到一定閥值自動降級,同樣要使用異步機制探測回復情況

    3)故障降級:比如要調用的遠程服務掛掉了(網絡故障、DNS故障、http服務返回錯誤的狀態碼、rpc服務拋出異常),則可以直接降級。降級后的處理方案有:默認值(比如庫存服務掛了,返回默認現貨)、兜底數據(比如廣告掛了,返回提前準備好的一些靜態頁面)、緩存(之前暫存的一些緩存數據)

    4)限流降級:秒殺或者搶購一些限購商品時,此時可能會因為訪問量太大而導致系統崩潰,此時會使用限流來進行限制訪問量,當達到限流閥值,后續請求會被降級;降級后的處理方案可以是:排隊頁面(將用戶導流到排隊頁面等一會重試)、無貨(直接告知用戶沒貨了)、錯誤頁(如活動太火爆了,稍后重試)。

    入門案例

    在springcloud-api模塊下的service包中新建降級配置類DeptClientServiceFallBackFactory.java

    /*** @Auther: csp1999* @Date: 2020/05/20/9:18* @Description: Hystrix服務降級 ~*/ @Component public class DeptClientServiceFallBackFactory implements FallbackFactory {@Overridepublic DeptClientService create(Throwable cause) {return new DeptClientService() {@Overridepublic Dept queryById(Long id) {return new Dept().setDeptno(id).setDname("id=>" + id + "沒有對應的信息,客戶端提供了降級的信息,這個服務現在已經被關閉").setDb_source("沒有數據~");}@Overridepublic List<Dept> queryAll() {return null;}@Overridepublic Boolean addDept(Dept dept) {return false;}};} }

    在DeptClientService中指定降級配置類DeptClientServiceFallBackFactory

    @Component //注冊到spring容器中 //@FeignClient:微服務客戶端注解,value:指定微服務的名字,這樣就可以使Feign客戶端直接找到對應的微服務 @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class)//fallbackFactory指定降級配置類 public interface DeptClientService {@GetMapping("/dept/get/{id}")public Dept queryById(@PathVariable("id") Long id);@GetMapping("/dept/list")public List<Dept> queryAll();@GetMapping("/dept/add")public Boolean addDept(Dept dept); }

    springcloud-consumer-dept-feign模塊中開啟降級:

    server:port: 80# Eureka配置 eureka:client:register-with-eureka: false # 不向 Eureka注冊自己service-url: # 從三個注冊中心中隨機取一個去訪問defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/# 開啟降級feign.hystrix feign:hystrix:enabled: true

    服務熔斷VS降級VS限流

    • 服務熔斷—>服務端:某個服務超時或異常,引起熔斷~,類似于保險絲(自我熔斷)
    • 服務降級—>客戶端:從整體網站請求負載考慮,當某個服務熔斷或者關閉之后,服務將不再被調用,此時在客戶端,我們可以準備一個 FallBackFactory ,返回一個默認的值(缺省值)。會導致整體的服務下降,但是好歹能用,比直接掛掉強。
    • 觸發原因不太一樣,服務熔斷一般是某個服務(下游服務)故障引起,而服務降級一般是從整體負荷考慮;管理目標的層次不太一樣,熔斷其實是一個框架級的處理,每個微服務都需要(無層級之分),而降級一般需要對業務有層級之分(比如降級一般是從最外圍服務開始)
    • 實現方式不太一樣,服務降級具有代碼侵入性(由控制器完成/或自動降級),熔斷一般稱為自我熔斷

    熔斷,降級,限流

    限流:限制并發的請求訪問量,超過閾值則拒絕;

    降級:服務分優先級,犧牲非核心服務(不可用),保證核心服務穩定;從整體負荷考慮;

    熔斷:依賴的下游服務故障觸發熔斷,避免引發本系統崩潰;系統自動執行和恢復

    Dashboard 流監控

    新建springcloud-consumer-hystrix-dashboard模塊

    添加依賴

    <!--Hystrix依賴--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version> </dependency> <!--dashboard依賴--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix-dashboard</artifactId><version>1.4.6.RELEASE</version> </dependency> <!--Ribbon--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version> </dependency> <!--Eureka--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version> </dependency> <!--實體類+web--> <dependency><groupId>com.haust</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <!--熱部署--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId> </dependency>

    主啟動類

    @SpringBootApplication // 開啟Dashboard @EnableHystrixDashboard public class DeptConsumerDashboard_9001 {public static void main(String[] args) {SpringApplication.run(DeptConsumerDashboard_9001.class,args);} }

    給springcloud-provider-dept-hystrix-8001模塊下的主啟動類添加如下代碼,添加監控

    @SpringBootApplication @EnableEurekaClient //EnableEurekaClient 客戶端的啟動類,在服務啟動后自動向注冊中心注冊服務 public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class,args);}//增加一個 Servlet@Beanpublic ServletRegistrationBean hystrixMetricsStreamServlet(){ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());//訪問該頁面就是監控頁面registrationBean.addUrlMappings("/actuator/hystrix.stream");return registrationBean;} }

    訪問:http://localhost:9001/hystrix

    進入監控頁面:

    效果如下圖:

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-6Lrufp0x-1610725250932)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115190406423.png)]

    一些問題解決辦法

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fz0nuLpz-1610725250934)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115190154045.png)]

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ifS1YBTP-1610725250939)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115190205062.png)]

    Zull路由網關

    概述

    什么是zuul?

    Zull包含了對請求的路由(用來跳轉的)和過濾兩個最主要功能:

    其中路由功能負責將外部請求轉發到具體的微服務實例上,是實現外部訪問統一入口的基礎,而過濾器功能則負責對請求的處理過程進行干預,是實現請求校驗,服務聚合等功能的基礎。Zuul和Eureka進行整合,將Zuul自身注冊為Eureka服務治理下的應用,同時從Eureka中獲得其他服務的消息,也即以后的訪問微服務都是通過Zuul跳轉后獲得。

    注意:Zuul 服務最終還是會注冊進 Eureka

    提供:代理 + 路由 + 過濾 三大功能!

    Zuul 能干嘛?

    • 路由
    • 過濾

    官方文檔:https://github.com/Netflix/zuul/

    入門案例

    新建springcloud-zuul模塊,并導入依賴

    <dependencies><!--導入zuul依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zuul</artifactId><version>1.4.6.RELEASE</version></dependency><!--Hystrix依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix</artifactId><version>1.4.6.RELEASE</version></dependency><!--dashboard依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-hystrix-dashboar</artifactId><version>1.4.6.RELEASE</version></dependency><!--Ribbon--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version></dependency><!--Eureka--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency><!--實體類+web--><dependency><groupId>com.haust</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--熱部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency> </dependencies>

    application.yml

    server:port: 9527spring:application:name: springcloud-zuul #微服務名稱# eureka 注冊中心配置 eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/instance: #實例的idinstance-id: zuul9527.comprefer-ip-address: true # 顯示ipinfo:app.name: haust.springcloud # 項目名稱company.name: 河南科技大學西苑校區 # 公司名稱# zull 路由網關配置 zuul:# 路由相關配置# 原來訪問路由 eg:http://www.cspStudy.com:9527/springcloud-provider-dept/dept/get/1# zull路由配置后訪問路由 eg:http://www.cspstudy.com:9527/haust/mydept/dept/get/1routes:mydept.serviceId: springcloud-provider-dept # eureka注冊中心的服務提供方路由名稱mydept.path: /mydept/** # 將eureka注冊中心的服務提供方路由名稱 改為自定義路由名稱# 不能再使用這個路徑訪問了,*: 忽略,隱藏全部的服務名稱~ignored-services: "*"# 設置公共的前綴prefix: /haust

    主啟動類

    /*** @Auther: csp1999* @Date: 2020/05/20/20:53* @Description: Zull路由網關主啟動類*/ @SpringBootApplication @EnableZuulProxy // 開啟Zuul public class ZuulApplication_9527 {public static void main(String[] args) {SpringApplication.run(ZuulApplication_9527.class,args);} }

    測試:

    可以看出Zull路由網關被注冊到Eureka注冊中心中了!

    上圖是沒有經過Zull路由網關配置時,服務接口訪問的路由,可以看出直接用微服務(服務提供方)名稱去訪問,這樣不安全,不能將微服務名稱暴露!

    所以經過Zull路由網關配置后,訪問的路由為:

    我們看到,微服務名稱被替換并隱藏,換成了我們自定義的微服務名稱mydept,同時加上了前綴haust,這樣就做到了對路由fan訪問的加密處理!

    詳情參考springcloud中文社區zuul組件 :https://www.springcloud.cc/spring-cloud-greenwich.html#_router_and_filter_zuul

    SpringCloud Config 分布式配置

    Dalston.RELEASE

    Spring Cloud Config為分布式系統中的外部配置提供服務器和客戶端支持。使用Config Server,您可以在所有環境中管理應用程序的外部屬性。客戶端和服務器上的概念映射與Spring Environment和PropertySource抽象相同,因此它們與Spring應用程序非常契合,但可以與任何以任何語言運行的應用程序一起使用。隨著應用程序通過從開發人員到測試和生產的部署流程,您可以管理這些環境之間的配置,并確定應用程序具有遷移時需要運行的一切。服務器存儲后端的默認實現使用git,因此它輕松支持標簽版本的配置環境,以及可以訪問用于管理內容的各種工具。很容易添加替代實現,并使用Spring配置將其插入。

    概述

    分布式系統面臨的–配置文件問題

    微服務意味著要將單體應用中的業務拆分成一個個子服務,每個服務的粒度相對較小,因此系統中會出現大量的服務,由于每個服務都需要必要的配置信息才能運行,所以一套集中式的,動態的配置管理設施是必不可少的。spring cloud提供了configServer來解決這個問題,我們每一個微服務自己帶著一個application.yml,那上百個的配置文件修改起來,令人頭疼!

    什么是SpringCloud config分布式配置中心?

    spring cloud config 為微服務架構中的微服務提供集中化的外部支持,配置服務器為各個不同微服務應用的所有環節提供了一個中心化的外部配置

    spring cloud config 分為服務端客戶端兩部分。

    服務端也稱為 分布式配置中心,它是一個獨立的微服務應用,用來連接配置服務器并為客戶端提供獲取配置信息,加密,解密信息等訪問接口。

    客戶端則是通過指定的配置中心來管理應用資源,以及與業務相關的配置內容,并在啟動的時候從配置中心獲取和加載配置信息。配置服務器默認采用git來存儲配置信息,這樣就有助于對環境配置進行版本管理。并且可用通過git客戶端工具來方便的管理和訪問配置內容。

    spring cloud config 分布式配置中心能干嘛?

    • 集中式管理配置文件
    • 不同環境,不同配置,動態化的配置更新,分環境部署,比如 /dev /test /prod /beta /release
    • 運行期間動態調整配置,不再需要在每個服務部署的機器上編寫配置文件,服務會向配置中心統一拉取配置自己的信息
    • 當配置發生變動時,服務不需要重啟,即可感知到配置的變化,并應用新的配置
    • 將配置信息以REST接口的形式暴露

    與GitHub整合

    新建倉庫

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Bhz1F83t-1610725250942)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115201322508.png)]

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LE7yvLGo-1610725250943)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115201720254.png)]

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BDYARVKc-1610725250944)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115201835756.png)]

    下載遠程代碼

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CFHdAOxD-1610725250945)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115203431941.png)]

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TsRQNrCr-1610725250946)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115203520367.png)]

    對git進行配置

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-pRrLqu6I-1610725250946)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115203746644.png)]

    生成公鑰

    此文件夾下

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Z1QfZuVv-1610725250947)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115205541149.png)]

    ssh-keygen -t rsa -C “2764954910@qq.com”

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fY2YDC6L-1610725250949)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115205752053.png)]

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mJltkGjK-1610725250950)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115205742128.png)]

    上傳代碼、

    先下載再提交,對應

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-XrlSWZgt-1610725250951)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115211052522.png)]

    由于spring cloud config 默認使用git來存儲配置文件 (也有其他方式,比如自持SVN 和本地文件),但是最推薦的還是git ,而且使用的是 http / https 訪問的形式。

    服務端

    前提yml寫對否則會報錯

    新建springcloud-config-server-3344模塊導入pom.xml依賴

    <dependencies><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--config--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId><version>2.1.1.RELEASE</version></dependency><!--eureka--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency> </dependencies>

    resource下創建application.yml配置文件,Spring Cloud Config服務器從git存儲庫(必須提供)為遠程客戶端提供配置:

    server:port: 3344spring:application:name: springcloud-config-server# 連接碼云遠程倉庫cloud:config:server:git:# 注意是https的而不是sshuri: https://gitee.com/wdlyb/springcloud-config.git# 通過 config-server可以連接到git,訪問其中的資源以及配置~# 不加這個配置會報Cannot execute request on any known server 這個錯:連接Eureka服務端地址不對 # 或者直接注釋掉eureka依賴 這里暫時用不到eureka eureka:client:register-with-eureka: falsefetch-registry: false

    主啟動類

    @EnableConfigServer // 開啟spring cloud config server服務 @SpringBootApplication public class Config_server_3344 {public static void main(String[] args) {SpringApplication.run(Config_server_3344.class,args);} }

    將本地git倉庫springcloud-config文件夾下新建的application.yml提交到碼云倉庫:

    定位資源的默認策略是克隆一個git倉庫(在spring.cloud.config.server.git.uri),并使用它來初始化一個迷你SpringApplication。小應用程序的Environment用于枚舉屬性源并通過JSON端點發布。

    HTTP服務具有以下格式的資源:

    /{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties

    其中“應用程序”作為SpringApplication中的spring.config.name注入(即常規的Spring Boot應用程序中通常是“應用程序”),“配置文件”是活動配置文件(或逗號分隔列表的屬性),“label”是可選的git標簽(默認為“master”)。

    測試訪問http://localhost:3344/application-dev.yml

    測試訪問 http://localhost:3344/application/test/master

    測試訪問 http://localhost:3344/master/application-dev.yml

    如果測試訪問不存在的配置則不顯示 如:http://localhost:3344/master/application-aaa.yml

    客戶端

    將本地git倉庫springcloud-config文件夾下新建的config-client.yml提交到碼云倉庫:

    新建一個springcloud-config-client-3355模塊,并導入依賴

    <!--config--> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-start --> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>2.1.1.RELEASE</version> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>

    resources下創建application.yml和bootstrap.yml配置文件

    bootstrap.yml 是系統級別的配置

    # 系統級別的配置 spring:cloud:config:name: config-client # 需要從git上讀取的資源名稱,不要后綴profile: devlabel: masteruri: http://localhost:3344

    application.yml 是用戶級別的配置

    # 用戶級別的配置 spring:application:name: springcloud-config-client

    創建controller包下的ConfigClientController.java 用于測試

    @RestController public class ConfigClientController {@Value("${spring.application.name}")private String applicationName; //獲取微服務名稱@Value("${eureka.client.service-url.defaultZone}")private String eurekaServer; //獲取Eureka服務@Value("${server.port}")private String port; //獲取服務端的端口號@RequestMapping("/config")public String getConfig(){return "applicationName:"+applicationName +"eurekaServer:"+eurekaServer +"port:"+port;} }

    主啟動類

    @SpringBootApplication public class ConfigClient {public static void main(String[] args) {SpringApplication.run(ConfigClient.class,args);} }

    測試:

    啟動服務端Config_server_3344 再啟動客戶端ConfigClient

    訪問:http://localhost:8201/config/

    小案例

    本地新建config-dept.yml和config-eureka.yml并提交到碼云倉庫

    這里配置文件內容不再列舉直接到代碼中看把。

    新建springcloud-config-eureka-7001模塊,并將原來的springcloud-eureka-7001模塊下的內容拷貝的該模塊。

    1.清空該模塊的application.yml配置,并新建bootstrap.yml連接遠程配置

    spring:cloud:config:name: config-eureka # 倉庫中的配置文件名稱label: masterprofile: devuri: http://localhost:3344

    2.在pom.xml中添加spring cloud config依賴

    <!--config--> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-config --> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>2.1.1.RELEASE</version> </dependency>

    3.主啟動類

    @SpringBootApplication @EnableEurekaServer //EnableEurekaServer 服務端的啟動類,可以接受別人注冊進來~ public class ConfigEurekaServer_7001 {public static void main(String[] args) {SpringApplication.run(ConfigEurekaServer_7001.class,args);} }

    4.測試

    第一步:啟動 Config_Server_3344,并訪問 http://localhost:3344/master/config-eureka-dev.yml 測試


    第二部:啟動ConfigEurekaServer_7001,訪問 http://localhost:7001/ 測試


    顯示上圖則成功

    新建springcloud-config-dept-8001模塊并拷貝springcloud-provider-dept-8001的內容

    同理導入spring cloud config依賴、清空application.yml 、新建bootstrap.yml配置文件并配置

    spring:cloud:config:name: config-deptlabel: masterprofile: devuri: http://localhost:3344

    主啟動類

    @SpringBootApplication @EnableEurekaClient //在服務啟動后自動注冊到Eureka中! @EnableDiscoveryClient //服務發現~ @EnableCircuitBreaker // public class ConfigDeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(ConfigDeptProvider_8001.class,args);}//增加一個 Servlet@Beanpublic ServletRegistrationBean hystrixMetricsStreamServlet(){ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());registrationBean.addUrlMappings("/actuator/hystrix.stream");return registrationBean;} }

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EFNYsTnO-1610725250953)(C:\Users\王東梁\AppData\Roaming\Typora\typora-user-images\image-20210115233434134.png)]

    總結

    以上是生活随笔為你收集整理的SpringCloud(笔记)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    99久久久国产精品免费99 | 国内揄拍国内精品 | 免费 在线 中文 日本 | 成年人免费av网站 | 色偷偷88888欧美精品久久久 | 99在线视频精品 | 国产精品永久久久久久久久久 | 九九视频精品免费 | 国产精品18久久久久久久 | 免费高清在线视频一区· | 狠狠狠狠狠操 | 91九色蝌蚪国产 | 日韩精品一区二区在线视频 | 日韩电影中文,亚洲精品乱码 | 亚洲精品高清在线观看 | 国内精品久久久久影院一蜜桃 | 国产精品96久久久久久吹潮 | 中文资源在线播放 | 久久精品欧美 | 久久日韩精品 | 最近日本mv字幕免费观看 | 色哟哟国产精品 | 欧美日韩国产区 | 在线三级播放 | 国产剧情av在线播放 | 91丨九色丨国产丨porny精品 | 国产免费又爽又刺激在线观看 | 久久官网 | 欧美精品乱码久久久久久 | 久久精品视 | 九九热国产 | 国产精品久久久久久久久久三级 | 麻豆免费视频 | 欧美日产在线观看 | 中文字幕高清视频 | 一级精品视频在线观看宜春院 | 精品视频在线视频 | a黄在线观看 | 91视频久久 | 国产精品久久久久久久妇 | 欧美巨大| 欧美韩国日本在线 | 黄色影院在线观看 | 国产精品免费在线观看视频 | av在线免费网 | 久久99日韩 | 精品视频在线免费观看 | 涩涩资源网 | 国产亚洲精品美女 | 最近免费观看的电影完整版 | 中文字幕在线视频精品 | 日韩在线视频精品 | 午夜免费久久看 | 久久视频在线免费观看 | 国产传媒一区在线 | 一级成人在线 | 日本丰满少妇免费一区 | 欧美做受高潮1 | 欧美一级电影在线观看 | 一区二区欧美激情 | 亚洲视频2 | 五月开心六月婷婷 | 少妇bbbb| 国产91亚洲精品 | 日韩中文字幕国产精品 | 国产又粗又猛又爽又黄的视频免费 | 一区二区三区中文字幕在线 | 日日夜夜精品免费观看 | 一区二区三区高清在线观看 | aa一级片 | 亚洲欧洲精品一区 | 日韩成人xxxx| 精品久久免费 | 欧美a级在线免费观看 | 国产精品毛片久久久久久久 | 三级av免费 | 精品久久毛片 | 国产精品亚洲片在线播放 | 在线观看av黄色 | 成人免费xxx在线观看 | 2019中文字幕第一页 | 又色又爽又激情的59视频 | 日韩大陆欧美高清视频区 | 色婷婷综合久久久久 | 草久视频在线 | 91香蕉视频在线 | 三级毛片视频 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 天天射网站| 国产精品久久 | 久久久精品欧美一区二区免费 | 日韩中文字幕国产 | 久久久高清视频 | 久久天天操 | 超碰人人av| 国产成人精品久久亚洲高清不卡 | 国产剧情一区二区在线观看 | av中文字幕在线观看网站 | 中文字幕一区二区三区四区视频 | 久久久久久免费 | 国产69精品久久app免费版 | 免费在线观看不卡av | 欧洲一区二区三区精品 | 黄色网在线播放 | 天天干天天做天天爱 | .精品久久久麻豆国产精品 亚洲va欧美 | 久久免费99精品久久久久久 | 欧美欧美| 免费看一级特黄a大片 | 日日夜夜骑 | 久久99影院| 日韩大片在线 | 国产一级免费视频 | 高清不卡一区二区三区 | 婷婷干五月| 国产在线91在线电影 | 91在线看| 久久精品免费 | 欧美欧美 | 国产91精品高清一区二区三区 | 不卡av电影在线观看 | 久久乐九色婷婷综合色狠狠182 | 国产亚洲婷婷免费 | 四虎在线永久免费观看 | 免费日韩在线 | 色丁香婷婷| 国产精品久久一区二区三区不卡 | 国产成人a亚洲精品 | 色综合中文字幕 | 不卡电影免费在线播放一区 | 99 精品 在线 | 久热色超碰 | 国产成人精品女人久久久 | 日韩专区av| 国产三级av在线 | 成 人 黄 色视频免费播放 | 亚洲欧洲成人 | 91麻豆精品国产91久久久更新时间 | 亚洲精品中文字幕在线 | 五月婷婷中文字幕 | 久久情网 | 成人影片在线免费观看 | 国产精品一区二区久久精品爱微奶 | 久久久久99精品成人片三人毛片 | 天堂久色 | 久久99精品国产麻豆婷婷 | 免费看一级黄色大全 | 国内精品免费久久影院 | 国产高清视频在线播放 | 国产午夜三级一区二区三 | 国产一区在线免费观看 | 97成人免费| 日本特黄一级片 | 五月婷婷丁香在线观看 | 国产91精品看黄网站在线观看动漫 | 午夜美女福利 | 成人亚洲免费 | 欧美日韩亚洲第一 | av中文字幕在线观看网站 | 欧美资源在线观看 | 91av色| 在线91av | 日本韩国欧美在线观看 | 免费看黄在线看 | 夜夜高潮夜夜爽国产伦精品 | 国产精品美女久久久网av | 亚洲国产精品va在线看 | 国产综合片 | 国产理伦在线 | 日日干干夜夜 | 久久tv视频 | 免费黄av| 国产精品免费麻豆入口 | 国产精品高清免费在线观看 | 国产69久久久欧美一级 | 午夜骚影 | 成人av免费在线播放 | 久久久免费观看完整版 | av中文电影 | 久久久久久美女 | 国产视频不卡一区 | 日韩精品视频一二三 | 免费a级黄色毛片 | 一区二区欧美激情 | 国产美女网 | 丁香网五月天 | 国产黄色片在线免费观看 | 亚洲精品视频在线看 | 成人在线一区二区 | 999男人的天堂| 日韩xxx视频 | 日韩成年视频 | 欧美激情综合五月 | av免费看av | 国内久久看 | 国产精品免费久久 | 天天操天天操天天操天天 | 香蕉久久国产 | 在线观看黄色的网站 | 国产精品精品 | 97超级碰碰碰碰久久久久 | 激情 亚洲 | 国产精品 亚洲精品 | 操操碰| av综合 日韩| 国产视频不卡一区 | 日韩黄色在线电影 | 成人久久久精品国产乱码一区二区 | 日本中文字幕在线看 | 久久精品波多野结衣 | 国产精品2018 | 国内亚洲精品 | www黄色av| 色婷婷福利视频 | 国语自产偷拍精品视频偷 | 在线高清av | 毛片一级免费一级 | 色婷婷免费视频 | 黄色视屏免费在线观看 | 国产成人三级三级三级97 | 久久综合五月 | 日韩免费视频观看 | 成人欧美一区二区三区在线观看 | 日韩三级免费 | 中文字幕一区二区三区四区视频 | 精品国产成人av | 亚洲成人免费观看 | 一本一道久久a久久精品 | 一个色综合网站 | 成人午夜黄色影院 | 国产二区精品 | 九九视频在线观看视频6 | 亚洲一区二区高潮无套美女 | 久久激情精品 | 天堂在线v| 99精品亚洲| 91伊人| 久久久久成人精品免费播放动漫 | 欧美激情视频一区二区三区免费 | 色婷婷视频在线 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 久久久久久久久久久久久久免费看 | 91探花系列在线播放 | 久草精品视频在线播放 | 免费色视频网站 | 国产中文欧美日韩在线 | 中文字幕一区二区三区四区 | 亚洲国产日韩欧美 | 99精品视频在线观看播放 | 在线观看精品一区 | 亚洲精品日韩av | a在线观看免费视频 | 99久久久国产精品美女 | 亚洲精品国产精品国自 | 永久免费精品视频网站 | 在线 国产 日韩 | 亚洲情婷婷 | 又黄又爽的免费高潮视频 | 国产视频亚洲精品 | 日本久久久久久久久久久 | 亚洲精品av中文字幕在线在线 | 麻豆视频在线观看 | 久久久精品国产免费观看同学 | 国产伦精品一区二区三区无广告 | 国产免费嫩草影院 | 精品日韩视频 | 亚州精品天堂中文字幕 | 欧美一性一交一乱 | 久久手机在线视频 | 国产成人三级一区二区在线观看一 | 人人艹视频 | 成人久久久电影 | 午夜久久福利视频 | 亚洲精品视 | 成人av中文字幕 | 热99在线视频 | 国产精品99久久久久久武松影视 | 日韩精品视频一二三 | 一区二区不卡视频在线观看 | 国产亚洲精品女人久久久久久 | 国产美女被啪进深处喷白浆视频 | 日免费视频 | 中文字幕久久精品 | 日本少妇高清做爰视频 | 欧美日韩亚洲第一页 | 免费69视频| 久久精品成人欧美大片古装 | 久久久久久久久久免费 | 久久国内免费视频 | 日韩精品专区在线影院重磅 | 99久久99久久免费精品蜜臀 | avsex| 丁香婷婷综合激情 | 日韩一区二区在线免费观看 | 国产欧美综合在线观看 | 波多野结衣网址 | 日韩理论片在线 | 国产成人久久精品 | 婷婷在线不卡 | 视频福利在线观看 | 国产精品第7页 | 97超碰在线久草超碰在线观看 | 五月婷婷六月丁香在线观看 | 色综合 久久精品 | 色综合中文字幕 | 国产亚洲精品久久久久动 | 成人精品在线 | 99久久国产免费,99久久国产免费大片 | 成人在线超碰 | 精品国产理论片 | 国产一级二级av | 国产精品一区二区视频 | 久久中文欧美 | www91在线观看 | 在线视频一区观看 | 在线免费观看国产精品 | 国产视频亚洲精品 | 五月丁婷婷 | 精品国产中文字幕 | 国产精品18久久久久vr手机版特色 | 国产在线不卡一区 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 国产视频在线播放 | 最新日韩视频 | 国产91勾搭技师精品 | 视频二区| 91成人精品一区在线播放 | 色综合久久网 | 一级a性色生活片久久毛片波多野 | 首页国产精品 | 国产视频二区三区 | 国产成人一区二区三区在线观看 | 一级性视频 | 久久人人爽爽人人爽人人片av | 色视频在线观看免费 | 69视频在线播放 | 91免费网站在线观看 | 欧美国产一区二区 | 九九精品无码 | 日韩av电影中文字幕 | 麻豆你懂的 | 中文字幕中文字幕在线一区 | 日本特黄一级 | 天天射天天干天天 | 99久久精品国产欧美主题曲 | 99视频免费播放 | 99日精品 | 久久免费在线观看 | www黄色com | 亚洲综合五月天 | 岛国一区在线 | 欧美一区免费观看 | 99在线热播精品免费99热 | 97福利在线观看 | 久久老司机精品视频 | 91网址在线观看 | 亚洲无吗av| 国产精品6| 91大神电影| 久久久久五月天 | 中文字幕免费高清在线观看 | 亚洲日韩精品欧美一区二区 | 国产精品成人一区 | 日韩在线高清免费视频 | 国产精品成人一区二区 | 99精品视频在线播放免费 | 日本护士三级少妇三级999 | 香蕉视频在线免费 | 国产第一页在线播放 | 久久激情五月婷婷 | 久久精品一二三 | 日韩精品一区二区在线视频 | 国产精品久久久久久久久久东京 | 深夜男人影院 | 日韩av进入 | 在线视频 日韩 | 国产1区2区3区精品美女 | 97色婷婷人人爽人人 | 国产一区二区在线观看视频 | 亚洲国产操 | 国产精品 中文字幕 亚洲 欧美 | 久久久在线观看 | av网在线观看 | 国产剧情一区二区 | 亚洲中字幕 | 国际精品久久久久 | 久久久久亚洲精品男人的天堂 | 欧美日韩xxx | 中文字幕丰满人伦在线 | 亚洲每日更新 | 91在线看视频 | 天天插狠狠插 | 日韩中文字幕第一页 | 久久精品视频观看 | 91精品日韩 | 色人久久 | 国产日韩精品一区二区在线观看播放 | 成人在线观看免费视频 | 久久美女免费视频 | 国产成人亚洲在线观看 | 久久亚洲私人国产精品va | 国产在线观看免费 | 亚洲美女免费精品视频在线观看 | 国产精品你懂的在线观看 | 午夜精品久久久久久久99无限制 | 人人玩人人添人人澡97 | 亚洲热久久 | 岛国av在线免费 | 精品国内 | 欧美精品免费一区二区 | 欧美一级免费高清 | 国产精品mm | 国产在线高清视频 | 国产精品久久久久av免费 | 国内精品视频久久 | 久久黄色免费 | 欧美综合久久 | 亚洲国产日本 | 国产精品久久久久久久久久ktv | 国产在线高清视频 | 手机看片99 | 国产精品久久久99 | 免费三级av | 亚洲国产免费看 | 蜜臀av夜夜澡人人爽人人桃色 | 国产成人精品一二三区 | 久久免费播放视频 | 久久精品99国产国产精 | 国产黄色精品在线 | 欧美性生活大片 | 97成人超碰 | 国产精品久久久久久久久久不蜜月 | 天天天天干 | 午夜精选视频 | 操处女逼| 激情久久影院 | 五月婷婷中文网 | 黄色软件在线观看 | 男女视频91| 国产91九色蝌蚪 | 毛片二区 | 在线 欧美 日韩 | 91视频88av| 中中文字幕av| 人人爽久久久噜噜噜电影 | 国产日韩精品一区二区三区在线 | 日韩一区二区免费在线观看 | 国产精品久久久久久久av大片 | 日韩va亚洲va欧美va久久 | 久久久精品国产一区二区三区 | 最新日韩视频在线观看 | 亚洲精品中文字幕在线观看 | 狠狠色丁香婷婷综合久小说久 | 综合久久五月天 | 精品国产成人 | 久久一级片 | 丁香婷婷激情网 | 91九色视频网站 | 肉色欧美久久久久久久免费看 | 黄色高清视频在线观看 | 99久高清在线观看视频99精品热在线观看视频 | 国产美女精彩久久 | 日韩精品视频第一页 | 国产美女搞久久 | 91视频久久久 | 国产一级黄色片免费看 | 亚洲综合在线视频 | 高清不卡免费视频 | 国产美女在线观看 | 最新中文字幕在线观看视频 | 久久久久国产精品视频 | 欧美午夜一区二区福利视频 | 日本动漫做毛片一区二区 | 亚洲一区二区精品视频 | 一区二区不卡 | 黄色日批网站 | 久久毛片网 | 国产精品麻豆免费版 | 色综合久久久久综合99 | 国产一级片网站 | 欧美午夜a| 丝袜美腿在线播放 | 国产精品一区二区av麻豆 | 亚洲欧美怡红院 | 免费视频黄 | 白丝av免费观看 | 久久97超碰| 亚洲午夜精品一区二区三区电影院 | 日韩精品免费在线观看 | 国产一区二区三精品久久久无广告 | 久久综合九色综合97_ 久久久 | 国产日韩欧美在线观看 | 91精品国自产在线观看 | 欧美99热| 一区二区三区免费在线观看 | 视频91在线 | 四虎4hu永久免费 | 在线看v片 | 91亚洲综合| 久久黄色网页 | 亚洲精品激情 | 精品国产乱码久久久久久久 | 激情喷水 | 国产精品18久久久久久久 | 91久久人澡人人添人人爽欧美 | 波多野结衣在线观看一区二区三区 | 亚洲涩涩网站 | 草久在线观看视频 | 91精品国产综合久久福利 | 超碰在线观看99 | 欧美色综合天天久久综合精品 | 8x成人免费视频 | 欧美激情精品久久久久久免费 | 亚洲精品www久久久 www国产精品com | 91麻豆国产福利在线观看 | 日本丶国产丶欧美色综合 | 亚洲激情在线视频 | 色丁香久久 | 天天av综合网| www.成人精品 | 九九久久影院 | 狠狠网| 欧美aaaxxxx做受视频 | 久久久久国产a免费观看rela | 又湿又紧又大又爽a视频国产 | 欧美日韩国内在线 | 激情一区二区三区欧美 | 久久久久9999亚洲精品 | 久久免费在线观看 | 日韩在线在线 | 天天拍天天色 | 久久兔费看a级 | 91日韩在线 | 99一级片| 综合久久网 | 极品久久久久 | 亚洲精品中文在线观看 | 探花视频免费在线观看 | 在线观看中文av | 色婷婷视频在线观看 | 91在线你懂的 | 国产九九九九九 | 色五月成人 | 久久综合九色综合97_ 久久久 | 久久久久在线观看 | 国产综合在线观看视频 | 欧美精品一区二区在线播放 | 精品久久久久久久久久久久久久久久 | 91在线永久| 国产高清福利在线 | 91麻豆看国产在线紧急地址 | 亚洲欧美乱综合图片区小说区 | 久久精品久久久久久久 | 激情视频91 | 亚洲国产精品资源 | 99精品国产福利在线观看免费 | 午夜精品成人一区二区三区 | 成人永久免费 | 激情久久久久久久久久久久久久久久 | 国产精品欧美日韩在线观看 | 国产一区二区精品久久91 | 亚洲成人黄色网址 | 成人黄色毛片视频 | 国产一线在线 | 黄色成人在线网站 | 少妇bbb搡bbbb搡bbbb′ | www狠狠 | 国产高清视频免费在线观看 | 91成人短视频在线观看 | 日韩中文在线观看 | 久草在线视频在线 | 亚洲精品国产品国语在线 | 亚洲午夜精品久久久久久久久 | 国产一区二区久久 | 日本高清久久久 | 日韩免费在线网站 | 国产精品久久久久免费a∨ 欧美一级性生活片 | 亚洲视频在线观看 | 欧美一级视频在线观看 | 操天天操 | 免费在线播放黄色 | 成人一级电影在线观看 | 日韩亚洲在线 | 999视频网 | 亚洲免费精品视频 | 国内久久久 | 永久免费视频国产 | 久久综合久色欧美综合狠狠 | 久久久精品二区 | 精品一区二区在线免费观看 | 激情影音 | 欧洲激情在线 | 欧美a视频在线观看 | 久久国产露脸精品国产 | 久二影院| 免费午夜在线视频 | 中文永久字幕 | 国产亚洲字幕 | 色综合久久中文字幕综合网 | 91精品久久久久久久久久久久久 | 亚洲成人国产精品 | 国产一区在线视频观看 | 亚洲成人欧美 | 亚洲乱码精品久久久久 | 色综合欧洲 | 黄色软件网站在线观看 | 中文视频一区二区 | aaawww| 91在线看黄 | 国产香蕉视频 | 国产精品色 | 日韩免费一级a毛片在线播放一级 | 亚洲精品1234区| 黄污视频网站 | 欧美视频日韩视频 | 在线色亚洲 | 亚洲aⅴ乱码精品成人区 | 婷婷色综合 | 成人黄色在线电影 | 久久久网站 | 亚洲乱亚洲乱妇 | 三级av小说| 99综合影院在线 | 黄色三级免费 | 国产黄色片免费在线观看 | 成人黄色av网站 | 超碰免费久久 | 99精品视频免费在线观看 | 天天操天天能 | 久久视频这里有精品 | 国产69熟 | 欧美一级小视频 | 亚洲国产字幕 | 成 人 黄 色 视频播放1 | 最近中文字幕完整视频高清1 | 日韩精品在线播放 | 四虎精品成人免费网站 | 日韩欧美一区二区三区在线观看 | 欧美日韩不卡在线观看 | 久久免费看av | 日韩精品高清不卡 | 久久精品久久久久电影 | 精品久久综合 | 91成人久久 | 午夜精品福利一区二区三区蜜桃 | 五月婷婷久久丁香 | 久久久久99精品成人片三人毛片 | 色婷婷 亚洲 | 中文字幕激情 | 久久精品成人热国产成 | 麻豆精品视频在线观看免费 | 国产+日韩欧美 | 日本三级人妇 | 亚洲欧洲久久久 | 人人爱人人射 | 日韩一级成人av | 夜夜骑日日 | www成人av | 国产中文在线播放 | 五月婷婷影视 | 福利视频导航网址 | 韩日精品在线 | 又黄又爽的免费高潮视频 | 91av色| 久草视频手机在线 | 精品国产99| 国产一级一片免费播放放a 一区二区三区国产欧美 | 日韩艹 | 午夜神马福利 | 国产成人精品一区二区三区在线观看 | 国产精品无av码在线观看 | 久草在线观看视频免费 | 中文视频在线播放 | 中文字幕在线观看第三页 | 天天草网站| 久久久久在线视频 | 综合网婷婷 | 久久久www成人免费精品 | 天天射天天艹 | 又黄又刺激又爽的视频 | 亚洲视频 在线观看 | 天堂网一区二区三区 | 精品国产乱码久久久久 | 99国内精品久久久久久久 | 日韩精品专区在线影院重磅 | 婷婷久月| 另类老妇性bbwbbw高清 | 国产1区2区 | 久久免费播放视频 | 日韩久久精品一区二区三区 | 国产精品久久久久久久久久久免费看 | 国产免费区 | 免费久久久久久久 | 日韩无在线 | 一区二区视频网站 | 欧美亚洲国产一卡 | 欧美日韩一区二区久久 | 日本在线h | 国产精品久久久久久久久久尿 | 日韩高清一区在线 | 亚洲欧美色婷婷 | 久久久久成人精品亚洲国产 | 综合在线色| 国产色拍拍拍拍在线精品 | 高清不卡免费视频 | 日韩欧美视频在线播放 | 久久女同性恋中文字幕 | 四虎在线免费视频 | 免费高清无人区完整版 | 在线亚洲观看 | 美女视频黄色免费 | 中文字幕乱码亚洲精品一区 | 在线a视频免费观看 | 欧美精品乱码久久久久久按摩 | 深爱激情开心 | 人人爽人人爽人人片av免 | 99精品小视频 | 精品免费视频. | 欧美国产不卡 | 一区二区三区四区久久 | 不卡的av片 | 欧美精品久久久 | 99热99热| 精品国产自在精品国产精野外直播 | 久久久在线视频 | 91色视频 | 色综合www| 992tv在线观看网站 | 97超碰影视 | 亚洲第一成网站 | 精品久久久久久久久久久久 | 中文字幕无吗 | 国产一区二区三区在线免费观看 | 丁香六月av| 国产美女黄网站免费 | 日韩精品视频久久 | 久久久精品高清 | 精品一区久久 | 人人射av| av天天澡天天爽天天av | 天天干中文字幕 | 日韩二区在线播放 | 国产精品久久久久aaaa | 国产伦精品一区二区三区… | 日韩av一区二区在线影视 | 久久久国产精品久久久 | 国产精品久久久视频 | 少妇自拍av | 97成人精品视频在线观看 | 91chinese在线 | 国产一级视屏 | 国产一级免费在线 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 日日躁你夜夜躁你av蜜 | 国产精品久久久久久久久软件 | 911久久 | 国产无区一区二区三麻豆 | 国产99黄 | 日韩免费视频网站 | 香蕉网站在线观看 | 天天综合网久久综合网 | 久久国产电影 | 国产精品区一区 | 亚洲午夜不卡 | 亚洲精品美女免费 | 国产精品久久精品国产 | 亚洲午夜精品一区二区三区电影院 | www.色五月| 91免费版成人 | 精品亚洲欧美一区 | 成人a级网站 | 久久精久久精 | 久久精品一二三 | 欧美吞精| 欧美人牲| 69视频永久免费观看 | 国产福利资源 | 97超碰人人模人人人爽人人爱 | 免费看黄在线网站 | 91成年人在线观看 | 久久久久久久久影院 | 伊人成人激情 | 中文字幕乱码亚洲精品一区 | 国产精品a久久久久 | 成人av电影免费 | 91尤物在线播放 | 亚洲,国产成人av | 在线免费视频一区 | 国产精品入口a级 | 日韩亚洲在线观看 | 人人揉人人揉人人揉人人揉97 | 欧美一级专区免费大片 | 久草国产视频 | 日日操天天操夜夜操 | 国产精品高潮久久av | 99久久9| 国产精品视频专区 | 视频一区在线免费观看 | 在线观看国产v片 | 91福利视频免费 | 青草草在线 | 黄色av网站在线免费观看 | 午夜精品一区二区国产 | 国产精品99久久久久久有的能看 | 99国产精品视频免费观看一公开 | 91精品视频在线 | 五月天堂色 | 国产中文自拍 | 天天色天天操综合网 | 久久精品久久99精品久久 | 在线视频久 | 99精品视频免费在线观看 | 精品久久国产 | 国产中文伊人 | 久久综合操 | 麻豆视频免费播放 | 国产精品久久久久久爽爽爽 | 国产黄色在线网站 | 久久婷婷色 | 免费观看视频黄 | 国产成人精品久久久久蜜臀 | 日日操日日干 | 久久噜噜少妇网站 | 日韩理论影院 | 国产黄在线 | 天天操狠狠操网站 | 婷婷久久精品 | 色资源网在线观看 | 国产免费xvideos视频入口 | 国产在线一卡 | 久草精品视频在线看网站免费 | av成人黄色| 一级片视频在线 | 中文字幕人成一区 | 色在线网 | 亚洲激情 欧美激情 | 国产探花在线看 | 久久精品中文字幕一区二区三区 | 国产成人精品av在线 | 夜夜视频资源 | 91精品在线麻豆 | 日韩精品中文字幕在线不卡尤物 | av资源网在线播放 | 亚洲更新最快 | av免费观看高清 | 色综合久久中文综合久久牛 | 午夜美女福利 | 国产精品高潮呻吟久久久久 | 超碰在线98 | 91精品国产99久久久久 | 久久精品国产免费看久久精品 | 中文字幕丝袜 | 久久超碰免费 | 亚洲永久在线 | 国产 日韩 在线 亚洲 字幕 中文 | 天天色成人网 | 亚洲精品免费在线观看视频 | 久久96国产精品久久99软件 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 天天操天天射天天爱 | 欧美成a人片在线观看久 | 日韩一区二区三区不卡 | 美女免费电影 | 成人免费观看av | 日韩最新av在线 | 在线观看av大片 | 91九色国产在线 | 久久视频| 一区二区三区四区五区六区 | 午夜精品久久久久99热app | 免费热情视频 | 一区二区三区高清不卡 | 日韩精品免费在线视频 | 在线观看色网站 | www.av在线.com | 亚洲精品字幕在线 | 在线观看免费视频 | 一区二区三区免费看 | 欧美午夜精品久久久久久孕妇 | 久久高清精品 | 久久久久北条麻妃免费看 | 国产一区在线视频观看 | 国产在线1区| 91在线视频免费播放 | 狠狠躁日日躁 | 久久精品草 | 中文字幕在线免费97 | 日本黄色片一区二区 | 免费视频一区二区 | 在线观看视频一区二区三区 | 精品一区二区在线播放 | 亚洲日韩精品欧美一区二区 | 国产精品99蜜臀久久不卡二区 | 久草av在线播放 | 成人黄色资源 | 国产一区二区高清视频 | 欧美一级性视频 | 精品一区二区三区在线播放 | www五月天com | 人人爽人人舔 | 午夜精品久久久久久久99婷婷 | 国产精品欧美久久久久三级 | 中文字幕乱码日本亚洲一区二区 | 99久久er热在这里只有精品66 | 久久久精品视频成人 | 韩国一区二区三区在线观看 | 顶级bbw搡bbbb搡bbbb | 在线视频 你懂得 | 青青河边草免费直播 | 亚洲国产免费 | 日韩大陆欧美高清视频区 | 干 操 插| 91在线精品播放 | 久久国内免费视频 | 91视频高清免费 | 特级毛片网站 | 国产永久免费 | 免费看黄色大全 | 久久国产精品久久精品国产演员表 | 日韩中文字幕免费电影 | 韩国精品在线观看 | 中文字幕久久精品亚洲乱码 | 久久久久久久久久久综合 | 久久99国产综合精品免费 | 狠狠搞,com | 日日天天干 | 91成人在线视频 | 国产精品精品国产婷婷这里av | 天堂av高清 | 一区二区激情 | 97在线精品视频 | 久草在| 99中文字幕视频 | 亚洲欧美成人综合 | 亚洲va欧美va | 97在线免费视频观看 | 波多野结衣网址 | 九九综合久久 | 98久久| 在线观看爱爱视频 | 成年人视频免费在线播放 | 婷婷av色综合 | 成人一区二区在线 | 欧美日韩视频在线观看一区二区 | 水蜜桃亚洲一二三四在线 | 国产欧美中文字幕 | 久久成年人视频 | 日韩1页| 99精品免费视频 | 97在线观看免费观看 | 日韩一级理论片 | 婷婷色5月 | 国产精品不卡视频 | avcom在线 | 日韩簧片在线观看 | 免费观看性生活大片3 | 精品久久久久久久久久久久 | 久久激情影院 | 午夜在线观看影院 | 天天操天天操天天操天天操天天操 | 久久综合视频网 | 亚洲精品一区二区三区四区高清 | 亚洲国产成人久久 | 午夜精品影院 | 亚洲日本中文字幕在线观看 | 国产视频在线看 | 2022国产精品视频 | 国产久草在线观看 | 欧美激情精品久久久久久 | 亚洲一区二区麻豆 | 一区二区三区免费在线观看视频 | 欧美在线一二区 | 国产69精品久久久久99尤 | 人人超碰97 | 日韩精品一区不卡 | 国产精品一区在线 | 日日夜夜精品免费 | 免费观看www小视频的软件 | 在线观看国产区 | 国产你懂的在线 | 日韩一三区 | 国产成人精品一区二 | 久久天堂亚洲 | 亚洲一区二区三区四区在线视频 | 婷婷丁香在线 | www在线观看视频 | 欧美日韩不卡在线观看 | 亚洲资源视频 | 亚洲成人av片在线观看 | 美女网站久久 | 91视视频在线直接观看在线看网页在线看 | 国产福利精品一区二区 | av大全在线观看 | 中文字幕在线观看资源 | 久久精彩免费视频 | 91色综合 | 婷婷在线播放 | 最近最新最好看中文视频 |