文章目录
  1. 1.概述
    1. 1.1 参考资料
    2. 1.2 Spring Cloud 版本
    3. 1.3 各类生态组件
    4. 1.4 SpringCloud 与 Dubbo/Dubbox 的比较
  2. 2.使用实例(基于 IntelliJ IDEA)
    1. 2.0 创建父项目 spring-cloud-demo
    2. 2.1 创建子模块 spring-cloud-registry(服务注册中心)
      1. 2.1.1 pom.xml
      2. 2.1.2 application.properties
      3. 2.1.3 SpringCloudRegistryApplication.java
      4. 2.1.4 运行
    3. 2.2 创建子模块 spring-cloud-provider(服务提供方)
      1. 2.2.1 pom.xml
      2. 2.2.2 application.properties
      3. 2.2.3 SpringCloudProviderController.java
      4. 2.2.4 SpringCloudProviderApplication.java
      5. 2.2.5 运行
    4. 2.3 创建子模块 spring-cloud-consumer(服务消费方)
      1. 2.3.1 pom.xml
      2. 2.3.2 application.properties
      3. 2.3.3 SpringCloudConsumerController.java
      4. 2.3.4 SpringCloudConsumerApplication.java
      5. 2.3.5 运行
    5. 2.4 辅助脚本
  3. 3.高可用服务注册中心
    1. 3.1 新建 spring-cloud-registry/application-peer1.properties
    2. 3.2 新建 spring-cloud-registry/application-peer2.properties
    3. 3.3 新建 spring-cloud-provider/application-peer1.properties
    4. 3.4 新建 spring-cloud-provider/application-peer2.properties
    5. 3.5 确认 spring-cloud-consumer/application.properties
    6. 3.6 启动所有注册中心和服务提供者、服务消费者
    7. 3.7 查看两个服务中心的控制台

Alibaba Dubbo 是国内流行的微服务框架,而 SpringCloud 是国外流行的微服务框架。SpringCloud 为微服务提供一站式完整的解决方案,具有独特的优势和发展前景。本文讲述了 SpringCloud 的历史和版本号规则、与同类产品相比的优势,并基于 SpringBoot 演示了服务注册中心、服务提供者和消费者的实现方法,并说明了高可用注册中心的部署思路。

作者:王克锋
出处:https://kefeng.wang/2017/12/20/spring-cloud/
版权:自由转载-非商用-非衍生-保持署名,转载请标明作者和出处。

1.概述

  Spring Cloud 是一个基于 Spring Boot 实现的“微服务架构”开发工具,它为基于JVM的云应用开发中涉及的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。
  所谓“微服务架构”,就是将一个完整的应用,从数据存储开始垂直拆分成多个不同的服务,每个服务都能独立部署、独立维护、独立扩展,服务与服务间通过诸如 RESTful API 的方式互相调用。

1.1 参考资料

Microservice Architecture
Martin Flower - 微服务
Spring Cloud 官网
Spring Cloud 中文网
Spring Cloud
《Spring Cloud微服务实战》 - 电子工业出版社 - 翟永超 著

1.2 Spring Cloud 版本

  Spring Cloud 是一个拥有众多子项目的大项目,每个子项目都有自己的版本号,每个 Spring Cloud 版本会包含不同版本的子项目。为避免主项目与子项目版本号混淆,Spring Cloud 版本不采用数字方式,而是通过命名方式。
  这些版本名称采用了伦敦地铁站名,按字母表顺序使用,如 Angel / Brixton / Camden / Dalston / Edgware / Finchley(尚未发布正式版本),当 Spring Cloud 项目的发布内容积累的重要程度时,就会发布一个“Service Releases”版本,简称 SRn 版本,其中n是一个递增数字。

Spring Cloud 版本列表见这里:Spring Cloud Dependencies
各大版本及其最新 SR、首SR月份、最新SR月份,如下(截止 2018-01-18,只涉及正式版本GA):

  • Angel.SR6: 2016-01
  • Brixton.SR7: 2016-05 ~ 2016-11
  • Camden.SR7: 2016-09 ~ 2017-05
  • Dalston.SR5: 2017-04 ~ 2017-12
  • Edgware.SR1: 2017-11 ~ 2018-01

