Spring Cloud Consul 实现服务注册和发现
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 的配置设置中找到,然后我们执行下面的命令:
$ chmod a+x "/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/bin/mvn"
$ sudo chmod 777 /etc/profile
$ vi /etc/profile
# set maven path
export M2_HOME="/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3"
export PATH=$PATH:$M2_HOME/bin
$ source /etc/profile
然后检查下 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 功能),后面再研究下。
参考资料:
- ameizi/spring-cloud-consul-example
- Spring Cloud构建微服务架构:服务注册与发现(Eureka、Consul)
- Spring Cloud Consul
- Spring Cloud Consul
- 使用 Spring Cloud Consul 实现服务的注册和发现
- Service Discovery with Consul
- spring-cloud-consul/spring-cloud-consul-sample
- Spring Boot Actuator 监控端点小结
- Spring Cloud(二)Consul 服务治理实现(推荐)
- 构建微服务(二)服务注册与发现
- springboot(十二):springboot 如何测试打包部署(推荐)
- springcloud(一):大话 Spring Cloud(推荐)
Spring Cloud Consul 实现服务注册和发现的更多相关文章
- Spring Cloud Consul使用——服务注册与发现(注册中心)
整理自该文章 一.Consul 服务端接下来我们开发 Consul 的服务端,创建一个 spring-cloud-consul-producer 项目 1.添加依赖包 <dependencies ...
- Spring Cloud Alibaba | Nacos服务注册与发现
目录 Spring Cloud Alibaba | Nacos服务注册与发现 1. 服务提供者 1.1 pom.xml项目依赖 1.2 配置文件application.yml 1.3 启动类Produ ...
- Spring Cloud Eureka 实现服务注册与发现
微服务 是一种架构模式,跟具体的语言实现无关,微服务架构将业务逻辑分散到了各个服务当中,服务间通过网络层进行通信共同协作:这样一个应用就可以划分为多个服务单独来维护发布.构建一个可靠微服务系统是需要具 ...
- Spring Cloud实践之服务注册与发现Eureka
一.简述: 服务提供者producer与服务消费者consumer都注册到eureka server,然后服务consumer在其应用内直接调用producer的服务名来调用服务,而不是像之前一样调用 ...
- 服务注册发现Eureka之一:Spring Cloud Eureka的服务注册与发现
Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...
- Spring Cloud之Eureka服务注册与发现
解决什么问题 ➟阐述微服务以及服务注册发现的部分概念 ➟阐述Eureka服务注册与发现的部分原理及细节 为什么需要服务中心 过去,每个应用都是一个CPU,一个主机上的单一系统.然而今天,随着大数据和云 ...
- Spring Cloud(一):服务注册与发现
Spring Cloud是什么 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均 ...
- Spring Cloud Alibaba 的服务注册与发现
Spring Cloud Alibaba 服务发现例子 一.需求 1.提供者完成的功能 2.消费者完成的功能 3.可以附加的额外配置 二.实现步骤 1.总的依赖引入 2.服务提供者和发现者,引入服务发 ...
- Spring Cloud Alibaba Nacos 服务注册与发现功能实现!
Nacos 是 Spring Cloud Alibaba 中一个重要的组成部分,它提供了两个重要的功能:服务注册与发现和统一的配置中心功能. 服务注册与发现功能解决了微服务集群中,调用者和服务提供者连 ...
随机推荐
- mysql常用基础操作语法(九)~~外连接查询【命令行模式】
1.左外连接left outer join或者left jion,outer可以省略不写,下边的右连接和全连接也一样: 左外连接的意思是,以left join左边的表中的数据为基准,即左边的表中有的必 ...
- 【javascript】jQuery判断用户右击事件
jquery 判断用户是鼠标是右击还是左击, // 1 = 鼠标左键 left; 2 = 鼠标中键; 3 = 鼠标右键 $(document).mousedown(function(e) { if(3 ...
- PHP simpleXML文件编程
SimpleXML simpleXML该技术的核心思想是以面向对象的方式来操作xml文件 <?php //simplexml文件 讲所有的元素转成对象 $library=simplexml_lo ...
- CSS3之background-clip
1.属性简介 background-clip:padding|border|content|text|!important 2.兼容性 (1)IE6.7.8不兼容 (2)火狐3.0以上兼容 (3)Ch ...
- VxWorks 基本启动方式
VxWorks 基本启动方式 按VxWorks内核的下载形式,VxWorks启动总体上分为两种方式:下载型和ROM 型. @下载型启动方式:bootrom+VxWorks.此时boot ...
- Caused by: java.net.SocketException: Software caused connection abort: socket write error
1.错误描述 [ERROR:]2015-05-06 10:54:18,967 [异常拦截] ClientAbortException: java.net.SocketException: Softwa ...
- 从Git到GitHub,详细教程
众所周知,一个稍微有点规模的项目,都不可能是一个人单打独斗完成的(能完成的大神别打我),所以,一个高效的项目团队就需要一个NB的工具来进行有效的交流(曾经有人问我企鹅不就可以吗,我竟无言以对),今天就 ...
- hdu5730 Shell Necklace
重温了这道cdq+FFT 讲白了就是不断对 dp[l~mid] 和 sh[1~r] 进行fft 得到 dp[mid+1~r] #include<bits/stdc++.h> using n ...
- POJ - 2828
题意 输入队伍长度n 接下来n行,a,b 表示b插在队伍的a处 求队伍最后的情况 题解 刚开始并不知道要用线段树,经大佬点悟,发现最后插入的位置就是对应的a.所以可以从后往前依次插入,每次的位置pos ...
- [BZOJ1046] [HAOI2007] 上升序列 (dp)
Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ...