天天看點

Spring Cloud(一)服務的注冊與發現Eureka

Spring Cloud簡介

Spring Cloud是一系列架構的有序集合。它利用Spring Boot的開發便利性巧妙地簡化了分布式系統基礎設施的開發,如服務發現注冊、配置中心、消息總線、負載均衡、斷路器、資料監控等,都可以用Spring Boot的開發風格做到一鍵啟動和部署。Spring Cloud并沒有重複制造輪子,它隻是将目前各家公司開發的比較成熟、經得起實際考驗的服務架構組合起來,通過Spring Boot風格進行再封裝屏蔽掉了複雜的配置和實作原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分布式系統開發工具包。

以上資訊來自于百度百科:https://baike.baidu.com/item/spring cloud/20269825?fr=aladdin

簡單點說:Spring Cloud是一個微服務架構,相比Dubbo等RPC架構, Spring Cloud提供的全套的分布式系統解決方案。

說到分布式,那麼大家知道分布式應用知識的的CAP理論麼?這裡給大家拓展一下知識面。

CAP定理:

指的是在一個分布式系統,Consistency(一緻性)、Availability(可用性)、Partition Tolerance(分區容錯性),三者不可同時獲得。

  1. 一緻性( C ):在分布式系統中的所有資料備份,在同一時刻是否同樣的值(所有節點在同一時刻的資料完全一緻,越多節點,資料同步越耗時)。
  2. 可用性( A ):在叢集中一部分節點故障過後,叢集整體是否還能響應用戶端的讀寫請求(對資料更新具備高可用)。
  3. 分區容錯性( P ):實則高可用性,一個節點發生故障,并不影響其他節點。

CAP理論就是說在分布式存儲系統中,最多隻能實作上面的兩點,而由于目前的網絡硬體肯定會出現延遲丢包等問題,

是以分區容錯性是我們必須實作的,是以我們隻能在一緻性和可用性之間進行權衡。

服務的注冊與發現

  1. 服務注冊:可以了解為服務提供者(provider),在服務啟動時,向注冊中心,注冊自己的服務。
  2. 服務發現:可以了解為服務消費者(consumer),就是消費者去注冊中心上查詢注冊了哪些服務,服務有多少個執行個體,哪些是健康的,哪些是不可用的。

常見的服務注冊中心:

  1. zookeeper
  2. eureka
  3. consul
  4. etcd

這裡,我就以Eureka為例,作為服務注冊與發現的元件。

項目的搭建

建立父工程

建立一個Maven父工程,其他Module依賴該父工程。這裡部落客選擇的開發工具是IDEA。現在已經有大部分開發人員,轉戰IDEA了。Spring Cloud版本選擇Finchley.RELEASE。

首先在我們的IDEA中選擇File->New->Project,選擇Maven項目,輸入groupId和artifactId,然後一路Next到底。

Spring Cloud(一)服務的注冊與發現Eureka

接着在pom檔案中引入相關的依賴。

父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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.root.project</groupId>
    <artifactId>springcloud-project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/>
    </parent>

    <modules>
        <module>eureka-server</module>
        <module>user-service</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <!-- 單元測試 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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


</project>
           

注意,這裡的打包方式(packaging)類型是pom。

建立注冊中心(Eureka)

在父工程下,建立Module。右擊項目,選擇New->Module,選擇Spring Initializr。

Spring Cloud(一)服務的注冊與發現Eureka

和建立Maven項目一樣,填寫我們的groupId和artifactId,注意這裡打包方式,選擇jar。因為它是一個Spring Boot項目,會以jar的方式運作。

Spring Cloud(一)服務的注冊與發現Eureka

最後,選擇我們需要的元件。Cloud Discovery下的Eureka Server,然後一直Next即可。

Spring Cloud(一)服務的注冊與發現Eureka

子產品建立完成,同樣需要引入相關限制。

eureka-server的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.root.project</groupId>
    <artifactId>eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-server</name>
    <packaging>jar</packaging>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>com.root.project</groupId>
        <artifactId>springcloud-project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>


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

</project>

           

如需啟動注冊中心,需要我們進行相關的配置。

1.在啟動類中加入@EnableEurekaServer注解,表明這是一個注冊中心。

@SpringBootApplication
/**
 * @author: 清風一陣吹我心
 * 注解表明是eureka注冊中心
 * */
@EnableEurekaServer
public class EurekaServerApplication {

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

}
           

2.在application.yml檔案中進行相關配置,有些朋友應該是application.properties,這都是無關緊要的,因為部落客習慣使用.yml檔案。

#應用名稱
spring:
  application:
    name: eureka-server

