springCloud基礎(chǔ)

二芭梯、服務(wù)的注冊(cè)與發(fā)現(xiàn) - Eureka

問題:為什么需要注冊(cè)中心坛芽?
如果沒有注冊(cè)中心捣作,服務(wù)和服務(wù)之間會(huì)形成硬耦合狀態(tài)


image.png

注冊(cè)中心的作用就是為了減少服務(wù)間的調(diào)用耦合


image.png

1、Eureka 對(duì)比 Zookeeper
image.png

2昂验、Eureka服務(wù)端的搭建

2.1 配置自定義的父工程(繼承SpringBoot、SpringCloud)

pom.xml

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.qf</groupId>
    <artifactId>springcloud_demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
   <!-- <name>springcloud_demo</name>
    <description>Demo project for Spring Boot</description>-->

    <!--
        SpringBoot 2.1.x <-> SpringCloud版本 G版
        SpringBoot 2.2.x <-> SpringCloud版本 H版
    -->
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR5</spring-cloud.version>
    </properties>

    <!-- 刪除
        <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>-->

    <!-- 相當(dāng)于讓當(dāng)前的工程繼承了SpringCloud的父工程艾扮,用這種方式可以實(shí)現(xiàn)Maven的多繼承 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <!-- 導(dǎo)入pom工程既琴,相當(dāng)于多繼承 -->
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!--插件刪除 只有微服務(wù)才要依賴<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>-->

</project>

2.2 創(chuàng)建Eureka服務(wù)

1)創(chuàng)建一個(gè)Maven工程(Eureka微服務(wù)),繼承自定義的父工程(springcloud_demo)
2)修改當(dāng)前maven工程的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">
       <parent>
           <artifactId>springcloud_demo</artifactId>
           <groupId>com.qf</groupId>
           <version>0.0.1-SNAPSHOT</version>
       </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud_eureka</artifactId>

    <dependencies>
        <!-- 必須到包含starter的依賴包 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3)配置當(dāng)前springboot的啟動(dòng)類

package com.qf.application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
//添加注解
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        //run的第一個(gè)參數(shù)一定是添加了@SpringBootApplication注解的類
        //不是當(dāng)前類
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

4)配置application.yml

server:
  port: 20000
spring:
  application:
    #配置微服務(wù)的名稱泡嘴,以后所有的微服務(wù)甫恩,都必須配置這個(gè)屬性,不然注冊(cè)中心的名字會(huì)變成unable
    name: eureka-server
#配置eureka的相關(guān)屬性
eureka:
  client:
    service-url:
      #配置eureka的注冊(cè)地址
      #defaultZone沒有提示酌予,必須手寫
      defaultZone: http://localhost:20000/eureka
    #當(dāng)前的微服務(wù)就是注冊(cè)中心磺箕,注冊(cè)中心不能從注冊(cè)中心抓取服務(wù),所以該配置需要配置成false
    fetch-registry: false
    #使得當(dāng)前的微服務(wù)不注冊(cè)到注冊(cè)中心上
    register-with-eureka: false

5)啟動(dòng)SpringBoot工程 - 啟動(dòng)Eureka服務(wù)端
6)訪問注冊(cè)中心抛虫,http://localhost:20000

image.png

3松靡、微服務(wù)(Eureka客戶端)的搭建

3.1 Eureka客戶端的搭建

1)創(chuàng)建一個(gè)Maven工程,繼承springcloud_demo工程
2)配置Maven工程的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">
    <parent>
        <artifactId>springcloud_demo</artifactId>
        <groupId>com.qf</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud_mircoservice_student</artifactId>

    <dependencies>
        <!-- 微服務(wù)需要對(duì)外提供功能建椰,所以需要添加web依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 同時(shí)為了能夠讓微服務(wù)注冊(cè)到注冊(cè)中心之上 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>

3)配置啟動(dòng)類

    @SpringBootApplication
    //SpringCloud 2.x之后 該注解可以省略
    @EnableEurekaClient
    public class StudentApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(StudentApplication.class, args);
        }
    }

