1. 程式人生 > 實用技巧 >2、SpringCloud快速搭建

2、SpringCloud快速搭建

SpringCloud構建微服務是基於SpringBoot開發的。
建立服務提供者的訪問方法,消費者如何訪問提供者,SpringCloud是基於rest的訪問,他們之間是通過json進行互動

建立服務提供者

依賴

<!--springboot開發web專案的依賴-->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

controller

@RestController
public class HelloController {
    @RequestMapping("/service/hello")
    public String hello(){
//        業務處理(省略)
        return "hello spring clound";
    }
}

建立服務消費者

建立一個新的springboot專案
開發消費者方法,去消費服務提供者提供的服務,這個消費者方法也是一個Controller

@RestController
public class WebController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/web/hello")
    public String hello(){
//        邏輯判斷(省略)

//        呼叫SpringCloud服務提供者提供的服務(通過RestTemplate這個類遠端呼叫服務)
        return restTemplate.getForEntity("http://localhost:8080/service/hello", String.class).getBody();
    }

配置RestTemplate類

//配置檔案
@Configuration
public class BeanConfig {
    /**
     * @Bean 等價於 <bean id="restTemplate" class="xxx.xxx.RestTemplate"/>
     *
     * @return
     */
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

埠配置避免兩個專案的埠號衝突

server.port=8081

訪問
通過http://localhost:8081/web/hello訪問消費者方法,消費者方法會呼叫服務提供者提供的方法

Spring Cloud結構的遠端呼叫模式

服務提供者的服務需要註冊到服務中心上,消費者通過註冊中心獲取提供者註冊的服務,然後進行呼叫

走進服務註冊中心Eureka

  微服務架構中,服務註冊與發現是核心元件之一,手動指定每個服務是很低效的,SpringCloud提供多種服務註冊與發現的實現方式,如:Eureka、Consul、Zookeeper。
  SpringCloud支援最後的是Eureka,然後Consul、Zookeeper

服務註冊

  將服務所在主機、埠、版本號、通訊協議等資訊登記到註冊中心上。

什麼是服務發現?

  服務消費者向註冊中心請求已經登記的服務列表,然後得到某個服務的主機、埠、版本號、通訊協議等資訊、從而實現對具體服務的呼叫。

Eureka

  • 一個服務治理元件,主要包括服務註冊與發現,用來搭建服務註冊中心
  • Eureka 是一個基於 REST 的服務,用來定位服務,進行中間層伺服器的負載均衡和故障轉移
  • Eureka 由 Netflix 提供,SpringCloud進行二次封裝
  • C/S 設計架構:
    • Eureka Server(服務端)是服務中心;維護人員可以通過Eureka Server 來監控系統中的各個微服務是否正常執行
    • Eureka Client(客戶端)是一個java客戶端,用於簡化與伺服器的互動,負載均衡,服務的故障切換等;
    • 通過客戶連線到服務端,並維持心跳連線;

Eureka 與 Zookeeper 的比較

CAP理論 一個分散式系統不可能同時滿足cap (C:資料一致性,A:服務可用性,P:分割槽容錯性)

