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. linux下ssd电子盘速度检测

    代码: #include<stdio.h> #include<sys/time.h> #include <fcntl.h> #include <pthread ...

  2. Ubuntu Desktop变为Ubuntu Server服务器版的方法

    去Ubuntu官网看到有好几种版本可以下载,alternate(文本安装).desktop9(桌面).netbook(上网本).server(服务器). 使用server版某个理由: 32位的系统可以 ...

  3. MySQL查询所有数据库表出错

    1.错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:show tables 错误代码: 1046 No database sel ...

  4. Python中进程

    程序 程序:编写完的代码称为程序. 进程 进程:又称重量级进程,正在执行中的程序称为进程.进程的执行会占用内存等资源.多个进程同时执行时,每个进程的执行都需要由操作系统按一定的算法(RR调度.优先数调 ...

  5. IOLI-crackme0x06-0x09 writeup

    前几天写了使用Radare2并用3中方法来解决crackme0x00, 然后紧接着第二天 就写了另外5个writeup, 如果认真看会发现那几个crackme的分析也是一开始 走了很多弯路, 但玩多了 ...

  6. C# Hook原理及EasyHook简易教程

    前言 在说C# Hook之前,我们先来说说什么是Hook技术.相信大家都接触过外挂,不管是修改游戏客户端的也好,盗取密码的也罢,它们都是如何实现的呢? 实际上,Windows平台是基于事件驱动机制的, ...

  7. 【HNOI2004】敲砖块(动态规划)

    越来越懒了,不想粘题目 题解 样例的输入是个很好的提醒, 把他往左边对齐之后 如果要打掉某个位置,那么必须要打掉右上方的所有砖 然后就很明显的一个DP了.... #include<iostrea ...

  8. 【Webpack的使用指南 02】Webpack的常用解决方案

    说是解决方案实际上更像是webpack的插件索引. 写这一篇的目的是为了形成一个所以,将来要用时直接来查找即可. 索引目录 1.自动构建HTML,可压缩空格,可给引用的js加版本号或随机数:html- ...

  9. C#开发Open-Webkit-Sharp浏览器并支持前端alert显示

    看了网上的很多教程,但是总是总是只言片语的,可能不同的人遇到的问题不一样,他们就只列举了自己的问题,那么这里我来做一下总结吧,跟大家分享一下我的完整的开发过程 首先你需要准备Visual Studio ...

  10. 关于java多态的理解

    要理解多态,就必须有一个大的理解方向,不然很容易绕进去. 首先知道多态的释义:多态性是指一个名词可以有多种语义. 对于java的多态性学习者来说,就是必须要知道多个同名方法在不同情况下的使用规则. j ...