4)配置application.yml

    server:
      port: 8080
    #微服務(wù)的名字
    spring:
      application:
        #微服務(wù)的名字一定不要用下劃線
        name: micro-student
    eureka:
      client:
        service-url:
          #配置注冊(cè)中心的地址雕欺,因?yàn)槲⒎?wù)需要注冊(cè),也需要抓取服務(wù)所以另外兩個(gè)配置就可以省略了
          defaultZone: http://localhost:20000/eureka

5)編寫微服務(wù)的功能接口(根據(jù)微服務(wù)本身的業(yè)務(wù)不同,編寫不同的接口)

    package com.qf.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/stu")
    public class StuController {
    
        /**
         * 根據(jù)學(xué)生id查詢學(xué)生姓名
         *
         * @ResponseBody -> 返回json (錯(cuò)誤)
         *
         * @ResponseBody -> 將方法的返回值屠列,放入response響應(yīng)體中
         *
         * 響應(yīng)體 -> 數(shù)值啦逆、字符串(json)、二進(jìn)制流....
         *
         * @param sid
         * @return
         */
        @RequestMapping("/queryName")
        public String getNameById(Integer sid){
            switch (sid){
                case 1:
                    return "小明";
                case 2:
                    return "小紅";
                case 3:
                    return "小剛";
                default:
                    return "查無此人";
            }
        }
    }

4笛洛、Eureka的集群

4.1 eureka集群的工作模式

image.png

4.2 Eureka集群的搭建(偽集群)

1)將eureka服務(wù)端復(fù)制2份
2)修改eureka服務(wù)的端口(因?yàn)槭莻渭合闹荆谝慌_(tái)機(jī)器上,需要修改端口)
3)找到本機(jī)的hosts文件(C:\Windows\System32\drivers\etc\hosts),分別給本機(jī)設(shè)置3個(gè)主機(jī)名


image.png

注意:第一次修改hosts文件撞蜂,一般沒有權(quán)限盲镶,所以需要修改下文件權(quán)限,如何修改文件權(quán)限蝌诡,自行百度

4)修改3個(gè)eureka服務(wù)的service-url配置

#配置eureka的相關(guān)屬性
eureka:
  client:
    service-url:
      #配置eureka的注冊(cè)地址
      #defaultZone沒有提示溉贿,必須手寫
      defaultZone: http://eureka1:20000/eureka,http://eureka2:20001/eureka,http://eureka3:20002/eureka
    #當(dāng)前的微服務(wù)就是注冊(cè)中心,注冊(cè)中心不能從注冊(cè)中心抓取服務(wù)浦旱,所以該配置需要配置成false
    fetch-registry: false
    #使得當(dāng)前的微服務(wù)不注冊(cè)到注冊(cè)中心上
    register-with-eureka: false

5)啟動(dòng)三臺(tái)eureka服務(wù)


image.png

6)所有的微服務(wù)的注冊(cè)地址必須改成eureka集群的地址

    eureka:
      client:
        service-url:
          #配置注冊(cè)中心的地址宇色,因?yàn)槲⒎?wù)需要注冊(cè),也需要抓取服務(wù)所以另外兩個(gè)配置就可以省略了
          defaultZone: http://eureka1:20000/eureka,http://eureka2:20001/eureka,http://eureka3:20002/eureka

5颁湖、Eureka的自我保護(hù)機(jī)制

5.1 什么是Eureka的自我保護(hù)機(jī)制宣蠕?

Eureka如果收到的微服務(wù)心跳相對(duì)于應(yīng)該收到的微服務(wù)心跳來說,如果低于了85%甥捺,那么就會(huì)觸發(fā)Eureka的自我保護(hù)機(jī)制抢蚀。一旦自我保護(hù)機(jī)制啟動(dòng),Eureka會(huì)保護(hù)所有的微服務(wù)镰禾,不被移除皿曲,哪怕當(dāng)前微服務(wù)已經(jīng)下線,仍然會(huì)保留到Eureka微服務(wù)列表中吴侦。

5.2 Eureka自我保護(hù)機(jī)制觸發(fā)后的表現(xiàn)

image.png

5.3 自我保護(hù)機(jī)制的作用

