20200523 尚硅谷2020最新版SpringCloud【筆記】1


尚硅谷2020最新版SpringCloud【筆記】1

2.從2.2.x和H版開始說起

技術 版本
Spring Cloud Hoxton.SR1
Spring Boot 2.2.2.RELEASE
Spring Cloud Alibaba 2.1.0.RELEASE

4.微服務架構編碼構建

配置熱部署Devtools

  1. 改 POM,添加依賴

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    
  2. 在父工程中添加 Maven 插件

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.2.2.RELEASE</version>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
  3. IDEA 設置

    1. File | Settings | Build, Execution, Deployment | Compiler 中,全部勾選
    2. 快捷鍵 Ctrl+Shift+Alt+/ -> 1.Registry... -> 勾選 compiler.automake.allow.when.app.running 和 actionSystem.assertFocusAccessFromEdt
  4. 重啟 IDEA

開啟 Run Dashboard

Services 視圖中添加 Run Configuration Type,選擇 Spring Boot

遵循原則

約定 > 配置 > 編碼

創建父工程 Project

創建步驟:

  1. New Project
  2. 聚合總工程名字
  3. Maven選版本
  4. 工程名字
  5. 字符編碼
  6. 注解生效激活
  7. java編譯版本選8
  8. File Type過濾(可選)

父工程 POM

<?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.atguigu.springcloud</groupId>
    <artifactId>mycloud2020</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>cloud-provider-payment8001</module>
		...
    </modules>

    <!-- 統一管理jar包版本 -->
    <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>
        <mysql.version>5.1.47</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
    </properties>

    <!-- 子模塊繼承之后,提供作用:鎖定版本+子modlue不用寫groupId和version  -->
    <dependencyManagement>
        <dependencies>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud alibaba 2.1.0.RELEASE-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</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>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.2.2.RELEASE</version>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  • 注意其中的 packaging 標簽值為 pom

創建 cloud-provider-payment8001 微服務提供者支付Module模塊,即生產者

創建步驟:

  1. 建 module,名為 cloud-provider-payment8001
  2. 改 POM
  3. 寫 YML
  4. 主啟動類
  5. 業務類

創建 cloud-consumer-order80 微服務消費者訂單Module模塊,即

工程重構

創建 cloud-api-commons Module模塊

  1. 將重復代碼放入此模塊

  2. 打包此模塊,maven命令clean install

  3. 在其他模塊中刪除重復代碼,添加此模塊依賴

    <dependency>
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    

5.Eureka 服務注冊與發現

定位

Eureka 類比物業公司,服務類比入駐企業

單機 Eureka 服務中心構建

  1. 建Module,cloud-eureka-server7001

  2. 改POM

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
  3. 寫 YML

    eureka:
      instance:
        hostname: localhost   # eureka服務端的實例名字
      client:
        register-with-eureka: false   # 表示不向注冊中心注冊自己
        fetch-registry: false   #表示自己就是注冊中心,職責是維護服務實例,並不需要去檢索服務
        # 設置與eureka server交互的地址查詢服務和注冊服務都需要依賴這個地址
        service-url:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    
  4. 主啟動,添加 @EnableEurekaServer

業務模塊配置 Eureka 客戶端

  1. 改 POM

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

    eureka:
      client:
        # 表示是否將自己注冊進EurekaServer默認為true。
        register-with-eureka: true
        # 是否從EurekaServer抓取已有的注冊信息,默認為true。單節點無所謂,集群必須設置為true才能配合ribbon使用負載均衡
        fetchRegistry: true
        service-url:
          defaultZone: http://localhost:7001/eureka
          # 集群版
          # defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
    
  3. 主啟動類,添加注解 @EnableEurekaClient

