在实际生产中,我们需要高可用的集群方案,本章就是基于SpringBoot1.5.4 Cloud(Dalston.SR2) 的高可用Eureka Cluster,以及生产中需要注意的事项…

- Eureka Cluster

本教程用1个项目(battcn-cloud-discovery),多环境方式演示

- pom.xml

1
2
3
4
5
6
7
8
9
10
11
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

- Application.java

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableEurekaServer
public class BattcnCloudDiscoveryApplication { public static void main(String[] args) {
SpringApplication.run(BattcnCloudDiscoveryApplication.class, args);
}
}

- application.yml

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
33
34
35
36
37
38
39
40
41
42
43
44
server:
port: 8761
spring:
profiles:
active: peer2
#官方写的就是 8761
---
spring:
profiles: peer1
application:
name: Eureka-Server-1
eureka:
instance:
hostname: peer1
#配置主机名
client:
register-with-eureka: false
#配置服务注册中心是否以自己为客户端进行注册(配置false)
fetch-registry: false
#是否取得注册信息(配置false)
service-url:
defaultZone: http://peer2:7002/eureka/
#defaultZone 一定要按照标准写法,因为service-url的数据类型是Map 这算是个小坑需要注意
server:
port: 7001
---
spring:
profiles: peer2
application:
name: Eureka-Server-1
eureka:
instance:
hostname: peer2
#配置主机名
client:
register-with-eureka: false
#配置服务注册中心是否以自己为客户端进行注册(配置false)
fetch-registry: false
#是否取得注册信息(配置false)
service-url:
defaultZone: http://peer1:7001/eureka/
server:
port: 7002
#defaultZone 一定要按照标准写法,因为service-url的数据类型是Map 这算是个小坑需要注意

- 启动集群

命令:mvn clean package (先打成jar包)

1
2
peer1:java -jar battcn-cloud-discovery.jar --spring.profiles.active=peer1
peer2:java -jar battcn-cloud-discovery.jar --spring.profiles.active=peer2

1.点击蓝色加号
2.点击Spring Boot
3.填写 Name:peer1 Program arguments:–spring.profiles.active=peer1(启动2个操作2次,记得改名字和激活环境,Eclipse太简单了application.yml 直接修改内容启动就行了)

启动多个

启动成功分别访问

1
http://peer1:7001

peer1

1
http://peer2:7002

peer2

如出现上图所示,代表我们集群启动成功

- 高可用测试

1.创建battcn-cloud-h1 和 battcn-cloud-h2 2个项目,基本大同小异

就这2个包够了,跟 h1 代码唯一的区别就是 h2 做调用 h1写好接口就行了

- pom.xml

1
2
3
4
5
6
7
8
9
10
11
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

- application.yml

1
2
3
4
5
6
7
8
9
10
11
12
server:	
port: 7012
spring:
application:
name: battcn-cloud-h2 eureka:
instance:
hostname: localhost #配置主机名
client:
service-url:
defaultZone: http://peer1:7001/eureka/,http://peer2:7002/eureka/ #配置Eureka Server

- H2Application.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class H2Application { static Logger LOGGER = LoggerFactory.getLogger(H2Application.class); @Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
} @RequestMapping("/h2")
public String home(@RequestParam String email) {
// 改写法之前有说过是VIP模式
return restTemplate().getForObject("http://battcn-cloud-h1/h1?email=" + email, String.class);
} public static void main(String[] args) {
SpringApplication.run(H2Application.class, args);
}
}

- 测试

分别启动 battcn-cloud-h1 和 battcn-cloud-h2

服务注册

访问:http://localhost:7012/h2?email=1837307557@qq.com

浏览器:My Name's :battcn-cloud-h1 Email:1837307557@qq.com 代表请求成功,然后我们断掉 peer1 或者 peer2 继续请求依旧可用,只是日志会抛异常,通过日志我们可以发现peer2 time out 因为它被杀掉了,但是这并不影响我们服务调用(高可用),只要在启动peer2 错误就不会在出现,在生产中如果集群都挂了 直接 运维下岗就是了(如果peer1 peer2同时挂掉,在启动服务会自动注册上去.)

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
2017-07-31 23:01:03.314 ERROR 14792 --- [-target_peer2-8] c.n.e.cluster.ReplicationTaskProcessor   : Network level connection to peer peer2; retrying after delay