為什么Eureka要一種看起來如此傻逼的設(shè)計(jì)屋休?- 自我保護(hù)機(jī)制是為了保證微服務(wù)間的高可用性,避免腦裂的影響
為什么Zookeeper要設(shè)計(jì)一個(gè)過半數(shù)存活原則备韧?感覺特別浪費(fèi)資源劫樟? - 為了讓整個(gè)集群一定只有一個(gè)Leader
CAP原則:任何一個(gè)分布式系統(tǒng),都只能滿足CAP中的2個(gè)原則织堂,因?yàn)榉謪^(qū)問題不可避免叠艳,所以P是必選的,一般的系統(tǒng)易阳,都是從C和A中做選擇虑绵。Zookeeper是CP設(shè)計(jì),而Eureka是AP設(shè)計(jì)闽烙。
C(一致性)
A(可用性)
P(分區(qū)容錯(cuò)性)

zookeeper的過半數(shù)存活的設(shè)計(jì)

image.png

Eureka的自我保護(hù)設(shè)計(jì)


image.png

思考:Eureka的自我保護(hù)機(jī)制翅睛,雖然是為了保證服務(wù)的高可用声搁,但是如果服務(wù)真的掛掉了?那么也被自我保護(hù)起來捕发,是不是有問題呢疏旨?
自我保護(hù)機(jī)制一旦啟動(dòng),確實(shí)會(huì)保護(hù)那些真的出問題的微服務(wù)扎酷,所以Eureka設(shè)計(jì)了一個(gè)閾值檐涝,當(dāng)15%的心跳都丟失的時(shí)候,才會(huì)發(fā)生自我保護(hù)機(jī)制法挨。因?yàn)檫@個(gè)時(shí)候谁榜,相對(duì)于15%的機(jī)器掛掉來說,發(fā)生腦裂的概率大一些凡纳。但是有沒有可能真的是15%機(jī)器掛掉了窃植?這個(gè)時(shí)候Eureka是不能幫我們判斷的,需要客戶端本身有一定的容錯(cuò)機(jī)制荐糜,比如斷路器
思考:CP設(shè)計(jì)好巷怜?還是AP設(shè)計(jì)好? - 取決于業(yè)務(wù)暴氏,對(duì)于注冊(cè)中心來說延塑,偶爾拿到出問題的微服務(wù),其實(shí)對(duì)于整個(gè)架構(gòu)來講沒有太大問題答渔,微服務(wù)架構(gòu)最害怕整個(gè)注冊(cè)中心服務(wù)不可用关带,因此對(duì)于注冊(cè)中心來說,AP(高可用)設(shè)計(jì)強(qiáng)于CP(一致性)設(shè)計(jì)沼撕。并不是說一致性不好宋雏,對(duì)于分布式鎖的業(yè)務(wù)來講,一定要CP端朵,不然整個(gè)集群的業(yè)務(wù)會(huì)混亂

注意:zookeeper可以是偶數(shù)臺(tái),只是說奇數(shù)臺(tái)燃箭,服務(wù)器成本更低一些

三冲呢、服務(wù)的調(diào)用-Ribbon + RestTemplate(獨(dú)立的組件)

1、什么是Ribbon招狸?

Ribbon是一個(gè)客戶端的負(fù)載均衡器敬拓,用來進(jìn)行SpringCloud間的微服務(wù)負(fù)載均衡調(diào)用

2、什么是客戶端負(fù)載均衡裙戏?服務(wù)端負(fù)載均衡乘凸?

image.png

負(fù)載均衡的方式:
1)客戶端負(fù)載均衡
2)服務(wù)端負(fù)載均衡
2.1)網(wǎng)絡(luò)4層負(fù)載
2.2)網(wǎng)絡(luò)7層負(fù)載 - nginx

3、Ribbon+RestTemplate的使用

1)再創(chuàng)建一個(gè)微服務(wù)(班級(jí)服務(wù))累榜,用于后續(xù)的服務(wù)間調(diào)用

2)在主動(dòng)的調(diào)用方(學(xué)生服務(wù) -> 班級(jí)服務(wù)营勤,學(xué)生服務(wù)就是主動(dòng)調(diào)用方)添加依賴

    <!-- 添加ribbon依賴 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            </dependency>

