Spring Cloud Consul 實現服務註冊和發現

来源:https://www.cnblogs.com/xishuai/archive/2018/03/28/spring-cloud-consul-sample.html
-Advertisement-
Play Games

Spring Cloud 是一個基於 Spring Boot 實現的雲應用開發工具,它為基於 JVM 的雲應用開發中涉及的配置管理、服務發現、斷路器、智能路由、微代理、控制匯流排、全局鎖、決策競選、分散式會話和集群狀態管理等操作提供了一種簡單的開發方式。通過 Spring Boot 風格進行再封裝屏蔽 ...


Spring Cloud 是一個基於 Spring Boot 實現的雲應用開發工具,它為基於 JVM 的雲應用開發中涉及的配置管理、服務發現、斷路器、智能路由、微代理、控制匯流排、全局鎖、決策競選、分散式會話和集群狀態管理等操作提供了一種簡單的開發方式。通過 Spring Boot 風格進行再封裝屏蔽掉了複雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分散式系統開發工具包。

Spring Cloud 包含了多個子項目(針對分散式系統中涉及的多個不同開源產品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud CloudFoundry、Spring Cloud AWS、Spring Cloud Security、Spring Cloud Commons、Spring Cloud Zookeeper、Spring Cloud CLI 等項目。


項目地址:https://github.com/yuezhongxin/spring-cloud-consul-sample

ASP.NET Core 2.0 & Docker & Consul 的實現:https://github.com/yuezhongxin/HelloDocker.Sample

目前的測試站點,使用 ASP.NET Core 結合 Conusl 和 Fabio 搭建的微服務集群,因為各服務之間的通信基於 HTTP REST 協議,所以服務的實現可以跨語言,下麵我們就開發一個 Spring Boot 服務,然後使用 Spring Cloud Consul 將服務註冊到已有的集群中。

Java 開發工具我選用的 IntelliJ IDEA(MacOS 安裝教程),目前使用很好(Color Scheme 使用系統的 Darcula,字體大小 14),Java SDK 需要額外下載安裝(我安裝的版本 10)。

因為第一次使用 IntelliJ IDEA,下麵我把創建項目的過程,貼詳細一點。

首先,創建項目(選擇“Spring Initializr”,Spring Boot 項目),預設選擇 Java SDK 10:

然後填寫項目的基本信息(Artifact 為"spring-cloud-consul-sample",其他為預設):

註:Maven 是一個項目管理和構建工具,包含三個關鍵組件:項目對象模型(POM)、依賴項管理模型、構建生命周期和階段。

Group ID 和 Artifact ID 的區別,如果把 Group ID 看作是公司,那 Artifact ID 就可以看作是公司部門,有點類似於 .NET 中的解決方案和類庫的關係,比如 Spring Cloud 項目的 Group ID 為org.springframework.cloud,Spring Cloud Consul 的 Artifact ID 為spring-cloud-starter-consul-discovery

下麵選擇創建 Spring Boot 項目類型(選擇 Web 依賴項):

然後填寫項目名稱和項目目錄:

然後點擊“Finish”,就完成啦。


像開發 ASP.NET Core 應用程式一樣,我們需要先引用各種程式包,Spring Boot 項目也是一樣,因為使用 Maven 進行依賴管理,我們需要在pom.xml中配置依賴關係,配置如下:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

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

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

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
        <scope>compile</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-consul-dependencies</artifactId>
            <version>2.0.0.M7</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

引用spring-cloud-starter-consul-discovery對應 Spring Cloud Consul,引用spring-boot-starter-actuator用作健康檢查(地址/actuator/health),另外 Actuator 還支持項目的監控和管理。

這裡再說下節點的作用:

  • parent:父引用配置,會繼承父引用的配置。
  • dependencies:當前引用配置,如果父引用配置了,子項目會自動引用。
  • dependencyManagement:當然引用配置,如果父引用配置了,子項目不會自動引用,子項目只要用到的時候引用,不需要配置版本號。

然後再貼一下SpringCloudConsulSampleApplication.java的代碼:

package com.example.springcloudconsulsample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.discovery.DiscoveryClient;

@EnableDiscoveryClient
@RestController
@SpringBootApplication
public class SpringCloudConsulSampleApplication {

    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 獲取所有服務
     */
    @RequestMapping("/services")
    public Object services() {
        return discoveryClient.getServices();
    }

    @RequestMapping("/home")
    public String home() {
        return "Hello World";
    }

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

增加@EnableDiscoveryClient註解,項目啟動的時候,會註冊當前 Spring Boot 服務。

在使用 ASP.NET Core 註冊服務的時候,配置信息會填寫在代碼中(如服務名稱和埠等,當然也可以在配置文件),然後使用 Consul 組件註冊服務(調用 Consul HTTP REST)。

Spring Cloud Consul 註冊服務的話,需要添加配置文件(Spring Boot 項目資源文件在 resources 目錄下)。

application.properties中添加配置:

spring.application.name=spring-boot-service

然後添加application.yml配置文件:

debug: true
server:
  port: 24543
spring:
  cloud:
    consul:
      host: 127.0.0.1
      port: 8500
      discovery:
        register: true
        hostname: 10.9.10.215
        serviceName: ${spring.application.name}
        healthCheckPath: /actuator/health
        healthCheckInterval: 15s
        tags: urlprefix-/${spring.application.name}
        instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

上面配置需要再詳細說明說明下:

  • debug配置是否調試模式,如果打包發佈的話,需要設置為false
  • server.port配置的是 Spring Boot 服務的埠。
  • spring.cloud.consul.host/port配置的是本地 Consul 的地址和埠(Server 節點和 Client 節點都可以),Spring Cloud Consul 會調用 Consul HTTP REST 介面,進行服務註冊。
  • spring.cloud.consul.discovery.true配置啟動是否註冊服務,
  • spring.cloud.consul.discovery.hostname配置 Spring Boot 服務的主機地址,也可以不進行配置,預設本機地址。
  • spring.cloud.consul.discovery.serviceName配置 Consul 註冊的服務名稱,${spring.application.name}變數是我們上面application.properties配置文件中添加的配置。
  • spring.cloud.consul.discovery.healthCheckPath配置 Consul 健康檢查地址,Actuator 組件幫我們進行了實現,所以我們不需要額外的實現,地址在服務啟動的時候,列印信息裡面可以看到。
  • spring.cloud.consul.discovery.healthCheckInterval配置 Consul 健康檢查頻率,也就是心跳頻率。
  • spring.cloud.consul.discovery.tags配置 Consul 註冊服務的 Tags,設置為urlprefix-/serviceName的格式,是自動註冊到 Fabio 集群中。
  • spring.cloud.consul.discovery.instanceId配置 Consul 註冊服務 ID。

上面的工作做完之後,我們還需要在本地啟動 Consul 和 Fabio,參考:Mac OS、Ubuntu 安裝及使用 Consul

然後我們就可以直接使用 IntelliJ IDEA 調試項目了,按Shift + F9進行調試。

上面說到 Actuator 的列印信息:

2018-03-28 10:09:54.645  INFO 63482 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
2018-03-28 10:09:54.646  INFO 63482 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
2018-03-28 10:09:54.647  INFO 63482 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto protected java.util.Map<java.lang.String, java.util.Map<java.lang.String, org.springframework.boot.actuate.endpoint.web.Link>> org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.links(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)

或者我們也可以使用 Maven 打包發佈,然後使用命令啟動服務。使用 IntelliJ IDEA 中的 Maven 進行打包,或者使用 Maven 命令打包都可以,這邊我們使用Maven 命令進行打包。

在我們安裝 IntelliJ IDEA 的時候,Maven 自動安裝了,但直接敲mvn -v會發現命令找不到,需要我們配置一下環境變數。

我自己的 Maven 文件目錄是/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3,可以在 IntelliJ IDEA 的配置設置中找到,然後我們執行下麵的命令:

$ export M2_HOME="/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3" && 
export PATH=$PATH:$M2_HOME/bin && 
chmod a+x "/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/bin/mvn"

然後檢查下 Maven 命令是否生效:

$ mvn -v
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
Maven home: /Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3
Java version: 10, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/Home
Default locale: zh_CN_#Hans, platform encoding: UTF-8
OS name: "mac os x", version: "10.13.2", arch: "x86_64", family: "mac"

然後我們修改application.yml中的debug:false,使用 Maven 進行打包(目錄切換到pom.xml平級):

$ mvn clean package  -Dmaven.test.skip=true
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building spring-cloud-consul-sample 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.0.0:clean (default-clean) @ spring-cloud-consul-sample ---
[INFO] Deleting /Users/xishuai/Documents/項目文件/測試項目/spring-cloud-consul-sample/target
[INFO]
[INFO] --- maven-resources-plugin:3.0.1:resources (default-resources) @ spring-cloud-consul-sample ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ spring-cloud-consul-sample ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/xishuai/Documents/項目文件/測試項目/spring-cloud-consul-sample/target/classes
[INFO]
[INFO] --- maven-resources-plugin:3.0.1:testResources (default-testResources) @ spring-cloud-consul-sample ---
[INFO] Not copying test resources
[INFO]
[INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ spring-cloud-consul-sample ---
[INFO] Not compiling test sources
[INFO]
[INFO] --- maven-surefire-plugin:2.20.1:test (default-test) @ spring-cloud-consul-sample ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ spring-cloud-consul-sample ---
[INFO] Building jar: /Users/xishuai/Documents/項目文件/測試項目/spring-cloud-consul-sample/target/spring-cloud-consul-sample-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.0.0.RELEASE:repackage (default) @ spring-cloud-consul-sample ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.815 s
[INFO] Finished at: 2018-03-28T10:26:46+08:00
[INFO] Final Memory: 30M/114M
[INFO] ------------------------------------------------------------------------

生成的 jar 程式包,會在 target 目錄下,文件為spring-cloud-consul-sample-0.0.1-SNAPSHOT.jar(格式為項目名 + 版本號),然後我們可以直接啟動服務了:

$ java -jar  target/spring-cloud-consul-sample-0.0.1-SNAPSHOT.jar
2018-03-28 10:33:31.750  INFO 63875 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2b662a77: startup date [Wed Mar 28 10:33:31 CST 2018]; root of context hierarchy
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (jar:file:/Users/xishuai/Documents/項目文件/測試項目/spring-cloud-consul-sample/target/spring-cloud-consul-sample-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/spring-core-5.0.4.RELEASE.jar!/) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2018-03-28 10:33:31.971  INFO 63875 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2018-03-28 10:33:32.015  INFO 63875 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$4d45e598] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.0.RELEASE)

查看健康檢查是否成功:

查看 Consul 是否服務註冊成功:

查看 Fabio 集群是否包含服務:

服務註冊成功之後,我們可以手動進行發現服務,或者通過 Spring Cloud Ribbon/Feign 組件進行發現,並提供負載均衡功能(類似於 Fabio 功能),後面再研究下。

參考資料:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • function returnFloat(value) { var value = Math.round(parseFloat(value) * 100) / 100; var xsd = value.toString().split("."); if (xsd.length == 1) { val ...
  • 最近應項目需求,為了獲取到更多用戶想要搜索的信息,需要把用戶點擊複製的內容獲取到,然後傳送給後臺以更好的瞭解客戶需求,自己在這個方法上栽了個大跟頭,只考慮其一卻不知道結合使用,腦袋卡頓,隨筆記下,望自己能夠慢慢成長、進步。 其中window.getSelection()是為了獲取選中的內容,詳解見h ...
  • 左右氣泡信息,這種展示效果用代碼寫並不難,但是我覺得這種佈局很有意思,所以就記錄下來了~~ 效果圖: ...
  • 1、jsp頁面通過EL表達式獲取list大小,中間件用tomcat7時,下麵這個寫法是可以的 2、但是如果用低版本的中間件,比如tomcat6,就會報錯,這種寫法有相容性問題,那麼需要改成下麵這種就相容低版本了 ...
  • 我新建了一個web前端的新手交流群,包括基礎知識和剛入職的技術分享,人還不多,期待著每一個人的加入,希望可以得到你的認同哦~你的加入是我組織交流群的一大動力哦!~ 歡迎大佬進駐,有很多萌新等待大佬的幫助哦! web前端交流QQ群:314439765 ...
  • 線程在它的生命周期中會處於各種不同的狀態:新建、等待、就緒、運行、阻塞、死亡。1、新建用new語句創建的線程對象處於新建狀態,此時它和其他java對象一樣,僅被分配了記憶體。2、等待當線程在new之後,並且在調用start方法前,線程處於等待狀態。 3、就緒當一個線程對象創建後,其他線程調用它的sta ...
  • 還是看代碼能讓我靜下心來。我現在語言表達能力嚴重下降,又不自信。fuck,不想了,我還是我,世上獨一無二的我。走自己的路,讓別人看吧。馬上4月了,天也變熱了! 閑話少扯,今天說單例模式,就算22種模式都不知道,也應該知道單例模式,這個在實際項目中用的比較多。 一個應用是一個進程,在記憶體中分配一定的空 ...
  • 橋接模式屬於先天模式,這裡的先天模式就是說一開始就要把結構搭建好,方便後來的擴展,而不是對已經出現的模塊和介面進行改進擴展的。橋接的核心在於實體類和操作類之間的聚合關係,這個聚合關係就是我們所說的"橋",不同於裝飾、代理和適配器模式的中的聚合關係,橋接不存在兩者之間的繼承關係,操作類是完全解耦的,而 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...