一個C#開發者學習SpringCloud搭建微服務的心路歷程

前言

Spring Cloud很火,很多文章都有介紹如何使用,但對於我這種初學者,我需要從創建項目開始學起,所以這些文章對於我的啓蒙,幫助不大,所以只好自己寫一篇文章,用於備忘。

SpringCloud是封裝了Netflix公司開發的Eureka模塊來實現服務註冊和發現。下圖爲Spring Cloud Eureka的本版列表:

下圖爲Spring Cloud 微服務的各個實現的總覽。

創建父項目

首先,我們打開IEDA創建項目,然後選擇Maven選項,然後點擊下一步,如下圖:

創建完成後,是一個空的Java父項目,如下圖:

創建服務查詢中心子項目——EurekaServer

EurekaServer是用於服務查詢的,C#開發者可能更熟悉consul,雖然用法不一樣,但實現的效果是一樣的。

現在我們創建一個服務查詢中心項目,在項目上右鍵-->new-->Module-->Spring Initializr-->next,選擇和父類項目同一版本的jdk,如下圖:

然後選擇SpringCloudDiscovery—EurekaServer,如下圖:

創建完成如下圖所示:

打開新建的項目的入口文件——EurekaserverApplication,爲EurekaserverApplication類增加註解@EnableEurekaServer,這個註解會將當前類標記爲Eureka Server。

然後修改application.properties爲application.yml,編寫代碼如下:

# 配置啓動端口
server:
  port: 5180
# 配置eureka
eureka:
  instance:
    hostname: localhost
  client:
    fetch-registry: false # 表示是否從Eureka Server獲取註冊信息,默認爲true.因爲這是一個單點的Eureka Server,不需要同步其他的Eureka Server節點的數據,這裏設置爲false
    register-with-eureka: false # 表示是否將自己註冊到Eureka Server,默認爲true.由於當前應用就是Eureka Server,故而設置爲false.
    service-url:
      # 設置與Eureka Server的地址,查詢服務和註冊服務都需要依賴這個地址.默認是http://localhost:8761/eureka/;多個地址可使用','風格.
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

可以看到,上面的配置eureka的hostname是localhost,這個是屬於服務器端的配置,但還配置了client,裏面配置的內容是不把自己作爲服務註冊到Eureka Server服務查詢中,這個配置會讓我們看不懂,爲什麼服務器查詢要配置是否把自己註冊進服務查詢呢?這樣配置的確有點奇怪,調查發現,eureka中的服務端也是個客戶端,這樣做的目的是爲了讓服務端也可以互相註冊,實現高可用,但這樣的配置模式,確實很容易讓人誤解,不過既然已經使用了eureka,我們只能死記硬背了。

PS:具體可以搜索org.springframework.cloud.netflix.eureka. EurekaClientConfigBean來查找相關屬性如何配置。

配置好EurekaServer後,我們使用IDEA調試項目,然後在瀏覽器輸入:http://localhost:5180/,EurekaServer運行成功,如下圖:

創建普通服務並註冊到服務查詢中心——EurekaClient

下面我們創建一個WebApi,一個使用了EurekaClient的WebApi,項目會通過EurekaClient 將當前項目註冊到服務查詢中心裏,如下個圖:

點擊下一步,然後這次我們選擇SpringCloudDiscovery—Eureka Discovery Client,如下圖:

項目創建成功後,然後我們還是找到入口文件,爲KibaApplication類加上@EnableEurekaClient註解,如下圖:

然後修改application.properties爲application.yml,編寫代碼如下:

# 啓動端口
server:
  port: 5181
​
spring:
  application:
    name: eureka-kiba
# eureka客戶端配置,配置要註冊的服務查詢中心
eureka:
  client:
    service-url:
      defaultZone: http://localhost:5180/eureka # 指定服務註冊中心

然後我們在pom.xml裏添加spring-boot-starter-web的Jar包引用,代碼如下:

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

然後創建一個controller文件,再創建一個HelloWorld的java類,如下圖:

然後編輯HelloWorld類,代碼如下:

package com.client.kiba.controller;
​
import org.springframework.web.bind.annotation.*;
​
@RequestMapping(value = "/helloWorld")
@RestController
public class HelloWorld {
    @RequestMapping(value = "/GetName", method = RequestMethod.GET)
    public String GetName()
    {
        return "我是Kiba518";
    }
    @RequestMapping(value = "/GetAge", method = {RequestMethod.GET,RequestMethod.POST})
    public int GetAge()
    {
        return 518;
    }
    @PostMapping("/GetAge1")
    public int GetAge1()
    {
        return 518;
    }
    @GetMapping("/GetAge2")
    public int GetAge2()
    {
        return 518;
    }
}

然後啓動項目,然後在打開我們的eureka服務查詢中心——http://localhost:5180/,可以看到服務已經成功註冊進了服務中心。

注意:這裏需要單獨啓動一下我們剛剛建好的項目。


到此,eureka服務註冊就介紹完了。

不得不說,eureka把服務註冊處理的如此簡單,僅僅用配置就搞定了,實在非常優秀。

使用eureka內註冊的服務

創建一個新moudle,創建過程如上。

修改Kiba3Application的代碼如下:

package com.clinet.kiba3;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
​
@SpringBootApplication
@EnableDiscoveryClient
public class Kiba3Application {
​
    public static void main(String[] args) {
        SpringApplication.run(Kiba3Application.class, args);
    }
    @Bean
    @LoadBalanced
    RestTemplate restTemplate()
    {
        return new RestTemplate();
    }
}