建议使用最新的 SR 正式版本(当前为 Edgware.SR1)。
注意 Edgware 不支持 SpringBoot 2.x,可用 1.5.10.RELEASE(1.x 最高版本)。
否则应用类启动时会报错:java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>(...)

1.3 各类生态组件

  • Spring Cloud Eureka: 服务治理组件(服务发现)
  • Spring Cloud Ribbon: 客户端负载均衡组件
  • Spring Cloud Hystrix: 服务容错保护组件(断路器)
  • Spring Cloud Feign: 声明式服务调用组件
  • Spring Cloud Zuul: API 网关治理组件(智能路由)
  • Spring Cloud Config: 分布式配置中心组件
  • Spring Cloud Bus: 消息总线组件
  • Spring Cloud Stream: 消息驱动组件
  • Spring Cloud Sleuth: 分布式服务跟踪组件

SpringCloud 流程图:

  • 请求统一通过API网关(Zuul)来访问内部服务.
  • 网关接收到请求后,从注册中心(Eureka)获取可用服务
  • 由Ribbon进行均衡负载后,分发到后端具体实例
  • 微服务之间通过Feign进行通信处理业务
  • Hystrix负责处理服务超时熔断
  • Turbine监控服务间的调用和熔断相关指标

1.4 SpringCloud 与 Dubbo/Dubbox 的比较

  与 Dubbo 相比,SpringCloud 提供了完整的微服务各个组件(核心仍然是服务治理),提供更灵活的 REST API 调用方式(Dubbo只有RPC,当当扩展的Dubbox优化了RPC并增加了REST API)。
  Dubbo 采用 Zookeeper 作为服务注册中心,因此只需要开发 Productor 和Consumer 即可;而 Spring Cloud 需要我们开发一个服务治理服务(服务注册中心),不过这对于 Spring Boot 是很便捷的。

对比点 SpringCloud Dubbo
出品者 Spring社区 阿里巴巴
活跃度 更新频繁 五年未更新,刚重启更新
流行地 国外 国内
功能 整个微服务架构的各方面,包括服务治理,像品牌机稳定 只是实现了服务治理(注册/发现/监控/调度等),其他环节要自己接入,像组装机有风险
注册中心 Netflix Eureka(遵循AP) ZooKeeper(遵循CP,欠佳)
调用方式 RPC/REST API(供消双方没有代码级别的强依赖) RPC(供消双方需要使用共同接口,必须对外封装出REST API),当当的dubbox是添加了REST API支持
编码侵入性 有侵入 通过Spring配置,无侵入
开发文档 英文、中文(SpringCloud中文网SpringCloud中国社区) 中文、英文

国际上,SpringCloud是主流;而Dubbo在国内是主流,有一定局限性,现在Dubbo在积极适配SpringCloud。长远来看,SpringCloud是未来趋势。

2.使用实例(基于 IntelliJ IDEA)

  Spring Cloud 为服务治理(服务注册中心、服务注册与发现)做了一层抽象接口,Spring Cloud 应用中支持多种不同的服务治理框架,比如 Eureka([ju’riːkə]推荐使用) / Consul / Zookeeper,这些选项可以在新建项目时 Cloud Discovery 分支下看到。本例也是使用 Eureka。

Eureka分为两部分:

  • Eureka Server: 服务注册中心(服务注册中心使用);
  • Eureka Client: 服务注册(服务提供者使用)、服务发现(服务消费者使用)。

本例中,各个模块都运行在本机上,端口规划如下:

  • 服务注册中心(集群):800x,如 8001,8002
  • 服务提供者(多个):806x,如 8061,8062,8063
  • 服务消费者(多个):808x,如 8081,8082

2.0 创建父项目 spring-cloud-demo

创建 Maven 工程(不依赖于任何 Maven 框架),创建后删除 src 目录。
wang.kefeng/spring-cloud-demo

2.1 创建子模块 spring-cloud-registry(服务注册中心)

依赖选择: Cloud Discovery / Eureka Server(服务端)

2.1.1 pom.xml

其中的 spring-cloud-starter-eureka-server 已废弃(Deprecated),需要手工改为 spring-cloud-starter-netflix-eureka-server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>

<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR1</spring-cloud.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

2.1.2 application.properties

