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 功能),后面再研究下。

参考资料:

Spring Cloud Consul 实现服务注册和发现的更多相关文章

  1. Spring Cloud Consul使用——服务注册与发现(注册中心)

    整理自该文章 一.Consul 服务端接下来我们开发 Consul 的服务端,创建一个 spring-cloud-consul-producer 项目 1.添加依赖包 <dependencies ...

  2. Spring Cloud Alibaba | Nacos服务注册与发现

    目录 Spring Cloud Alibaba | Nacos服务注册与发现 1. 服务提供者 1.1 pom.xml项目依赖 1.2 配置文件application.yml 1.3 启动类Produ ...

  3. Spring Cloud Eureka 实现服务注册与发现

    微服务 是一种架构模式,跟具体的语言实现无关,微服务架构将业务逻辑分散到了各个服务当中,服务间通过网络层进行通信共同协作:这样一个应用就可以划分为多个服务单独来维护发布.构建一个可靠微服务系统是需要具 ...

  4. Spring Cloud实践之服务注册与发现Eureka

    一.简述: 服务提供者producer与服务消费者consumer都注册到eureka server,然后服务consumer在其应用内直接调用producer的服务名来调用服务,而不是像之前一样调用 ...

  5. 服务注册发现Eureka之一:Spring Cloud Eureka的服务注册与发现

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...

  6. Spring Cloud之Eureka服务注册与发现

    解决什么问题 ➟阐述微服务以及服务注册发现的部分概念 ➟阐述Eureka服务注册与发现的部分原理及细节 为什么需要服务中心 过去,每个应用都是一个CPU,一个主机上的单一系统.然而今天,随着大数据和云 ...

  7. Spring Cloud(一):服务注册与发现

    Spring Cloud是什么 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均 ...

  8. Spring Cloud Alibaba 的服务注册与发现

    Spring Cloud Alibaba 服务发现例子 一.需求 1.提供者完成的功能 2.消费者完成的功能 3.可以附加的额外配置 二.实现步骤 1.总的依赖引入 2.服务提供者和发现者,引入服务发 ...

  9. Spring Cloud Alibaba Nacos 服务注册与发现功能实现!

    Nacos 是 Spring Cloud Alibaba 中一个重要的组成部分,它提供了两个重要的功能:服务注册与发现和统一的配置中心功能. 服务注册与发现功能解决了微服务集群中,调用者和服务提供者连 ...

随机推荐

  1. Android okHttp网络请求库详解

    okhttp 是一个 Java 的 HTTP+SPDY 客户端开发包,同时也支持 Android.需要Android 2.3以上. 特点 OKHttp是Android版Http客户端.非常高效,支持S ...

  2. python3.4 UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position

    python3.4 UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 实用python的时候 打开一个csv的文件出 ...

  3. 利用Tomcat部署Web项目报错

    1.错误描述 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -help ...

  4. JustMock .NET单元测试利器(一)

    1.什么是Mock? Mock一词是指模仿或者效仿,用于创建实例和静态模拟.安排和验证行为.在软件开发中提及"mock",通常理解为模拟对象.模拟对象的概念就是我们想要创建一个可以 ...

  5. 权限的分类(shiro项目中来的五)

    第一种权限:菜单栏展示还是不展示的权限(粗颗粒) 实现方法,在SYS_ROLE表中添加一个字段rights,通过 public static BigInteger sumRights(String[] ...

  6. SOA和微服务架构

    微服务架构强调的第一个重点就是业务系统需要彻底的组件化和服务化,原有的单个业务系统会拆分为多个可以独立开发,设计,运行和运维的小应用.这些小应用之间通过服务完成交互和集成.每个小应用从前端web ui ...

  7. python基础—装饰器

    python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...

  8. 【Luogu2458】保安站岗(动态规划)

    [Luogu2458]保安站岗(动态规划) 题面 题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地 ...

  9. 【linux之链接,函数,随机数】

    一.链接 硬链接(hard link):同一个文件使用了多个别名.新建文件是已经存在的一个别名,,当原文件删除时,新建的文件仍然可以使用.硬链接和原来的文件没有什么区别,而且共享一个inode号.通过 ...

  10. 剑指offer(15)反转链表

    题目描述 输入一个链表,反转链表后,输出链表的所有元素. 题目分析 至少需要三个指针pPre(指向前一个结点).pCurrent(指向当前的结点,在代码中就是pHead).pPnext(指向后一个结点 ...