詳解Spring Cloud Consul 實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)
Spring Cloud 是一個(gè)基于 Spring Boot 實(shí)現(xiàn)的云應(yīng)用開發(fā)工具,它為基于 JVM 的云應(yīng)用開發(fā)中涉及的配置管理、服務(wù)發(fā)現(xiàn)、斷路器、智能路由、微代理、控制總線、全局鎖、決策競(jìng)選、分布式會(huì)話和集群狀態(tài)管理等操作提供了一種簡單的開發(fā)方式。通過 Spring Boot 風(fēng)格進(jìn)行再封裝屏蔽掉了復(fù)雜的配置和實(shí)現(xiàn)原理,最終給開發(fā)者留出了一套簡單易懂、易部署和易維護(hù)的分布式系統(tǒng)開發(fā)工具包。
Spring Cloud 包含了多個(gè)子項(xiàng)目(針對(duì)分布式系統(tǒng)中涉及的多個(gè)不同開源產(chǎn)品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud CloudFoundry、Spring Cloud AWS、Spring Cloud Security、Spring Cloud Commons、Spring Cloud Zookeeper、Spring Cloud CLI 等項(xiàng)目。
項(xiàng)目地址:https://github.com/yuezhongxin/spring-cloud-consul-sample
ASP.NET Core 2.0 & Docker & Consul 的實(shí)現(xiàn):https://github.com/yuezhongxin/HelloDocker.Sample
目前的測(cè)試站點(diǎn),使用 ASP.NET Core 結(jié)合 Conusl 和 Fabio 搭建的微服務(wù)集群,因?yàn)楦鞣?wù)之間的通信基于 HTTP REST 協(xié)議,所以服務(wù)的實(shí)現(xiàn)可以跨語言,下面我們就開發(fā)一個(gè) Spring Boot 服務(wù),然后使用 Spring Cloud Consul 將服務(wù)注冊(cè)到已有的集群中。
Java 開發(fā)工具我選用的 IntelliJ IDEA(MacOS 安裝教程),目前使用很好(Color Scheme 使用系統(tǒng)的 Darcula,字體大小 14),Java SDK 需要額外下載安裝(我安裝的版本 10)。
因?yàn)榈谝淮问褂?IntelliJ IDEA,下面我把創(chuàng)建項(xiàng)目的過程,貼詳細(xì)一點(diǎn)。
首先,創(chuàng)建項(xiàng)目(選擇“Spring Initializr”,Spring Boot 項(xiàng)目),默認(rèn)選擇 Java SDK 10:
然后填寫項(xiàng)目的基本信息(Artifact 為"spring-cloud-consul-sample",其他為默認(rèn)):
注:Maven 是一個(gè)項(xiàng)目管理和構(gòu)建工具,包含三個(gè)關(guān)鍵組件:項(xiàng)目對(duì)象模型(POM)、依賴項(xiàng)管理模型、構(gòu)建生命周期和階段。
Group ID 和 Artifact ID 的區(qū)別,如果把 Group ID 看作是公司,那 Artifact ID 就可以看作是公司部門,有點(diǎn)類似于 .NET 中的解決方案和類庫的關(guān)系,比如 Spring Cloud 項(xiàng)目的 Group ID 為org.springframework.cloud
,Spring Cloud Consul 的 Artifact ID 為spring-cloud-starter-consul-discovery
。
下面選擇創(chuàng)建 Spring Boot 項(xiàng)目類型(選擇 Web 依賴項(xiàng)):
然后填寫項(xiàng)目名稱和項(xiàng)目目錄:
然后點(diǎn)擊“Finish”,就完成啦。
像開發(fā) ASP.NET Core 應(yīng)用程序一樣,我們需要先引用各種程序包,Spring Boot 項(xiàng)目也是一樣,因?yàn)槭褂?Maven 進(jìn)行依賴管理,我們需要在pom.xml
中配置依賴關(guān)系,配置如下:
<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
對(duì)應(yīng) Spring Cloud Consul,引用spring-boot-starter-actuator
用作健康檢查(地址/actuator/health
),另外 Actuator 還支持項(xiàng)目的監(jiān)控和管理。
這里再說下節(jié)點(diǎn)的作用:
parent
:父引用配置,會(huì)繼承父引用的配置。dependencies
:當(dāng)前引用配置,如果父引用配置了,子項(xiàng)目會(huì)自動(dòng)引用。dependencyManagement
:當(dāng)然引用配置,如果父引用配置了,子項(xiàng)目不會(huì)自動(dòng)引用,子項(xiàng)目只要用到的時(shí)候引用,不需要配置版本號(hào)。
然后再貼一下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; /** * 獲取所有服務(wù) */ @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
注解,項(xiàng)目啟動(dòng)的時(shí)候,會(huì)注冊(cè)當(dāng)前 Spring Boot 服務(wù)。
在使用 ASP.NET Core 注冊(cè)服務(wù)的時(shí)候,配置信息會(huì)填寫在代碼中(如服務(wù)名稱和端口等,當(dāng)然也可以在配置文件),然后使用 Consul 組件注冊(cè)服務(wù)(調(diào)用 Consul HTTP REST)。
Spring Cloud Consul 注冊(cè)服務(wù)的話,需要添加配置文件(Spring Boot 項(xiàng)目資源文件在 resources 目錄下)。
application.properties
中添加配置:
spring.application.name=spring-boot-service
然后添加application.yml
配置文件:
然后添加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}}}
上面配置需要再詳細(xì)說明說明下:
debug
配置是否調(diào)試模式,如果打包發(fā)布的話,需要設(shè)置為false
。server.port
配置的是 Spring Boot 服務(wù)的端口。spring.cloud.consul.host/port
配置的是本地 Consul 的地址和端口(Server 節(jié)點(diǎn)和 Client 節(jié)點(diǎn)都可以),Spring Cloud Consul 會(huì)調(diào)用 Consul HTTP REST 接口,進(jìn)行服務(wù)注冊(cè)。spring.cloud.consul.discovery.true
配置啟動(dòng)是否注冊(cè)服務(wù),spring.cloud.consul.discovery.hostname
配置 Spring Boot 服務(wù)的主機(jī)地址,也可以不進(jìn)行配置,默認(rèn)本機(jī)地址。spring.cloud.consul.discovery.serviceName
配置 Consul 注冊(cè)的服務(wù)名稱,${spring.application.name}
變量是我們上面application.properties
配置文件中添加的配置。spring.cloud.consul.discovery.healthCheckPath
配置 Consul 健康檢查地址,Actuator 組件幫我們進(jìn)行了實(shí)現(xiàn),所以我們不需要額外的實(shí)現(xiàn),地址在服務(wù)啟動(dòng)的時(shí)候,打印信息里面可以看到。spring.cloud.consul.discovery.healthCheckInterval
配置 Consul 健康檢查頻率,也就是心跳頻率。spring.cloud.consul.discovery.tags
配置 Consul 注冊(cè)服務(wù)的 Tags,設(shè)置為urlprefix-/serviceName
的格式,是自動(dòng)注冊(cè)到 Fabio 集群中。spring.cloud.consul.discovery.instanceId
配置 Consul 注冊(cè)服務(wù) ID。
上面的工作做完之后,我們還需要在本地啟動(dòng) Consul 和 Fabio
然后我們就可以直接使用 IntelliJ IDEA 調(diào)試項(xiàng)目了,按Shift + F9
進(jìn)行調(diào)試。
上面說到 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 打包發(fā)布,然后使用命令啟動(dòng)服務(wù)。使用 IntelliJ IDEA 中的 Maven 進(jìn)行打包,或者使用 Maven 命令打包都可以,這邊我們使用Maven 命令進(jìn)行打包。
在我們安裝 IntelliJ IDEA 的時(shí)候,Maven 自動(dòng)安裝了,但直接敲mvn -v
會(huì)發(fā)現(xiàn)命令找不到,需要我們配置一下環(huán)境變量。
我自己的 Maven 文件目錄是/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3
,可以在 IntelliJ IDEA 的配置設(shè)置中找到,然后我們執(zhí)行下面的命令:
$ 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 進(jìn)行打包(目錄切換到pom.xml
平級(jí)):
$ 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/項(xiàng)目文件/測(cè)試項(xiàng)目/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/項(xiàng)目文件/測(cè)試項(xiàng)目/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/項(xiàng)目文件/測(cè)試項(xiàng)目/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 程序包,會(huì)在 target 目錄下,文件為spring-cloud-consul-sample-0.0.1-SNAPSHOT.jar
(格式為項(xiàng)目名 + 版本號(hào)
),然后我們可以直接啟動(dòng)服務(wù)了:
$ 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/項(xiàng)目文件/測(cè)試項(xiàng)目/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 是否服務(wù)注冊(cè)成功:
查看 Fabio 集群是否包含服務(wù):
服務(wù)注冊(cè)成功之后,我們可以手動(dòng)進(jìn)行發(fā)現(xiàn)服務(wù),或者通過 Spring Cloud Ribbon/Feign 組件進(jìn)行發(fā)現(xiàn),并提供負(fù)載均衡功能(類似于 Fabio 功能),后面再研究下。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
eclipse創(chuàng)建java項(xiàng)目并運(yùn)行的詳細(xì)教程講解
eclipse是java開發(fā)的ide工具,是大部分java開發(fā)人員的首選開發(fā)工具,可是對(duì)于一些新Java人員來說,不清楚eclipse怎么運(yùn)行項(xiàng)目?這篇文章主要給大家介紹了關(guān)于eclipse創(chuàng)建java項(xiàng)目并運(yùn)行的相關(guān)資料,需要的朋友可以參考下2023-04-04通過實(shí)例解析Java分布式鎖三種實(shí)現(xiàn)方法
這篇文章主要介紹了通過實(shí)例解析Java分布式鎖三種實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Java 實(shí)現(xiàn)RSA非對(duì)稱加密算法
RSA解決了對(duì)稱加密的一個(gè)不足,比如AES算法加密和解密時(shí)使用的是同一個(gè)秘鑰,因此這個(gè)秘鑰不能公開,因此對(duì)于需要公開秘鑰的場(chǎng)合,我們需要在加密和解密過程中使用不同的秘鑰,加密使用的公鑰可以公開,解密使用的私鑰要保密,這就是非對(duì)稱加密的好處?!?/div> 2021-06-06Spark學(xué)習(xí)筆記 (二)Spark2.3 HA集群的分布式安裝圖文詳解
這篇文章主要介紹了Spark2.3 HA集群的分布式安裝,結(jié)合圖文與實(shí)例形式詳細(xì)分析了Spark2.3 HA集群分布式安裝具體下載、安裝、配置、啟動(dòng)及執(zhí)行spark程序等相關(guān)操作技巧,需要的朋友可以參考下2020-02-02Java語言描述存儲(chǔ)結(jié)構(gòu)與鄰接矩陣代碼示例
這篇文章主要介紹了Java語言描述存儲(chǔ)結(jié)構(gòu)與鄰接矩陣代碼示例,涉及Java存儲(chǔ)結(jié)構(gòu),鄰接矩陣,鄰接表的介紹與比較,然后分享了鄰接矩陣的Java實(shí)現(xiàn)等相關(guān)內(nèi)容,具有一定借鑒價(jià)值,需要的朋友可以參考。2017-11-11Java 使用Calendar計(jì)算時(shí)間的示例代碼
這篇文章主要介紹了Java 使用Calendar計(jì)算時(shí)間的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10詳解Java并發(fā)工具類之CountDownLatch和CyclicBarrier
在JDK的并發(fā)包中,有幾個(gè)非常有用的并發(fā)工具類,它們分別是:CountDownLatch、CyclicBarrier、Semaphore和Exchanger,本文主要來講講其中CountDownLatch和CyclicBarrier的使用,感興趣的可以了解一下2023-06-06最新評(píng)論