3)啟動(dòng)類中聲明RestTemplate組件

    @Bean
    @LoadBalanced//負(fù)載均衡
    public RestTemplate getRest(){
        return new RestTemplate();
    }

4)編寫服務(wù)調(diào)用代碼

     //根據(jù)班級(jí)id灵嫌,調(diào)用班級(jí)服務(wù),查詢班級(jí)信息
     //關(guān)鍵 調(diào)用地址 MICRO-CLASSES 必須寫一個(gè)微服務(wù)的名稱
    String classInfo = restTemplate
            .getForObject("http://MICRO-CLASSES/cls/queryClsName?cid=1",String.class);

4葛作、Ribbon的負(fù)載均衡

思考:Eureka如何知道兩個(gè)服務(wù)是集群的關(guān)系寿羞?還是兩個(gè)獨(dú)立的微服務(wù)?
微服務(wù)名稱相同赂蠢,那么就是集群關(guān)系

    spring:
      application:
        name: micro-classes
image.png

4.1 Ribbon的負(fù)載均衡策略

/**
 * 切換負(fù)載均衡策略
 * @return
 */
@Bean
public IRule getRule(){
    return new RandomRule();
}

四绪穆、服務(wù)的調(diào)用-Feign(底層其實(shí)就是Ribbon)

1、為什么有了Ribbon還有用Feign虱岂?

Feign底層也調(diào)用了Ribbon玖院,F(xiàn)eign其實(shí)本質(zhì)上是Ribbon + Hystrix(豪豬)的集合體,因?yàn)镽ibbon本身的寫法不夠面向?qū)ο蟮卺芏郕ava程序員對(duì)這種寫法會(huì)很不習(xí)慣难菌。

2、Feign的使用

1)調(diào)用方添加feign的依賴

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

2)編寫一個(gè)Feign接口(關(guān)鍵)

    @FeignClient("MIRCO-TEACHER")
    public interface ITeacherFeign {
    
        @RequestMapping("/tea/queryTeaName")
        String queryTeaName(@RequestParam("tid") Integer tid);
    }

3)在需要調(diào)用微服務(wù)的地方绍傲,注入改接口

    @Autowired
    private ITeacherFeign teacherFeign;
    
    ...
    //遠(yuǎn)程調(diào)用教師服務(wù)
    String s = teacherFeign.queryTeaName(cid);

4)配置啟動(dòng)類注解

    @SpringBootApplication(scanBasePackages = "com.qf")
    @EnableEurekaClient
    //表示啟動(dòng)feign扔傅,而且這個(gè)注解需要找到Feign接口所在的包,默認(rèn)去啟動(dòng)類所在包下找
    //所有如果Feign接口沒有在啟動(dòng)類的包下烫饼,就需要手動(dòng)配置掃描
    @EnableFeignClients(basePackages = "com.qf.feign")
    public class ClassesApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ClassesApplication.class, args);
        }
    }

3猎塞、Feign的超時(shí)與重試

Feign默認(rèn)超時(shí)時(shí)間為1S,如果1S內(nèi)杠纵,被調(diào)用方?jīng)]有返回結(jié)果荠耽,就默認(rèn)失敗,然后重試1次比藻。
有些時(shí)候铝量,如果不加干預(yù),可能引起請(qǐng)求的重復(fù)發(fā)送银亲,導(dǎo)致出現(xiàn)各種問題慢叨。
注意:Feign自帶超時(shí)和重試的功能,但是默認(rèn)是關(guān)閉的务蝠。所以我們看到的超時(shí)和重試的效果拍谐,是底層Ribbon提供的。如果開啟了Feign的超時(shí)重試就會(huì)覆蓋掉Ribbon的設(shè)置

