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@SpringBootApplicationpublic 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配置文件:
然後添加application.yml配置文件:debug: trueserver: port: 24543spring: 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
然後我們就可以直接使用IntelliJ IDEA 調試項目了,按Shift + F9進行調試。
上面說到Actuator 的打印信息:
2018-03-28 10:09:54.645 INFO 63482 --- [ main] sbaewsWebMvcEndpointHandlerMapping : 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] sbaewsWebMvcEndpointHandlerMapping : 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] sbaewsWebMvcEndpointHandlerMapping : 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 -vApache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)Maven home: /Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3Java version: 10, vendor: Oracle CorporationJava home: /Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/HomeDefault locale: zh_CN_#Hans, platform encoding: UTF-8OS 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.jar2018-03-28 10:33:31.750 INFO 63875 --- [ main] scaAnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2b662a77: startup date [Wed Mar 28 10:33:31 CST 2018]; root of context hierarchyWARNING: An illegal reflective access operation has occurredWARNING: 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$1WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operationsWARNING: All illegal access operations will be denied in a future release2018-03-28 10:33:31.971 INFO 63875 --- [ main] faAutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring2018-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 功能),後面再研究下。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。