#指定端口
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
    #聲明自己是個服務端,server一定程度上也是client,互為client
  client:
    #由于自己就是伺服器,不需要注冊到自己
    register-with-eureka: false
    #由于自己就是伺服器,不需要從伺服器擷取注冊資訊
    fetch-registry: false
    #服務位址
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

#自我保護機制 禁止關閉,預設是true
#  server:
#    enable-self-preservation: false
           

注冊中心的搭建就完成了,啟動浏覽器,通路 http://localhost:8761,出現如下界面。

Spring Cloud(一)服務的注冊與發現Eureka

就證明,注冊中心,搭建成功了。這是Eureka提供的一個管理服務注冊與發現的控制台。可以看到Application下顯示 No application available,這是因為,還沒有往注冊中心注冊服務。

接下來,就建立一個使用者服務(Eureka Client)。

建立使用者服務(Eureka Client)

Client向Server注冊時,它會提供一些中繼資料,例如主機和端口,URL,首頁等。

在父工程下,建立Module。右擊項目,選擇New->Module,選擇Spring Initializr。和建立注冊中心一樣,就不加圖了。然後選擇我們需要的元件。因為是Client,是以需要選擇Cloud Discovery下的Eureka Discovery,這裡需要用到應用開發,是以,還需要加入Web子產品。

Spring Cloud(一)服務的注冊與發現Eureka

限制引入之後,同樣需要配置pom.xml。

user-service的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.root.project</groupId>
    <artifactId>user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-service</name>
    <packaging>jar</packaging>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>com.root.project</groupId>
        <artifactId>springcloud-project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

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

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

配置完成,再去application.yml進行相關的配置。

#應用名稱
spring:
  application:
    name: user-service

#端口
server:
  port: 8800

#指定注冊中心
eureka:
  client:
    service-url:
      defaultzone: http://localhost:8761/eureka/
           

大家注意,spring.application.name這個配置很重要,因為以後服務之間的調用,一般都是根據這個name。

最後再在啟動類上加入用戶端的注解。

@SpringBootApplication
/**
 * @author: 清風一陣吹我心
 * @description: @EnableEurekaClient表明這個是一個eurekaclient(ps:預設可以不用加)
 */
@EnableEurekaClient
public class UserServiceApplication {

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

}
           

其他邏輯的實作,基本上就是Spring Boot中的操作,是以,想要入手Spring Cloud,還需要掌握Spring Boot相關知識。下面就寫一些僞代碼來測試一下。

建立一個使用者的實體類:

package com.root.project.userservice.pojo;

import lombok.Data;

import java.io.Serializable;

/**
 * @ClassName: User
 * @Author: 清風一陣吹我心
 * @Description: TODO
 * @Date: 2019/1/17 16:26
 * @Version 1.0
 **/
@Data
public class User implements Serializable {

    private String title;
    private String author;

    public User(){

    }
    public User(String title,String author){
          this.title = title;
          this.author = author;
    }


    //使用lombok自動生成getter、setter
}
           

在控制層寫相應的請求處理:

package com.root.project.userservice.controller;

import com.root.project.userservice.pojo.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName: UserController
 * @Author: 清風一陣吹我心
 * @Description: TODO
 * @Date: 2019/1/17 14:42
 * @Version 1.0
 **/
@RestController
@RequestMapping("/api/v1.0/")
public class UserController {

    @Value("${server.port}")
    private String port;

    @GetMapping(value = "user")
    public String helloMethod() {
        User user = new User("Spring Cloud之服務注冊與發現", "清風一陣吹我心");
        return "這篇文章的标題是:" + user.getTitle() + ",作者是:" + user.getAuthor() + ",端口号是:" + port;
    }
}

           

啟動使用者服務,看一下Eureka的界面

Spring Cloud(一)服務的注冊與發現Eureka

可以看到箭頭的标注處,就是使用者服務,顯示的正是application.yml中的應用名稱,還有相關的端口号:8800。

當然還有人會疑惑,上面還有一段紅色的文字,其實這是一個警告,意思是說:服務過于少,而且上線率比較低。這是Eureka的一種自我保護模式,可以關閉這種檢查。

ps:自我保護模式禁止關閉,預設是開啟狀态(true)

接下來,就通路 http://localhost:8800/api/v1.0/user ,看用戶端傳回的結果吧。

Spring Cloud(一)服務的注冊與發現Eureka

文章就要接近尾聲了。如有不明白的朋友,可以在下方進行留言。當然,如果部落客有什麼地方出了錯,也歡迎大家指出。

願你學會在孤獨中,與自己交流,聽自己說話,進而學會深刻。

繼續閱讀