集群 Eureka 服務中心構建

  1. 新建 cloud-eureka-server7002 模塊

  2. 修改 hosts 文件

    hosts 文件路徑為 C:\Windows\System32\drivers\etc\hosts

    127.0.0.1       eureka7001.com
    127.0.0.1       eureka7002.com
    
  3. 改 YML

    eureka:
      instance:
        hostname: eureka7001.com		# eureka服務端的實例名字
      client:
        register-with-eureka: false   # 表示不向注冊中心注冊自己
        fetch-registry: false   #表示自己就是注冊中心,職責是維護服務實例,並不需要去檢索服務
        service-url:
    #    7001 配置 7002,7002 配置7001
         defaultZone: http://eureka7002.com:7002/eureka/
    
  4. 業務模塊改 YML

    defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
    

生產者模塊配置集群

  1. 復制生產者模塊,cloud-provider-payment8002

  2. 注意 YML 配置中,應用名稱保持一致

    spring:
      application:
        name: cloud-payment-service
    

消費者模塊配置負載均衡

  1. 修改配置類

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
    
  2. 修改 Controller

    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
    
    return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
    
  3. 測試負載均衡

actuator微服務信息完善

  1. 改 POM ,添加依賴

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
  2. 主機名稱:服務名稱修改

    eureka:
      instance:
      	# 服務實例 ID
        instance-id: payment8001
    
  3. 訪問信息有ip信息提示

    eureka:
      instance:
      	# 訪問路徑可以顯示IP地址
        prefer-ip-address: true
    

服務發現 Discovery

對於注冊進eureka里面的微服務,可以通過服務發現來獲得該服務的信息

  1. 主啟動類,添加注解 @EnableDiscoveryClient

  2. 業務代碼

    @Autowired
    private DiscoveryClient discoveryClient;
    
    @GetMapping("/discovery")
    public Object discovery() {
        List<String> services = discoveryClient.getServices();
        for (String service : services) {
            log.info("service *** {}" + service);
    
            List<ServiceInstance> instances = discoveryClient.getInstances(service);
            for (ServiceInstance instance : instances) {
                log.error("instance *** {}", instance);
            }
        }
    
    
        return discoveryClient;
    }
    

Eureka自我保護

某時刻某一個微服務不可用了,Eureka不會立刻清理,依舊會對該微服務的信息進行保存

屬於CAP里面的AP分支

禁止自我保護

  1. Eureka 服務中心配置

    eureka:  
      server:
        enable-self-preservation: false   # 關閉自我保護機制,保證不可用服務被及時踢除
        eviction-interval-timer-in-ms: 2000
    
  2. Eureka 客戶端配置

    eureka:
      instance:
        # Eureka客戶端向服務端發送心跳的時間間隔,單位為秒(默認是30秒)
        lease-renewal-interval-in-seconds: 1  
        #  Eureka服務端在收到最后一次心跳后等待時間上限,單位為秒(默認是90秒),超時將剔除服務
        lease-expiration-duration-in-seconds: 2   
    

6.Zookeeper服務注冊與發現

結論

服務在 Zookeeper 中創建的是臨時節點,一旦服務停止,一段時間后,節點被 Zookeeper 刪除。

SpringCloud整合Zookeeper代替Eureka

注冊中心Zookeeper

  1. 啟動 Zookeeper

    1. 在 Windows 服務中開啟 VMware DHCP Service 和 VMware NAT Service

    2. 關閉虛擬機中的防火牆

      systemctl stop firewalld.service
      
    3. 啟動 Zookeeper

      # 啟動服務
      ./zkServer.sh start
      # 驗證狀態
      ./zkServer.sh status
      # 啟動客戶端
      ./zkCli.sh
      