com.sun.jersey.api.client.ClientHandlerException: org.apache.http.conn.ConnectTimeoutException: Connect to peer2:7002 timed out
at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187) ~[jersey-apache-client4-1.19.1.jar:1.19.1]
at com.netflix.eureka.cluster.DynamicGZIPContentEncodingFilter.handle(DynamicGZIPContentEncodingFilter.java:48) ~[eureka-core-1.6.2.jar:1.6.2]
at com.netflix.discovery.EurekaIdentityHeaderFilter.handle(EurekaIdentityHeaderFilter.java:27) ~[eureka-client-1.6.2.jar:1.6.2]
at com.sun.jersey.api.client.Client.handle(Client.java:652) ~[jersey-client-1.19.1.jar:1.19.1]
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682) ~[jersey-client-1.19.1.jar:1.19.1]
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) ~[jersey-client-1.19.1.jar:1.19.1]
at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570) ~[jersey-client-1.19.1.jar:1.19.1]
at com.netflix.eureka.transport.JerseyReplicationClient.submitBatchUpdates(JerseyReplicationClient.java:116) ~[eureka-core-1.6.2.jar:1.6.2]
at com.netflix.eureka.cluster.ReplicationTaskProcessor.process(ReplicationTaskProcessor.java:71) ~[eureka-core-1.6.2.jar:1.6.2]
at com.netflix.eureka.util.batcher.TaskExecutors$BatchWorkerRunnable.run(TaskExecutors.java:187) [eureka-core-1.6.2.jar:1.6.2]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
Caused by: org.apache.http.conn.ConnectTimeoutException: Connect to peer2:7002 timed out
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:123) ~[httpclient-4.5.3.jar:4.5.3]
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180) ~[httpclient-4.5.3.jar:4.5.3]
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144) ~[httpclient-4.5.3.jar:4.5.3]
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134) ~[httpclient-4.5.3.jar:4.5.3]
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610) ~[httpclient-4.5.3.jar:4.5.3]
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445) ~[httpclient-4.5.3.jar:4.5.3]
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835) ~[httpclient-4.5.3.jar:4.5.3]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:118) ~[httpclient-4.5.3.jar:4.5.3]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) ~[httpclient-4.5.3.jar:4.5.3]
at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:173) ~[jersey-apache-client4-1.19.1.jar:1.19.1]
... 10 common frames omitted

- 注意事项

EurekaClientConfigBean.java 默认构造方法,如果serviceUrl.defaultZone = null 那么 就注册到 http://localhost:8761/eureka/ 中去(日志会输出改地址,起初我是看的一脸懵逼),所以其他的Key都可以以 杠(-) 或者全大写方式,该处不行,因为人家源码是Map不是对象

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public EurekaClientConfigBean() {
this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");
this.gZipContent = true;
this.useDnsForFetchingServiceUrls = false;
this.registerWithEureka = true;
this.preferSameZoneEureka = true;
this.availabilityZones = new HashMap();
this.filterOnlyUpInstances = true;
this.fetchRegistry = true;
this.dollarReplacement = "_-";
this.escapeCharReplacement = "__";
this.allowRedirects = false;
this.onDemandUpdateStatusChange = true;
this.clientDataAccept = EurekaAccept.full.name();
} public String[] getAvailabilityZones(String region) {
String value = (String)this.availabilityZones.get(region);
if(value == null) {
value = "defaultZone";
} return value.split(",");
} public List<String> getEurekaServerServiceUrls(String myZone) {
String serviceUrls = (String)this.serviceUrl.get(myZone);
if(serviceUrls == null || serviceUrls.isEmpty()) {
serviceUrls = (String)this.serviceUrl.get("defaultZone");
} if(!StringUtils.isEmpty(serviceUrls)) {
String[] serviceUrlsSplit = StringUtils.commaDelimitedListToStringArray(serviceUrls);
List<String> eurekaServiceUrls = new ArrayList(serviceUrlsSplit.length);
String[] var5 = serviceUrlsSplit;
int var6 = serviceUrlsSplit.length; for(int var7 = 0; var7 < var6; ++var7) {
String eurekaServiceUrl = var5[var7];
if(!this.endsWithSlash(eurekaServiceUrl)) {
eurekaServiceUrl = eurekaServiceUrl + "/";
} eurekaServiceUrls.add(eurekaServiceUrl);
} return eurekaServiceUrls;
} else {
return new ArrayList();
}
}

- 小谈

其实我是比较倾向于 consul 这种零侵入式的,但是consul 在做高可用比较操蛋,它对外暴露的是 agent 如果你这个 agent挂了,那么后面服务就GG思密达了,cloud service 不允许配置多个agent,个人没找到好的解决方案,有好方案的可以交流…..

