SpringCloud(二)Eureka服務註冊與發現

寫在前面:

  • 你好,歡迎你的閱讀!
  • 我熱愛技術,熱愛分享,熱愛生活, 我始終相信:技術是開源的,知識是共享的!
  • 博客裏面的內容大部分均爲原創,是自己日常的學習記錄和總結,便於自己在後面的時間裏回顧,當然也是希望可以分享自己的知識。目前的內容幾乎是基礎知識和技術入門,如果你覺得還可以的話不妨關注一下,我們共同進步!
  • 除了分享博客之外,也喜歡看書,寫一點日常雜文和心情分享,如果你感興趣,也可以關注關注!
  • 微信公衆號:傲驕鹿先生


說明:

1、專欄涉及到的源碼已經同步至 https://github.com/SetAlone/springcloud2020(持續更新)

2、springcloud系列博文內容爲學習《尚硅谷2020最新版SpringCloud(H版&alibaba)框架開發教程》的記錄,此係列課程是目前看來個人覺得非常不錯的資源,在此可以與大家進行分享。

3、個人收集到了課程源碼和所需的腦圖、筆記等資源,如需要私信我即可。查找資源不易,希望可以給個點贊和關注。
 

一、基礎知識

1、什麼是服務治理

Spring Cloud封裝了Netflix公司開發的Eureka模塊來實現服務治理。

在傳統的RPC遠程調用框架中,管理每個服務與服務之間依賴關係比較複雜,所以需要使用 服務治理,管理服務與服務之間的依賴關係,可以實現服務調用、負載均衡、容錯等,實現服務發現與註冊。

2、什麼是服務註冊

Eureka採用了CS的設計架構,Eureka Server作爲服務註冊功能的服務器,它是服務註冊中心。而系統中的其他服務,使用Eureka的額客戶端連接到Eureka Server並維持心跳連接。這樣系統的維護人員就可以通過Eureka Server來監控系統中各個微服務是否正常運行。

在服務註冊和發現中,有一個註冊中心。當服務器啓動的時候,會把當前自己服務器的信息以別名方式註冊到註冊中心上。另一方(消費服務提供者)以該別名的方式去註冊中心上獲取到實際的服務通訊地址,然後在實現本地RPC遠程調用框架核心設計思想:在於註冊中心,因爲使用註冊中心管理每個服務與服務之間的一個依賴關係(服務治理理念)。在任何的RPC遠程框架中,都會有一個註冊中心(存放服務地址相關信息(接口地址))。

3、Eureka的兩個組件

二、單機Eureka構建

1、IDEA生成EurekaServer端服務註冊中心   

1)建moudle

在父工程上右鍵,new——>moudle,新建一個新的maven項目,不需要選擇嚮導。命令爲cloud-eureka-server7001。

2)改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">
    <parent>
        <artifactId>springcloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server7001</artifactId>


    <dependencies>
        <!--eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- 引入自己定義的api通用包,可以使用Payment支付Entity -->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--boot web actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--一般通用配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

</project>

3)寫yml

在resources文件夾下創建application.yml文件

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com #eureka服務端的實例名稱
  client:
    register-with-eureka: false     #false表示不向註冊中心註冊自己。
    fetch-registry: false     #false表示自己端就是註冊中心,我的職責就是維護服務實例,並不需要去檢索服務
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4)主啓動類

package com.atguigu.springcloud;

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

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

5)測試

因爲是服務註冊中心,所以不需要編寫業務類。進行測試:

在瀏覽器中輸入http://localhost:7001/進行測試,如下爲測試結果圖:

2、EurekaClient端cloud-provider-payment8001 將註冊進EurekaServer成爲服務提供者provider

1)選定8001模塊

2)改pom,在8001模塊的pom文件中添加依賴

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

3)寫yml

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 當前數據源操作類型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驅動包
    url: jdbc:mysql://localhost:3306/db2020?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root