設(shè)置Feign的超時(shí)和重試:

    #配置ribbon的超時(shí)和重試
    ribbon:
      #配置的是連接超時(shí)
      ConnectTimeout: 1000
      #配置讀超時(shí)
      ReadTimeout: 1000
      #配置ribbon的重試次數(shù)馏段,默認(rèn)是0
      MaxAutoRetries: 0
      #配置ribbon的下個(gè)服務(wù)的重試次數(shù)轩拨,默認(rèn)是1
      MaxAutoRetriesNextServer: 0
    
    #MaxAutoRetriesNextServer為m, 表示會(huì)重試(m + 1)個(gè)實(shí)例
    #MaxAutoRetries為n院喜,表示單實(shí)例重試(n + 1)次
    #總的執(zhí)行次數(shù) (n + 1) * (m + 1)
    
    
    #配置Feign的超時(shí)亡蓉,一旦配置了Feign的超時(shí),ribbon的重試和超時(shí)會(huì)全部失效
    feign:
      client:
        config:
          MIRCO-TEACHER: #可以針對(duì)不同的微服務(wù)配置不同的超時(shí)時(shí)間
            connectTimeout: 1000
            readTimeout: 6000
          MIRCO-STUDENT:
            connectTimeout: 1000
            readTimeout: 2000

五喷舀、Hystrix-斷路器

1小槐、 什么是斷路器

斷路器 - 就是微服務(wù)架構(gòu)的保險(xiǎn)絲

2、為什么需要Hystrix(保險(xiǎn)絲)绘雁?

在微服務(wù)架構(gòu)中啄寡,根據(jù)業(yè)務(wù)會(huì)拆分成一個(gè)一個(gè)為微服務(wù),服務(wù)于服務(wù)之間可以互相調(diào)用。為了保證高可用性,單個(gè)服務(wù)通常會(huì)集群部署,但是由于網(wǎng)絡(luò)等原因简识,不能保證服務(wù)100%可用。如果單個(gè)服務(wù)出現(xiàn)問題感猛,調(diào)用這個(gè)服務(wù)的服務(wù)就有可能出現(xiàn)線程阻塞七扰,剛好這個(gè)時(shí)候大量的請(qǐng)求在訪問當(dāng)前服務(wù),就會(huì)導(dǎo)致當(dāng)前服務(wù)的線程資源不足陪白,從而導(dǎo)致服務(wù)癱瘓颈走,形成故障轉(zhuǎn)移,導(dǎo)致"服務(wù)雪崩"

圖解析:

tomcat的工作原理咱士,客戶端發(fā)請(qǐng)求給tomcat立由,tomcat調(diào)用一條線程出來解析格式化文本,再去找相對(duì)應(yīng)的controller進(jìn)行處理序厉,最后返回一個(gè)值給線程锐膜,結(jié)束線程。


image.png

3弛房、Hystrix是如何解決服務(wù)間調(diào)用問題的

資源隔離:雞蛋不要放在一個(gè)籃子里(線程池隔離道盏、信號(hào)量隔離)
服務(wù)降級(jí):當(dāng)調(diào)用目標(biāo)服務(wù)出問題(超時(shí)、報(bào)錯(cuò)....)時(shí)文捶,會(huì)自動(dòng)的調(diào)用一個(gè)本地的方法荷逞,返回一個(gè)默認(rèn)值
請(qǐng)求熔斷:一旦確定目標(biāo)服務(wù)出問題(失敗比例),Hystrix的熔斷器會(huì)自動(dòng)打開粹排,攔截后續(xù)的所有請(qǐng)求种远,立刻判定失敗,進(jìn)行服務(wù)降級(jí)顽耳。過了單位時(shí)間之后坠敷,熔斷器變成半開狀態(tài),放行一個(gè)請(qǐng)求斧抱,如果還是失敗常拓,繼續(xù)全開渐溶,攔截請(qǐng)求辉浦,否則熔斷器關(guān)閉。

4茎辐、Ribbon整合Hystrix(了解)

1)在Ribbon的工程中宪郊,添加Hystrix的依賴

    <!-- hystrix 依賴-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>

2)在啟動(dòng)類上添加注解

    ....
    @EnableHystrix
    ...