  • 微服務本身就分為多個節點,當一個節點出現故障時,其他節點不會隨之癱瘓,這就是容錯性是分散式系統必須保證的;
  • 服務可用性 和 資料一致性 兩者無法並存只能進行取捨,Zookeeper保證的是CP,而Eureka則是AP

Zookeeper

例如:一個Zookeeper叢集,有三個節點,其中master因網路故障或與其他節點失去聯絡,那麼Zookeeper就會在剩下的節點中選舉出一個節點作為master,但是選舉的過程需要時間,而這段時間整個Zookeeper叢集是不可用的,也就是註冊服務癱瘓,Provider無法向註冊中心註冊服務,這時就失去了C(服務可用性)。Zoo因網路問題導致Zookeeper失去master節點是大概率時間,雖然能回覆,但是選舉時間內導致服務註冊長期不可用是難以容忍的。

Eureka

Eureka叢集與Zookeeper不同,節點之間沒有主從關係,如果某個節點掛了,剩餘節點依然能提供註冊和查詢服務。如果Eureka Client 向 Eureka Server 註冊時發現連線失敗,會自動切換到其他正常的節點。但是無法保證查到的資訊是最新的(不保證強一致性)

例如:
Eureka Client 向 Eureka Server 註冊服務,註冊完後,由於某些原因客戶端停掉了該服務,這是的服務端有可能沒有進行更新,導致消費者(consumer)去註冊中心(Eureka Server)中獲取該服務的註冊資訊是有的,但是呼叫服務的時候卻無法呼叫的問題。

搭建並配置Eureka服務註冊中心

Spring Cloud 中的Eureka 服務註冊中心實際上也是一個Spring Boot工程,通過引入相關依賴和註解配置,讓Spring Boot構建的微服務應用與Eureka進行整合整合。

步驟:
1.建立一個SpringBoot專案,並且新增SpringBoot的相關依賴;
(省略)
2.新增Eureka的依賴

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 新增Eureka依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <!--新增依賴管理-->
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <!--還可以配置Repository-->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

3.在Spring Boot 的入口類上新增一個@EnableEurekaServer註解,用於開啟Eureka註冊中心服務端

@SpringBootApplication
@EnableEurekaServer //開啟Eureka註冊中心服務端
public class Application {

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

4.在application.properties或yaml檔案中配置Eureka服務註冊中心資訊

server.port=8761

#配置該服務註冊中心的hostname(填ip)
eureka.instance.hostname=localhost
#由於我們目前建立的應用是一個服務註冊中心,而不是普通的應用。
# 預設情況下,這個應用會向註冊中心(也是它自己)註冊它自己,設定為false表示禁止這種自己向自己註冊的預設行為
eureka.client.register-with-eureka=false
#表示不去檢索其他的服務,因為服務註冊中心本身的職責就是維護服務例項,它不需要檢索其他服務
eureka.client.fetch-registry=false
#指定服務註冊中心的位置
eureka.client.service-url.defaultZone=http;//${eureka.instance.hostname}:${server.port}/eureka/

啟動與測試Eureka服務註冊中心

1.完成上面的專案搭建後,啟動springboot程式,執行main方法;
2.啟動成功之後,通過在瀏覽器位址列訪問我們的註冊中心

訪問介面如下:

注意

啟動失敗的話,肯能是SpringBoot與SpringCloud之間的相容問題
可以通過SpringCloud官網進行訪問點選跳轉SpringCloud,點檢Deference Doc,檢視相容版本

向Eureka服務註冊中心註冊服務

將服務提供者註冊到Eureka註冊中心

步驟
1.該服務提供者Provider新增Eureka的依賴
服務提供者想註冊中心註冊服務,需要連線eureka,所以需要eureka客戶端的支援

<!-- 新增Eureka客戶端依賴>
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <!-- 新增SpringCloud依賴管理-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.啟用Eureka中的EnableEurekaClient功能:
在SpringBoot的啟動類上新增@EnableEurekaClient註解來表示自己是一個Eureka Client,使得服務可用連線Eureka註冊中心;

3.配置服務名稱和註冊中心地址

#配置服務的名稱,通常與專案名一致(通過名稱訪問微服務)
server.servlet.context-path: /01springcloud-service-provider
#eureka的訪問地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

4.啟動服務提供者SpringBoot程式的main方法執行

5.訪問Eureka服務中心
這是就有一個服務註冊上了

從Eureka服務註冊中心發現和消費服務

  • 服務的發現由Eureka客戶端實現
  • 服務的消費由Ribbon實現
  • 服務的呼叫需要Eureka Client 和 Ribbon共同完成

Eureka Client
Eureka 客戶端時一個java客戶端,用來連線Eureka服務端,與服務端進行互動,負載均衡,服務的故障切換等

Ribbon

  • Ribbon是基於Http 和 TCP 的客戶端負載均衡器。
  • 使用Ribbon對服務進行訪問時,它會擴充套件Eureka客戶端的服務發現功能,實現從Eureka註冊中心中獲取服務端列表,並通過Eureka客戶端來確定服務端是否已經啟動。
  • Ribbon在Eureka客戶端服務發現的基礎上,實現了對服務例項的選擇策略,從而實現對服務的負載均衡消費。

服務消費者呼叫服務提供者

1.消費者專案新增Eureka Client的依賴
consumer從註冊中心獲取服務,需要連線Eureka,所以需要Eureka支援

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

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

2.啟用Eureka中的EnableEurekaClient功能
在啟動類上新增@EnableEurekaClient註解

3.配置服務的名稱和註冊中心的地址

#配置服務的名稱,通常與專案名一致(通過名稱訪問微服務)
server.servlet.context-path: /02springcloud-service-consumer
#eureka的訪問地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

4.呼叫服務提供者時使用ribbon來呼叫

//配置檔案
@Configuration
public class BeanConfig {
    /**
     * @Bean 等價於 <bean id="restTemplate" class="xxx.xxx.RestTemplate"/>
     *
     * @return
     */
    @LoadBalanced //ribbon支援
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

加入ribbon的支援,那麼呼叫的時候,使用服務名稱來訪問即可

@RestController
public class WebController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/web/hello")
    public String hello(){

//        Eureka + Ribbon的呼叫服務的方式(這種方式不再需要ip地址和埠號了)
        return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class).getBody();

    }
}

5.啟動消費者程式

6.訪問消費者
檢驗是否能正常呼叫