指定端口号为 8001,注意必须指定注册中心URL(eureka.client.serviceUrl.defaultZone,不论是否需要向它注册):

  • 如果只有一个注册中心: 指定自身URL,指定“不注册自身至注册中心”(eureka.client.register-with-eureka=false);
  • 如果有多个注册中心:指定其他注册中心URL,指定“要注册自身至指定的其他注册中心”(eureka.client.register-with-eureka=true);
1
2
3
4
5
6
7
8
server.port=8001
spring.application.name=spring-cloud-registry

# eureka.client.fetch-registry: 不去检索其他的服务
# eureka.client.register-with-eureka: 是否把自身注册到注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

2.1.3 SpringCloudRegistryApplication.java

增加注解 @EnableEurekaServer 启用“服务注册中心(Eureka Server)”

2.1.4 运行

运行 SpringCloudRegistryApplication.java

1
2
3
### spring-cloud-registry 日志
10:01:27.601 INFO [EurekaServerInitializerConfiguration.java:72] - Started Eureka Server
10:01:27.726 INFO [StartupInfoLogger.java:57] - Started SpringCloudRegistryApplication in 15.558 seconds (JVM running for 21.684)

进入 http://localhost:8001/
可见 “Instances currently registered with Eureka” 一栏,还没有注册到 Eureka 的服务提供者和消费者的实例。

2.2 创建子模块 spring-cloud-provider(服务提供方)

依赖选择: Cloud Discovery / Eureka Discovery(客户端)

2.2.1 pom.xml

其中的 spring-cloud-starter-eureka 已废弃(Deprecated),要手工改为 spring-cloud-starter-netflix-eureka-client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>

<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR1</spring-cloud.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

2.2.2 application.properties

  • 指定“服务提供者”的端口号为 8061;
  • 服务提供者的名称为 spring-cloud-provider,将来 spring-cloud-consumer 以该名称调用该服务;
  • 必须指定“服务注册中心”的地址 eureka.client.serviceUrl.defaultZone
    1
    2
    3
    server.port=8061
    spring.application.name=spring-cloud-provider
    eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/

2.2.3 SpringCloudProviderController.java

实现了两个URL:

  • /add: 服务提供者的 add 方法的具体实现;
  • /info: 在“服务注册中心”控制台中有“服务提供者”的链接,用来查看服务提供者的信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@RestController // 指定数据格式为 JSON(Apache Jackson)
public class SpringCloudProviderController {
@Resource
private DiscoveryClient discoveryClient; // of org.springframework

@RequestMapping(value = "/add", method = RequestMethod.GET)
public Integer add(@RequestParam Integer a, @RequestParam Integer b) {
Integer result = a + b;
return result;
}

@GetMapping("/info")
public Map<String, Object> info() {
Map<String, Object> map = new LinkedHashMap<>();
List<String> serviceNames = discoveryClient.getServices();
for (String serviceName : serviceNames) {
List<String> uris = new LinkedList<>();
for (ServiceInstance instance : discoveryClient.getInstances(serviceName)) {
uris.add(instance.getUri().toASCIIString());
}
map.put(serviceName, uris);
}
return map;
}
}

2.2.4 SpringCloudProviderApplication.java

增加注解 @EnableDiscoveryClient 激活 Eureka 中的 DiscoveryClient 实现(SpringCloudProviderController 要用)。

2.2.5 运行

运行 SpringCloudProviderApplication.java

1
2
3
4
5
6
7
8
### spring-cloud-provider 日志(向注册中心注册服务)
10:13:36.707 INFO [DiscoveryClient.java:804] - DiscoveryClient_SPRING-CLOUD-PROVIDER/192.168.1.101:spring-cloud-provider:8061: registering service...
10:13:36.878 INFO [DiscoveryClient.java:813] - DiscoveryClient_SPRING-CLOUD-PROVIDER/192.168.1.101:spring-cloud-provider:8061 - registration status: 204
10:13:36.925 INFO [StartupInfoLogger.java:57] - Started SpringCloudProviderApplication in 8.455 seconds (JVM running for 9.204)