eureka:
  client:
    #表示是否將自己註冊進EurekaServer默認爲true。
    register-with-eureka: true
    #是否從EurekaServer抓取已有的註冊信息,默認爲true。單節點無所謂,集羣必須設置爲true才能配合ribbon使用負載均衡
    fetchRegistry: true
    service-url:
      #單機版
      defaultZone: http://localhost:7001/eureka
      
mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity別名類所在包


4)主啓動

在主啓動類PaymentMain8001中添加@EnableEurekaClient註解

package com.atguigu.springcloud;

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

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

5)測試

啓動Eureka Server,然後進行測試。http:localhost:7001

3、EurekaClient端cloud-consumer-order80 將註冊進EurekaServer成爲服務消費者consumer

1)選定cloud-consumer-order80模塊

2)改pom,在80模塊的pom文件中添加依賴

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

3)寫yml

server:
  port: 80

spring:
  application:
    name: cloud-payment-service

eureka:
  client:
    #表示是否將自己註冊進EurekaServer默認爲true。
    register-with-eureka: true
    #是否從EurekaServer抓取已有的註冊信息,默認爲true。單節點無所謂,集羣必須設置爲true才能配合ribbon使用負載均衡
    fetchRegistry: true
    service-url:
      #單機版
      defaultZone: http://localhost:7001/eureka
      

4)主啓動

在主啓動類OderMain8001中添加@EnableEurekaClient註解

package com.atguigu.springcloud;

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

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

5)測試

三、集羣Eureka構建

1、Eureka集羣原理說明

服務註冊:將服務信息註冊到註冊中心

服務發現:從註冊中心上獲取到服務信息

其實質就是:key-value形式的。Key:服務的名字 value:服務調用地址

執行步驟:

1、先啓動eureka註冊中心

2、啓動服務提供者(我們這裏的服務提供者就是payment支付服務)

3、服務提供者在啓動後會把自身的信息(如服務地址,以別名方式註冊到)註冊到eureka中

4、消費者(我們這裏是order服務)在需要調用接口的時候,使用服務別名去註冊中心獲取到實際的RPC遠程調用地址

5、消費者獲取到調用地址後,底層實際是利用HttpClient技術實現遠程調用的

6、消費者獲得服務地址後會緩存在本地的JVM內存中,默認每隔30秒更新移除服務調用地址

如果我們的註冊中心只有一個,在發生故障的情況下,就會導致整個的服務不可用,我們可以通過搭建Eureka註冊中心集羣的方式,實現負載均衡和故障容錯。

原理說明:

前面我們實現了單機Eureka搭建,既然是集羣搭建,就意味着有多個。比如我們現在單臺的eureka端口是7001,假設還有一臺服務是7002.那麼7001的註冊地址應該是7002,7002的註冊地址是7001.這樣就相互註冊了。7001會每30s給7002同步一次心跳,同理7002也會的。所以就相互守望了。因此我們可以用一句話進行概括:互相註冊,互相守望

2、集羣Eureka構建步驟

1)建moudle

按照上面構建cloud-eureka-server7001的構建步驟,進行cloud-eureka-server7002的構建

2)改pom

複製7001moudle的pom文件即可

3)修改映射配置文件

當我們有兩個應用進行相互註冊相互守望時,eureka服務端的實例名稱不能重複,因此需要修改映射配置文件,找到C:\Windows\System32\drivers\etc路徑下的hosts文件,對其進行修改,增加兩個虛擬的域名:

修改完成後刷新host文件,打開cmd命令窗口,進行如下的操作:

出現上面的界面則說明我們的映射配置文件已修改成功了。

4)寫yml(依次修改7001和7002的yml文件)

7001:

server:
  port: 7001
spring:
  application:
    name: cloud-eureka-service
eureka:
  instance:
    # eureka服務端的實例名稱
    hostname: eureka7001.com
  client:
    # false表示不向註冊中心註冊自己
    register-with-eureka: false
    # false表示自己端就是註冊中心,我的職責就是維護服務實例,並不需要檢索服務
    fetch-registry: false
    service-url:
      # 設置與Eureka Server交互的地址查詢服務和註冊服務都需要依賴這個地址
      defaultZone: http://eureka7002.com:7002/eureka/
 