3)在使用RestTemplate的地方掂恕,通過注解實(shí)現(xiàn)資源隔離

    //使用注解,隔離其他服務(wù)的調(diào)用資源弛槐,被該注解標(biāo)記的方法會(huì)被Hystrix提供的線程調(diào)用(線程池隔離)
    //fallbackMethod就是指定降級(jí)方法懊亡,當(dāng)資源不足或者服務(wù)報(bào)錯(cuò)時(shí),會(huì)走降級(jí)方法
    //熔斷器默認(rèn)已經(jīng)開啟
    @HystrixCommand(fallbackMethod = "myFallBack")
    @RequestMapping("/queryName")
    public String getNameById(Integer sid){
        ......
    }
    
    /**
     * 降級(jí)方法
     * @param sid
     * @return
     */
    public String myFallBack(Integer sid){
        return "服務(wù)異常乎串,降級(jí)方法調(diào)用5暝妗!叹誉!";
    }

5鸯两、Feign整合Hystrix(常用)

1)直接通過配置,開啟Hystrix

    #開啟Feign的斷路器功能      
    feign:
      hystrix:
        enabled: true

注意:Feign中已經(jīng)整合了Hystrix长豁,所以不需要添加任何依賴钧唐,F(xiàn)eign中的Hystrix功能默認(rèn)關(guān)閉

2)配置Feign接口,編寫降級(jí)實(shí)現(xiàn)類

    @FeignClient(value = "MIRCO-TEACHER", fallback = ITeacherFeign.TeacherFeign.class)
    public interface ITeacherFeign {
    
        @RequestMapping("/tea/queryTeaName")
        String queryTeaName(@RequestParam("tid") Integer tid);
    
    
        /**
         * Feign接口的實(shí)現(xiàn)類
         */
        @Component
        public static class TeacherFeign implements ITeacherFeign{
    
            //就是對(duì)應(yīng)的降級(jí)方法
            @Override
            public String queryTeaName(Integer tid) {
                return "教師服務(wù)調(diào)用異常匠襟,服務(wù)進(jìn)行降級(jí)6巯馈!酸舍!";
            }
        }
    }

6帅韧、Hystrix的常用配置

    #配置Hystrix的常用屬性
    hystrix:
      command:
        default:
          execution:
            isolation:
              #資源隔離的策略,線程池隔離(默認(rèn))父腕、信號(hào)量隔離(SEMAPHORE)
              strategy: THREAD
              #hystrix超時(shí)時(shí)間弱匪,默認(rèn)1秒
              thread:
                timeoutInMilliseconds: 500
            timeout:
              #是否開啟Hystrix的超時(shí)時(shí)間, 默認(rèn)為true璧亮,如果設(shè)置為false萧诫,
              #意為不超時(shí),但是Feign的超時(shí)仍然起作用
              enabled: true
          #熔斷器的相關(guān)配置枝嘶,默認(rèn)打開熔斷器
          circuitBreaker:
            enabled: true
            #單位時(shí)間內(nèi)帘饶,失敗的次數(shù),如果達(dá)到這個(gè)閾值群扶,那么熔斷器就會(huì)打開及刻,默認(rèn)20次
            requestVolumeThreshold: 5
            #多久之后,熔斷器進(jìn)入半開狀態(tài)竞阐,默認(rèn)5S
            sleepWindowInMilliseconds: 5000

注意:實(shí)際開發(fā)過程中缴饭,調(diào)用超時(shí),需要結(jié)合Feign的超時(shí)和Hystrix的超時(shí)骆莹,哪個(gè)超時(shí)設(shè)置的小颗搂,哪個(gè)就起作用,默認(rèn)都是1S幕垦。

7丢氢、Hystrix的儀表盤(圖形化界面監(jiān)控)

什么是Hystrix的儀表盤傅联?
Hystrix提供了一個(gè)組件,可以監(jiān)控Hystrix的微服務(wù)疚察,來動(dòng)態(tài)掌握各個(gè)微服務(wù)之間的請(qǐng)求調(diào)用情況蒸走。
配Hystrix的儀表盤

1)單獨(dú)創(chuàng)建一個(gè)SPringBoot項(xiàng)目,作為儀表盤工程
2)該工程添加依賴儀表盤工程

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>

3)配置啟動(dòng)注解儀表盤工程

    @EnableHystrixDashboard

4)啟動(dòng)該工程


image.png