### spring-cloud-registry 日志(服务提供者 SPRING-CLOUD-PROVIDER 的注册信息)
10:13:36.909 INFO [AbstractInstanceRegistry.java:267] - Registered instance SPRING-CLOUD-PROVIDER/192.168.1.101:spring-cloud-provider:8061 with status UP (replication=false)
10:13:37.565 INFO [AbstractInstanceRegistry.java:267] - Registered instance SPRING-CLOUD-PROVIDER/192.168.1.101:spring-cloud-provider:8061 with status UP (replication=true)

进入注册中心控制台 http://localhost:8001/
可以看到服务提供者 spring-cloud-provider
也可以点击查看其信息: http://localhost:8061/info

2.3 创建子模块 spring-cloud-consumer(服务消费方)

依赖选择: Cloud Discovery / Eureka Discovery(客户端)

2.3.1 pom.xml

其中的 spring-cloud-starter-eureka 已废弃(Deprecated),要手工改为 spring-cloud-starter-netflix-eureka-client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>

<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR1</spring-cloud.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

2.3.2 application.properties

  • 指定“服务消费者”的端口号为 8081(面向 SpringCloud 外部的 API 端口)
  • 指定“服务消费者”的名称为 spring-cloud-provider
  • 指定“服务注册中心”的地址 eureka.client.serviceUrl.defaultZone
1
2
3
server.port=8081
spring.application.name=spring-cloud-consumer
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/

2.3.3 SpringCloudConsumerController.java

实现了两个URL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@RestController // 指定数据格式为 JSON(Apache Jackson)
public class SpringCloudConsumerController {
@Resource
RestTemplate restTemplate;

@Resource
private DiscoveryClient discoveryClient; // of org.springframework

@RequestMapping(value = "/add", method = RequestMethod.GET)
public Integer add() {
String url = "http://spring-cloud-provider/add?a=10&b=20";
return restTemplate.getForObject(url, Integer.class);
}

@GetMapping("/info")
public Map<String, Object> info() {
Map<String, Object> map = new LinkedHashMap<>();
List<String> serviceNames = discoveryClient.getServices();
for (String serviceName : serviceNames) {
List<String> uris = new LinkedList<>();
for (ServiceInstance instance : discoveryClient.getInstances(serviceName)) {
uris.add(instance.getUri().toASCIIString());
}
map.put(serviceName, uris);
}
return map;
}
}

2.3.4 SpringCloudConsumerApplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
@EnableDiscoveryClient // 激活 Eureka 中的 DiscoveryClient 实现(SpringCloudProviderController 要用)
@SpringBootApplication
public class SpringCloudConsumerApplication {
@Bean // 生成 Bean,SpringCloudConsumerController 中使用
@LoadBalanced // 开启均衡负载
RestTemplate restTemplate() {
return new RestTemplate();
}

public static void main(String[] args) {
SpringApplication.run(SpringCloudConsumerApplication.class, args);
}
}

负载均衡分为两种:

  • 服务端负载均衡:服务清单和功能实现在服务端,位于各服务器节点之前,分为硬件(如F5)和软件(如Nginx)两种形式;
  • 客户端负载均衡:服务清单和功能实现在客户端,比如 SpringCloud 的 Ribbon,Ribbon从注册中心获取服务提供者列表,以轮询的方式向各提供者请求,起到负载均衡效果,SpringCloud 只需以 @LoadBalanced 注解就能实现客户端负载均衡。

2.3.5 运行

运行 SpringCloudConsumerApplication.java

1
2
3
4
5
6
7
8
### spring-cloud-consumer 日志(向注册中心注册服务)
10:27:46.585 INFO [DiscoveryClient.java:804] - DiscoveryClient_SPRING-CLOUD-CONSUMER/192.168.1.101:spring-cloud-consumer:8081: registering service...
10:27:46.647 INFO [DiscoveryClient.java:813] - DiscoveryClient_SPRING-CLOUD-CONSUMER/192.168.1.101:spring-cloud-consumer:8081 - registration status: 204
10:27:46.771 INFO [StartupInfoLogger.java:57] - Started SpringCloudConsumerApplication in 8.371 seconds (JVM running for 10.392)

### spring-cloud-registry 日志(服务消费者 SPRING-CLOUD-CONSUMER 的注册信息)
10:27:46.631 INFO [AbstractInstanceRegistry.java:267] - Registered instance SPRING-CLOUD-CONSUMER/192.168.1.101:spring-cloud-consumer:8081 with status UP (replication=false)
10:27:47.158 INFO [AbstractInstanceRegistry.java:267] - Registered instance SPRING-CLOUD-CONSUMER/192.168.1.101:spring-cloud-consumer:8081 with status UP (replication=true)