然後創建RemoteController接口,代碼如下:

package com.clinet.kiba3.controller;
​
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
​
@RestController
@RequestMapping("/Remote")
public class RemoteController {
    @Autowired
    RestTemplate restTemplate;
​
    /**
     * http://localhost:5183/Remote/TestRestRequest
     * @return
     */
    @GetMapping("/TestRestRequest")
    public ResponseEntity<String> TestRestRequest() {
        /**
         * 第一個參數:url——http://eureka-kiba2/helloWorld/GetName 這裏把ip替換爲在eureka中註冊的名字
         * 第二個參數:返回值類型
         */
        ResponseEntity<String> entity = restTemplate.getForEntity("http://eureka-kiba2/helloWorld/GetName", String.class);
        System.out.println("狀態碼:" + entity.getStatusCode());
        System.out.println("響應體" + entity.getBody());
​
        return ResponseEntity.ok(entity.getBody());
​
    }      
}

如上所示,遠程調用使用的是RestTemplate,不過調用的URL稍微做了修改,如上所示,我們請求的url地址是【http://eureka-kiba2/helloWorld/GetName】,可以看到,我們將ip替換爲了在eureka中註冊的應用名了。

在其他的註冊中心中,比如consul,也是通過應用名來調用單體服務的,這種調用模式屬於潛規則了。

下圖爲各個單體服務在註冊中心註冊的應用名。

在網頁輸入http://localhost:5183/Remote/TestRestRequest,輸出結果如下圖:

PS:Eureka還可以通過配置實現負載均衡,因爲註冊到註冊中心的服務,使用【協議+應用名+controller】的模式請求,所以將同一個服務發佈到不同服務器, 調用時,因爲應用名相同,就可以進行請求分流了,進而實現負載均衡了。

網關

網關的作用主要是將請求重新分發。現在我們新建一個項目用於做網關。

與上文一樣,在項目上右鍵-->new-->Module-->Spring Initializr。

然後在選擇依賴jar包時,選擇Spring Cloud Routing——Getway,如下圖:

在Eureka中,網關也是要作爲客戶端註冊進註冊中心的。

也就是說,我們必須引用eureka-client,如下:

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

還要在啓動類上增加@EnableEurekaClient註解,如下:

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

然後,我們配置Getway中最複雜的內容,application.yml配置。

詳細配置如下:

server:
  port: 5184
spring:
  application:
    name: getway
  cloud:
    gateway:
      discovery:
        # locator需要打開,不然通過 lb://.. 方式請求不到
        locator:
          enabled: true #開啓 Gateway 服務註冊中心服務發現
      routes:
        - id: kiba1 # 路由的id,要求唯一,通常使用應用名
          uri: lb://eureka-kiba #lb是一個動態路由協議,後面的eureka-kiba 是要跳轉的服務名稱。
          predicates:
            - Path=/kiba1/helloWorld/** # 指定匹配的controller,也可以指定到方法,比如 - Path=/helloWorld/GetName/** 這裏kiba1會在下面被過濾掉,即請求的是lb://eureka-kiba/helloworld
          filters:
            - StripPrefix=1 #過濾掉一個請求前綴
            # JwtAuthorization
        - id: kiba2
          uri: lb://eureka-kiba2
          predicates:
            - Path=/kiba2/helloWorld_kiba2/**
          filters:
            - StripPrefix=1


eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:5180/eureka #註冊中心地址
#    healthcheck:
#      enabled: true

請求註冊中心的服務採用【協議+應用名+controller】的模式,但在Getway裏,需要把協議從http改爲了lb,才能請求註冊中心的服務,開啓lb協議需要配置locator的enable爲true。

應用名就是在註冊中心註冊的應用名,

routes:指定下面就是配置路由的配置模塊。

id:路由的id,要求唯一,通常使用應用名。

predicates:斷言,就是判斷請求是否符合條件,符合條件方可請求,即使用一些已經定義好的配置條件過濾。

predicates—Path:指定匹配的controller,也可以指定到方法,比如 - Path=/helloWorld/**,這樣配置的話就是要求,請求url格式必須爲http://localhost:5184/helloWorld,不然就請求失敗。

filters:過濾,可以過濾請求信息,這裏只用到了過濾路由的路徑。

filters—StripPrefix:過濾掉請求地址總的路徑,每個【/】分割一對路徑,這個功能非常有用,因爲配置路徑時,通常會加上前綴來區分服務,這個過濾可以過濾掉前綴。

配置完成後啓動項目,訪問如下地址,結果如下:

http://localhost:5184/kiba1/helloWorld/GetName

http://localhost:5184/kiba2/helloWorld_kiba2/GetAge

如上圖,我們已經實現了微服務的網關+註冊中心+單體服務註冊了。

結語

Java的微服務真的非常便捷,通過一篇比較好的文章即可學會,通過簡單的配置,就可以搭建完成。真是微服務界的王者。

----------------------------------------------------------------------------------------------------

到此,SpringCloud搭建微服務已經介紹完了。

代碼已經傳到Github上了,歡迎大家下載。

Github地址:https://github.com/kiba518/kibacloud

----------------------------------------------------------------------------------------------------

注:此文章爲原創,任何形式的轉載都請聯繫作者獲得授權並註明出處!
若您覺得這篇文章還不錯,請點擊下方的推薦】,非常感謝!

https://www.cnblogs.com/kiba/p/16738718.html

 

 

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