高可用服务注册中心(Eureka-Cluster)的更多相关文章

  1. 使用Spring Cloud搭建高可用服务注册中心

    我们需要的,不仅仅是一个服务注册中心而已,而是一个高可用服务注册中心. 上篇博客[使用Spring Cloud搭建服务注册中心]中我们介绍了如何使用Spring Cloud搭建一个服务注册中心,但是搭 ...

  2. 使用SpringCloud搭建高可用服务注册中心

    我们需要的,不仅仅是一个服务注册中心而已,而是一个高可用服务注册中心. 上篇博客中我们介绍了如何使用Spring Cloud搭建一个服务注册中心,但是搭建好的服务注册中心是一个单节点的服务注册中心,这 ...

  3. 搭建高可用服务注册中心-Spring Cloud学习第一天(非原创)

    文章大纲 一.Spring Cloud基础知识介绍二.创建单一的服务注册中心三.创建一个服务提供者四.搭建高可用服务注册中心五.项目源码与参考资料下载六.参考文章   一.Spring Cloud基础 ...

  4. 服务注册发现Eureka之二:高可用服务注册中心

    前言 在Spring Cloud系列文章的开始,我们就介绍了服务注册与发现,其中,主要演示了如何构建和启动服务注册中心Eureka Server,以及如何将服务注册到Eureka Server中,但是 ...

  5. SpringCloud学习系列之一 ----- 搭建一个高可用的注册中心(Eureka)

    前言 本篇主要介绍的是SpringCloud相关知识.微服务架构以及搭建一个高可用的服务注册与发现的服务模块(Eureka). SpringCloud介绍 Spring Cloud是在Spring B ...

  6. SpringCloud学习成长之 十 高可用服务注册中心

    文章 第一篇: 服务的注册与发现(Eureka) 介绍了服务注册与发现,其中服务注册中心Eureka Server,是一个实例,当成千上万个服务向它注册的时候,它的负载是非常高的,这在生产环境上是不太 ...

  7. spring cloud 入门系列三:使用Eureka 搭建高可用服务注册中心

    在上一篇中分享了如何使用Eureka 进行服务治理,里面搭建的服务注册中心是单体的, 但是在实际的应用中,分布式系统为了防止单体服务宕机带来严重后果,一般都会采用服务器集群的形式,服务注册中心也是一样 ...

  8. springboot+cloud 学习(一)高可用服务注册中心(Eureka)

    先说说Eureka Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的.SpringClo ...

  9. Spring Cloud Eureka 4 (高可用服务注册中心)

    在微服务这样的分布式环境中,我们需要充分考虑发生故障的情况,所以在生产环境中必须考虑对各个组件进行高可用部署,对于服务注册中心也是一样. Eureka Server 的高可用实际上就是讲自己作为服务向 ...

随机推荐

  1. Java实现 LeetCode 710 黑名单中的随机数(黑白名单)

    710. 黑名单中的随机数 给定一个包含 [0,n ) 中独特的整数的黑名单 B,写一个函数从 [ 0,n ) 中返回一个不在 B 中的随机整数. 对它进行优化使其尽量少调用系统方法 Math.ran ...

  2. (Java实现) 过河卒

    过河卒 题目描述 棋盘上AA点有一个过河卒,需要走到目标BB点.卒行走的规则:可以向下.或者向右.同时在棋盘上CC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为&q ...

  3. Java实现 LeetCode 698 划分为k个相等的子集(递归)

    698. 划分为k个相等的子集 给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等. 示例 1: 输入: nums = [4, 3, 2, 3, ...

  4. Java实现 蓝桥杯VIP 算法训练求先序排列

    问题描述 给出一棵二叉树的中序与后序排列.求出它的先序排列.(约定树结点用不同的大写字母表示,长度<=8). 输入格式 两行,每行一个字符串,分别表示中序和后序排列 输出格式 一个字符串,表示所 ...

  5. java实现和为定值的两个数

    1 问题描述 输入一个整数数组和一个整数,在数组中查找两个数,满足他们的和正好是输入的那个整数.如果有多对数的和等于输入的整数,输出任意一对即可.例如,如果输入数组[1,2,4,5,7,11,15]和 ...

  6. java实现显示为树形

    ** 显示为树形** 树形结构应用十分广泛. 下面这段代码根据用户添加的数据,在内存中构建一个逻辑上等价的树形结构. 通过ShowTree() 可以把它显示为控制中的样子. 其中: a.add('a' ...

  7. Java实现串的简单处理

    串的处理 在实际的开发工作中,对字符串的处理是最常见的编程任务.本题目即是要求程序对用户输入的串进行处理.具体规则如下: 把每个单词的首字母变为大写. 把数字与字母之间用下划线字符(_)分开,使得更清 ...

  8. ReentrantLock原理分析

    一 UML类图 通过类图ReentrantLock是同步锁,同一时间只能有一个线程获取到锁,其他获取该锁的线程会被阻塞而被放入AQS阻塞队列中.ReentrantLock类继承Lock接口:内部抽象类 ...

  9. MongoDB知识点总结

    一:MongoDB 概述    一.NoSQL 简介 1. 概念:NoSQL(Not Only SQL的缩写),指的是非关系型数据库,是对不同于传统的关系型数据库的数据库管理系统的统称.用于超大规模数 ...

  10. 若linux 的分区硬盘满,如何处理?

    一.确定是不是真的是磁盘空间不足 输入命令:df –lh 查看磁盘信息 二.如何定位最大文件目录 输入命令:cd / 进入根目录. 输入命令:du -h max-depth=1 寻找当前目录,哪个文件 ...