5)去到需要監(jiān)控的工程貌嫡,配置監(jiān)控Servlet

    //添加監(jiān)控依賴
    <dependency>
        <groupId>com.netflix.hystrix</groupId>
        <artifactId>hystrix-metrics-event-stream</artifactId>
        <version>1.5.18</version>
        <scope>compile</scope>
    </dependency>
    
    
    //啟動(dòng)類配置監(jiān)控的Servlet
    @Bean
        public ServletRegistrationBean<HystrixMetricsStreamServlet> getServlet(){
            HystrixMetricsStreamServlet hystrixMetricsStreamServlet 
                = new HystrixMetricsStreamServlet();
            ServletRegistrationBean<HystrixMetricsStreamServlet> 
                servletRegistrationBean = new ServletRegistrationBean();
            servletRegistrationBean.setServlet(hystrixMetricsStreamServlet);
            servletRegistrationBean.addUrlMappings("/hystrix.stream");
            servletRegistrationBean.setName("HystrixMetricsStreamServlet");
            return servletRegistrationBean;
        }

6)去到儀表盤工程比驻,配置監(jiān)控地址即可

image.png

六、路由網(wǎng)關(guān)

1岛抄、什么是路由網(wǎng)關(guān)嫁艇?

簡(jiǎn)單來說,路由網(wǎng)關(guān)往往是微服務(wù)架構(gòu)的入口組件弦撩,外來的所有的請(qǐng)求步咪,都需要通過路由網(wǎng)關(guān)進(jìn)行分發(fā)和過濾。路由網(wǎng)關(guān)的核心功能:請(qǐng)求的路由益楼、請(qǐng)求的過濾

2猾漫、為什么需要路由網(wǎng)關(guān)?

image.png

路由網(wǎng)關(guān)提供了外部請(qǐng)求的訪問入口感凤,所有的外部請(qǐng)求都只需要知道路由網(wǎng)關(guān)的地址就行了悯周,無需知道每個(gè)微服務(wù)的訪問地址,路由網(wǎng)關(guān)可以將外部的請(qǐng)求負(fù)載分發(fā)給不同的微服務(wù)陪竿,這樣可以對(duì)外屏蔽微服務(wù)架構(gòu)內(nèi)部的結(jié)構(gòu)禽翼。因?yàn)槁酚删W(wǎng)關(guān)往往是外部請(qǐng)求訪問微服務(wù)架構(gòu)的入口,所以可以在路由網(wǎng)關(guān)做請(qǐng)求過濾的工作族跛。

SpringCloud默認(rèn)提供了2個(gè)路由網(wǎng)關(guān)闰挡,Zuul和Gateway,Zuul是網(wǎng)飛(netflix)提供的路由組件礁哄,而Gateway是SpringCloud團(tuán)隊(duì)自己開發(fā)的一款路由組件长酗,用來替換Zuul的

3、路由網(wǎng)關(guān)的請(qǐng)求路由實(shí)現(xiàn)

1)創(chuàng)建一個(gè)微服務(wù)工程桐绒,注意該微服務(wù)工程不能添加web依賴
2)添加Gateway依賴

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

3)配置application.yml

    server:
      port: 18888
    spring:
      application:
        name: gateway-server
      #配置路由網(wǎng)關(guān)的路由規(guī)則
      cloud:
        gateway:
          routes:
              #id:規(guī)則的標(biāo)識(shí)夺脾,是一個(gè)合法不重復(fù)的字符串即可
            - id: guize1
              #predicates:路由規(guī)則,什么樣的請(qǐng)求茉继,匹配當(dāng)前這個(gè)規(guī)則
              predicates:
                # http://localhost:18888/stu/a/b
                - Path=/stu/**
              #當(dāng)前的規(guī)則咧叭,分發(fā)給哪個(gè)微服務(wù)
              #http://MICRO-STUDENT/stu/a/b
              uri: lb://MICRO-STUDENT
     
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:20000/eureka

七、分布式統(tǒng)一配置中心

image.png

1烁竭、統(tǒng)一配置中心的搭建(服務(wù)端)

1)創(chuàng)建一個(gè)工程(可以不是微服務(wù)菲茬,不用注冊(cè)到注冊(cè)中心上)

2)添加依賴

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>

3)啟動(dòng)類添加依賴

    @EnableConfigServer

4)配置application.yml

    server:
      port: 40000
    spring:
      application:
        name: config-server
      #讀取本地配置文件,強(qiáng)制需要配置該屬性
      profiles:
        active: native
      cloud:
        config:
          server:
            #配置文件放到本地
            native:
              search-locations: classpath:config
            #配置文件放到svn上的配置
    #        svn:
    #          uri: #svn倉庫的地址
            #配置文件放到git上的配置
    #        git:
    #          uri: xxxxxxxx #配git倉庫的地址,git倉庫里放的就是各種配置文件

5)在config文件夾中生均,隨便準(zhǔn)備一個(gè)配置文件

    com:
      name: zhangsan

6)運(yùn)行配置中心,測(cè)試是否能都讀到管理的配置信息


image.png

2腥刹、微服務(wù)配置的統(tǒng)一管理(其他微服務(wù)的配置全部交由統(tǒng)一配置中心管理)

1)將所有微服務(wù)的application.yml放到統(tǒng)一配置中心的指定目錄下(git马胧、svn需要傳到指定的倉庫中)
2)所有微服務(wù)添加依賴

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

3)所有的微服務(wù),添加一個(gè)配置文件bootstrap.yml

注意:bootstrap.yml用法和application.yml的用法完全一致衔峰,但是在SpringBoot啟動(dòng)過程中佩脊,是先加載bootstrap.yml再加載application.yml

    spring:
      cloud:
        config:
          #配置統(tǒng)一配置中心的地址
          uri: http://localhost:40000
          #配置文件的名字
          name: teacher
          #配置文件的環(huán)境
          profile: local

4)啟動(dòng)配置中心、再啟動(dòng)微服務(wù)


image.png

注意:這里有一個(gè)強(qiáng)制的順序要求垫卤,必須先啟動(dòng)配置中心威彰,再啟動(dòng)微服務(wù)

3、統(tǒng)一配置需要注意的一些地方

1穴肘、如果配置文件是放在Config Server本地管理的歇盼,那么每次修改配置文件,都必須重啟Config Server才會(huì)生效
2评抚、如果配置文件是放在Config Server的git豹缀、SVN倉庫中管理的,那么每次修改配置文件慨代,不用重啟Config Server邢笙,會(huì)自動(dòng)生效
3、不管配置文件放在哪里侍匙,每次修改配置文件氮惯,所有的Config Client(微服務(wù)),都必須重啟才有效想暗。原因在于Config Client只有在啟動(dòng)的時(shí)候會(huì)去抓一次配置妇汗,然后配置就緩存到本地了,后續(xù)所有的代碼都是從本地獲得配置说莫,因此服務(wù)的變化铛纬,是無感知的,這也是一種優(yōu)化的結(jié)果
4唬滑、關(guān)于配置修改告唆,需要重啟所有微服務(wù)的解決方案(只說方案,不實(shí)現(xiàn))

統(tǒng)一配置中心的管理方案一


image.png

統(tǒng)一配置中心的管理方案二 升級(jí)方案

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載晶密,如需轉(zhuǎn)載請(qǐng)通過簡(jiǎn)信或評(píng)論聯(lián)系作者擒悬。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市稻艰,隨后出現(xiàn)的幾起案子懂牧,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僧凤,死亡現(xiàn)場(chǎng)離奇詭異畜侦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)躯保,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門旋膳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人途事,你說我怎么就攤上這事验懊。” “怎么了尸变?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵义图,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我召烂,道長(zhǎng)碱工,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任奏夫,我火速辦了婚禮痛垛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桶蛔。我一直安慰自己匙头,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布仔雷。 她就那樣靜靜地躺著蹂析,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碟婆。 梳的紋絲不亂的頭發(fā)上电抚,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音竖共,去河邊找鬼蝙叛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛公给,可吹牛的內(nèi)容都是我干的借帘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼淌铐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼肺然!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起腿准,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤际起,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體街望,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡校翔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了灾前。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片防症。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖豫柬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扑浸,我是刑警寧澤烧给,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站喝噪,受9級(jí)特大地震影響础嫡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酝惧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一榴鼎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晚唇,春花似錦巫财、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至悍及,卻和暖如春闽瓢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背心赶。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工扣讼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缨叫。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓椭符,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親耻姥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艰山,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355