7002:

server:
  port: 7002
spring:
  application:
    name: cloud-eureka-service2
eureka:
  instance:
    hostname:  eureka7002.com
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/
 

3、將支付服務8001微服務發佈到上面2臺Eureka集羣配置中

修改8001的yml文件,將原來的單機版修改爲集羣版即可。

#單機版
# defaultZone: http://localhost:7001/eureka
# 集羣版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

4、將訂單服務80微服務發佈到上面2臺Eureka集羣配置中

修改80的yml文件,將原來的單機版修改爲集羣版即可。

#單機版
# defaultZone: http://localhost:7001/eureka
# 集羣版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

5、支付服務提供者8001集羣環境搭建

1)參考cloud-provider-payment8001,新建cloud-provider-payment8002

2)複製pom文件

3)複製yml文件,修改裏面的端口號

4)複製主啓動類

5)複製業務類

分別修改8001和8002的controller文件,

6)測試

 

我們可以看到CLOUD-PAYMENT-SERVICE是有兩臺機器。分別是8001和8002

再來分別訪問8001和8002的服務:

我們可以看到把對應服務的端口號返回到頁面上了。

再使用消費者order80測試:

 

 

 

我們發現無論我們怎麼刷新訪問的端口都是8001。但是,我們payment確實啓動了兩個項目8001和8002啊。那麼爲什麼呢?

 

查看OderController,我們可以看到訪問服務的連接是寫死的,既然後面啓動了兩個服務,我想要既可以訪問8001的端口也要訪問8002的端口,那麼怎麼做呢?

6、負載均衡

如果我們修改成服務名稱呢?那麼服務名稱是什麼?服務名稱就是我們在eureka集羣註冊的application列表下的名稱。

 

那麼我們直接把CLOUD-PAYMENT-SERVICE這個服務名字複製到PAYMENT_URL中可以嗎?

 

重啓完成之後,我們重新訪問:

 

重新訪問的時候,我們看到提示信息是說:java.net.UnknownHostException: CLOUD-PAYMENT-SERVICE。沒有找到這個host異常。

爲什麼呢?我們知道,這個服務是註冊到eureka的服務的別名,而不是真實存在的。如果要想訪問到,這裏就需要使用到負載均衡了。

怎麼修改呢?需要修改RestTemplate的配置類中添加@LoadBalanced註解賦予RestTemplate負載均衡的能力。

修改如下:

在order80項目中,ApplicationContextConfig類裏面getRestTemplate方法上面添加@LoadBalance註解即可。如下圖:

 

修改完成之後,再次訪問頁面,然後刷新頁面,我們可以看到端口是8001和8002來回切換的。

7、測試

四、actuator微服務信息完善

1、主機名稱:服務名稱修改

主機名稱:服務名稱修改
當前問題:服務註冊含有主機名稱,要想按照規範的要求,只暴露服務名,不要出現主機名。

在這裏插入圖片描述
分別找到8001和8002的yml文件,添加配置即可:

在這裏插入圖片描述


2、訪問信息有ip信息提示

我們可以通過如下的配置,將我們微服務的ip地址進行顯示,方便我們進行調試和排錯。分別在8001和8002的yml文件中進行添加:

修改完成後效果如下:

在這裏插入圖片描述

五、服務發現Discovery

對於註冊eureka裏面的微服務,可以通過服務發現來獲得該服務的信息,具體的步驟如下:

修改cloud-provider-payment8001的Controller

在8001的主啓動上添加註解@EnableDiscoveryClient

六、eureka自我保護

我們暫時將7001和8001模塊還原到eureka的單機模式用以eureka自我保護的測試:

在7001的yml文件中進行配置:

在8001的yml文件中進行配置:

在啓動7001和8001後,停止8001來模仿故障,就會出現如下的結果:其服務

其服務馬上就會被刪除了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章