进入注册中心控制台 http://localhost:8001/
可以看到服务消费者 spring-cloud-consumer
也可以点击查看其信息: http://localhost:8081/info
打开 SpringCloud 对外的 API 接口,可看到计算结果:http://localhost:8081/add

2.4 辅助脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@echo off & cls

## 编译三个子模块
call mvn.cmd clean package -Dmaven.test.skip=true -f spring-cloud-registry/pom.xml
call mvn.cmd clean package -Dmaven.test.skip=true -f spring-cloud-provider/pom.xml
call mvn.cmd clean package -Dmaven.test.skip=true -f spring-cloud-consumer/pom.xml

start /b java -jar spring-cloud-registry/target/spring-cloud-registry-0.0.1-SNAPSHOT.jar
pause ## 等待 registry 启动完毕后,再按任意键继续

start /b java -jar spring-cloud-provider/target/spring-cloud-provider-0.0.1-SNAPSHOT.jar --server.port=8061
start /b java -jar spring-cloud-provider/target/spring-cloud-provider-0.0.1-SNAPSHOT.jar --server.port=8062
start /b java -jar spring-cloud-provider/target/spring-cloud-provider-0.0.1-SNAPSHOT.jar --server.port=8063
pause ## 等待 provider 启动完毕后,再按任意键继续

start /b java -jar spring-cloud-consumer/target/spring-cloud-consumer-0.0.1-SNAPSHOT.jar
pause ## 任意键继续结束所有程序

编译中可能遇到警告:WARN [URLConfigurationSource.java:121] - No URLs will be polled as dynamic configuration sources.
无需理会,也可以增加空的配置文件来避免:resources/config.properties

3.高可用服务注册中心

  前面的服务注册中心(Eureka Server)是单点的,可能导致单点故障,生产环境应该构建高可用的Eureka Server集群。下面以双节点注册中心为例来构建:

Eureka服务治理体系:

  • 服务注册中心(registry, Eureka Server): 存储各服务提供者,分两层存储,第一层为服务名称,第二层为服务实例名称;
  • 服务提供者(provider, Eureka Client): 发送 REST 请求,将自己注册到 Eureka Server 上;并定时向 Eureka Server 发送心跳包,以告知自己还在运行(称作“服务续约”);当服务提供者正常退出时,会通过 REST 请求告知服务中心,但异常退出时不会(此时由心跳机制弥补)。
  • 服务消费者(consumer, Eureka Client):发送 REST 请求,向注册中心查询当前有效的服务提供者列表,然后直接调用 provider。

相关参数有:

  • 关闭保护机制(配置在注册中心): 关闭后(建议采用此方式),严格以心跳断定服务提供者是否失效,认为失效时直接当作下线,不会采用一定算法的保护机制认为它可能还有效;
  • 提供者列表的刷新间隔(配置在注册中心):默认值为 30(秒),注册中心缓存了一份服务提供者清单,消费者查询时的数据来自该缓存,该参数定义了最新实际有效的提供者列表向缓存更新的时间间隔;
  • 服务失效时间(配置在注册中心): 默认值为 90(秒),注册中心每60秒检查一遍,在90s内没有收到某个服务提供者的心跳包,就把它看作下线,从提供给消费者的列表中剔除;
  • 心跳发送间隔(配置在服务提供者): 默认值为 30(秒),服务提供者每隔这个时间段,就会向注册中心发送心跳包;
    1
    2
    3
    4
    eureka.server.enable-self-preservation=false
    eureka.client.registry-fetch-interval-seconds=30
    eureka.instance.lease-expiration-duration-in-seconds=90
    eureka.instance.lease-renewal-interval-in-seconds=30

当有多个注册中心(集群)时,各服务中心相互注册为服务,只要其中一个注册中心收到服务提供者的注册信息,就会同步给其他的注册中心,以保证任何注册中心的注册表都是完整的。以两个服务中心、两个服务提供者为例,构建方案如下:

3.1 新建 spring-cloud-registry/application-peer1.properties