服務提供者

  1. 創建生產者服務

    1. 建 Module,cloud-provider-payment8004

    2. 改 POM

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

      如果啟動時報錯,可能是依賴的 ZooKeeper 的 jar 包與使用的 ZooKeeper 版本不一致,可以通過調整依賴解決:

      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
          <!--先排除自帶的zookeeper3.5.3-->
          <exclusions>
              <exclusion>
                  <groupId>org.apache.zookeeper</groupId>
                  <artifactId>zookeeper</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
      <!--添加zookeeper3.4.9版本-->
      <dependency>
          <groupId>org.apache.zookeeper</groupId>
          <artifactId>zookeeper</artifactId>
          <version>3.4.9</version>
      </dependency>
      
    3. 改 YML

      #8004表示注冊到zookeeper服務器的支付服務提供者端口號
      server:
        port: 8004
      
      
      #服務別名----注冊zookeeper到注冊中心名稱
      spring:
        application:
          name: cloud-provider-payment
        cloud:
          zookeeper:
            connect-string: 192.168.181.128:2181
      
    4. 主啟動類,添加注解 @EnableDiscoveryClient

  2. 驗證

    1. 啟動無報錯
    2. Zookeeper 客戶端中查看,會產生新的節點 servicesservices 下有 cloud-provider-payment 節點

服務消費者

  1. 建 Module ,cloud-consumerzk-order80
  2. 改 POM,同上
  3. 改 YML,同上
  4. 主啟動類,同上
  5. 測試
    1. Zookeeper 客戶端中查看,services 節點下有新的節點 cloud-consumer-order

7.Consul服務注冊與發現

Consul簡介

官網地址

功能

  • 服務發現
    提供HTTP和DNS兩種發現方式
  • 健康監測
    支持多種協議,HTTP、TCP、Docker、Shell腳本定制化
  • KV存儲
    key , Value的存儲方式
  • 多數據中心
    Consul支持多數據中心
  • 可視化Web界面

安裝並運行Consul

  1. 下載 Windows 64位程序;

  2. 查看版本信息

    .\consul.exe --version
    
  3. 使用開發模式啟動

    consul agent -dev
    
  4. 訪問Consul的首頁

    http;//localhost:8500
    

服務提供者

  1. 建 Module,cloud-providerconsul-payment8006

  2. 改 POM

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    
  3. 改 YML

    ###服務端口號
    server:
      port: 8006
    
    spring:
      application:
        name: consul-provider-payment
    ####consul注冊中心地址
      cloud:
        consul:
          host: localhost
          port: 8500
          discovery:
            #hostname: 127.0.0.1
            service-name: ${spring.application.name}
    
  4. 主啟動類,添加注解 @EnableDiscoveryClient

  5. 測試

    1. Consul 的圖形化界面中出現新的 Service,consul-provider-payment

服務消費者

  1. 建 Module ,cloud-consumerconsul-order80
  2. 改 POM,同上
  3. 改 YML,同上
  4. 主啟動類,同上
  5. 測試
    1. Consul 的圖形化界面中出現新的 Service,cloud-consumer-order

三個注冊中心異同點

組件名 語言 CAP 健康檢查 對外暴露接口 Spring Cloud 集成
Eureka Java AP 可配支持 HTTP 已集成
Consul Go CP 支持 HTTP/DNS 已集成
ZooKeeper Java CP 支持 客戶端 已集成

8.Ribbon負載均衡服務調用

概述

是什么

客戶端 負載均衡 的工具

主要功能是提供客戶端的軟件負載均衡算法和服務調用

Ribbon目前也進入維護模式,未來可以使用 Spring Cloud LoadBalancer 替代

能干嗎

LB(負載均衡)
  • 集中式LB

    即在消費方和服務方之間使用獨立的 LB 設施

    例如 Nginx,Nginx 是服務器負載均衡,客戶端所有請求都會交給 Nginx ,然后由 Nginx 實現轉發請求。即負載均衡是由服務端實現的。

  • 進程內LB

    將 LB 邏輯集成到消費方,消費方從服務注冊中心獲知有哪些地址可用,然后從這些地址中選擇一個合適的服務器。

    Ribbon 本地負載均衡,在調用微服務接口時,會在注冊中心上獲取注冊信息服務列表之后緩存到 JVM 本地,從而在本地實現 RPC 遠程服務調用技術。

    負載均衡+RestTemplate調用

Ribbon負載均衡演示

總結:Ribbon其實就是一個軟負載均衡的客戶端組件,他可以和其他所需請求的客戶端結合使用,和eureka結合只是其中的一個實例。

POM