指定自身端口为 8001,注册中心地址为第二个注册中心(localhost:8002);
开启 eureka.client.register-with-eureka(把自身注册到注册中心),第一个注册中心会注册到第二个注册中心;

1
2
3
4
5
server.port=8001
spring.application.name=spring-cloud-registry
eureka.client.serviceUrl.defaultZone=http://localhost:8002/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=false

3.2 新建 spring-cloud-registry/application-peer2.properties

指定自身端口为 8002,注册中心地址为第一个注册中心(localhost:8001);
开启 eureka.client.register-with-eureka(把自身注册到注册中心),第二个注册中心会注册到第一个注册中心;

1
2
3
4
5
server.port=8002
spring.application.name=spring-cloud-registry
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=false

3.3 新建 spring-cloud-provider/application-peer1.properties

指定注册中心为第一个注册中心(也可以指定为所有注册中心URL列表,以逗号分隔)。
如果指定多个注册中心,那么会逐个尝试注册,一旦有一个注册成功,就不会在向后续注册中心注册。

1
2
3
4
server.port=8061
spring.application.name=spring-cloud-provider
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
## eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/,http://localhost:8002/eureka/

3.4 新建 spring-cloud-provider/application-peer2.properties

指定注册中心为第二个注册中心(也可以指定为所有注册中心URL列表,以逗号分隔)。

1
2
3
4
server.port=8062
spring.application.name=spring-cloud-provider
eureka.client.serviceUrl.defaultZone=http://localhost:8002/eureka/
## eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/,http://localhost:8002/eureka/

3.5 确认 spring-cloud-consumer/application.properties

指定注册中心为第一个注册中心(也可以指定为所有注册中心URL列表,以逗号分隔)。

1
2
3
4
server.port=8081
spring.application.name=spring-cloud-consumer
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
## eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/,http://localhost:8002/eureka/

3.6 启动所有注册中心和服务提供者、服务消费者

1
2
3
4
5
6
7
java -jar target/spring-cloud-registry-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar target/spring-cloud-registry-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2

java -jar target/spring-cloud-provider-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar target/spring-cloud-provider-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2

java -jar target/spring-cloud-consumer-0.0.1-SNAPSHOT.jar

发现消费者依次调用了两个服务提供者,注册中心同步机制有效,消费者也达到了负载均衡效果。

3.7 查看两个服务中心的控制台

http://localhost:8001/
http://localhost:8002/
发现他们都有两个服务提供者,都是完整的。

文章目录
  1. 1.概述
    1. 1.1 参考资料
    2. 1.2 Spring Cloud 版本
    3. 1.3 各类生态组件
    4. 1.4 SpringCloud 与 Dubbo/Dubbox 的比较
  2. 2.使用实例(基于 IntelliJ IDEA)
    1. 2.0 创建父项目 spring-cloud-demo
    2. 2.1 创建子模块 spring-cloud-registry(服务注册中心)
      1. 2.1.1 pom.xml
      2. 2.1.2 application.properties
      3. 2.1.3 SpringCloudRegistryApplication.java
      4. 2.1.4 运行
    3. 2.2 创建子模块 spring-cloud-provider(服务提供方)
      1. 2.2.1 pom.xml
      2. 2.2.2 application.properties
      3. 2.2.3 SpringCloudProviderController.java
      4. 2.2.4 SpringCloudProviderApplication.java
      5. 2.2.5 运行
    4. 2.3 创建子模块 spring-cloud-consumer(服务消费方)
      1. 2.3.1 pom.xml
      2. 2.3.2 application.properties
      3. 2.3.3 SpringCloudConsumerController.java
      4. 2.3.4 SpringCloudConsumerApplication.java
      5. 2.3.5 运行
    5. 2.4 辅助脚本
  3. 3.高可用服务注册中心
    1. 3.1 新建 spring-cloud-registry/application-peer1.properties
    2. 3.2 新建 spring-cloud-registry/application-peer2.properties
    3. 3.3 新建 spring-cloud-provider/application-peer1.properties
    4. 3.4 新建 spring-cloud-provider/application-peer2.properties
    5. 3.5 确认 spring-cloud-consumer/application.properties
    6. 3.6 启动所有注册中心和服务提供者、服务消费者
    7. 3.7 查看两个服务中心的控制台