spring-cloud-starter-netflix-eureka-client 依賴中自帶了 spring-cloud-starter-netflix-ribbon,所以無需手動引入

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

二說RestTemplate的使用

  • getForObject:返回對象

    CommonResult commonResult = restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
    
  • getForEntity:返回 ResponseEntity

    ResponseEntity<CommonResult> entity = restTemplate.getForEntity(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    

Ribbon核心組件IRule

com.netflix.loadbalancer.IRule

IRule:根據特定算法從服務列表中選取一個要訪問的服務

  • com.netflix.loadbalancer.RoundRobinRule
    輪詢
  • com.netflix.loadbalancer.RandomRule
    隨機
  • com.netflix.loadbalancer.RetryRule
    先按照RoundRobinRule的策略獲取服務,如果獲取服務失敗則在指定時間內會進行重試
  • WeightedResponseTimeRule
    對RoundRobinRule的擴展,響應速度越快的實例選擇權重越大,越容易被選擇
  • BestAvailableRule
    會先過濾掉由於多次訪問故障而處於斷路器跳閘狀態的服務,然后選擇一個並發量最小的服務
  • AvailabilityFilteringRule
    先過濾掉故障實例,再選擇並發較小的實例
  • ZoneAvoidanceRule
    默認規則,復合判斷server所在區域的性能和server的可用性選擇服務器

替換負載均衡算法

注意:算法的配置類不能位於包掃描范圍內,需要獨立出來。例如,啟動類在包 com.atguigu.springcloud 下,算法的配置類就不能位於此包及其子包下,可以位於包 com.atguigu.myrule 下。

替換步驟:

  1. 新建配置類,com.atguigu.myrule.MySelfRule

    @Configuration
    public class MySelfRule {
        @Bean
        public IRule myRule() {
            return new RandomRule();	//定義為隨機
        }
    }
    
  2. 主啟動類,配置

    @RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration= MySelfRule.class)
    

9.OpenFeign服務接口調用

概述

Feign是一個聲明式的web服務客戶端,讓編寫web服務客戶端變得非常容易,只需創建一個接口並在接口上添加注解即可

OpenFeign 依賴 Ribbon,自帶負載均衡功能

Github 地址

服務消費者使用 OpenFeign 步驟

  1. 建 Module,cloud-consumer-feign-order80

  2. 改 POM

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

  4. 主啟動類,添加注解 @EnableFeignClients

  5. 業務類,Feign 接口類

    @Component
    @FeignClient(value = "CLOUD-PAYMENT-SERVICE")
    public interface PaymentFeignService {
        
        @GetMapping(value = "/payment/get/{id}")
        public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
    
    }
    
  6. 調用 Feign 接口類

    @Resource
    private PaymentFeignService paymentFeignService;
    
    @GetMapping(value = "/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
        return paymentFeignService.getPaymentById(id);
    }
    

OpenFeign超時控制

改 YML:

#設置feign客戶端超時時間(OpenFeign默認支持ribbon)
ribbon:
  #指的是建立連接所用的時間,適用於網絡狀況正常的情況下,兩端連接所用的時間,默認為1s
  ReadTimeout: 5000
  #指的是建立連接后從服務器讀取到可用資源所用的時間,默認為1s
  ConnectTimeout: 5000

OpenFeign日志打印功能

日志級別

級別 描述
NONE 默認,不顯示任何日志
BASIC 僅記錄請求方法、URL、響應狀態碼及執行時間
HEADERS 除了 BASIC 中定義的信息之外,還有請求和相應的頭信息
FULL 除了 HEADERS 中定義的信息之外,還有請求和響應的正文及元數據

配置步驟

  1. 新建配置類

    @Configuration
    public class FeignConfig {
        @Bean
        Logger.Level feignLoggerLevel() {
            return Logger.Level.FULL;
        }
    }
    
  2. 改 YML

    logging:
      level:
        # feign日志以什么級別監控哪個接口
        com.atguigu.springcloud.service.PaymentFeignService: debug
    

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM