在实际生产中,我们需要高可用的集群方案,本章就是基于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 直接修改内容启动就行了)
启动多个
启动成功分别访问
peer1
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,个人没找到好的解决方案,有好方案的可以交流…..
- 使用Spring Cloud搭建高可用服务注册中心
我们需要的,不仅仅是一个服务注册中心而已,而是一个高可用服务注册中心. 上篇博客[使用Spring Cloud搭建服务注册中心]中我们介绍了如何使用Spring Cloud搭建一个服务注册中心,但是搭 ...
- 使用SpringCloud搭建高可用服务注册中心
我们需要的,不仅仅是一个服务注册中心而已,而是一个高可用服务注册中心. 上篇博客中我们介绍了如何使用Spring Cloud搭建一个服务注册中心,但是搭建好的服务注册中心是一个单节点的服务注册中心,这 ...
- 搭建高可用服务注册中心-Spring Cloud学习第一天(非原创)
文章大纲 一.Spring Cloud基础知识介绍二.创建单一的服务注册中心三.创建一个服务提供者四.搭建高可用服务注册中心五.项目源码与参考资料下载六.参考文章 一.Spring Cloud基础 ...
- 服务注册发现Eureka之二:高可用服务注册中心
前言 在Spring Cloud系列文章的开始,我们就介绍了服务注册与发现,其中,主要演示了如何构建和启动服务注册中心Eureka Server,以及如何将服务注册到Eureka Server中,但是 ...
- SpringCloud学习系列之一 ----- 搭建一个高可用的注册中心(Eureka)
前言 本篇主要介绍的是SpringCloud相关知识.微服务架构以及搭建一个高可用的服务注册与发现的服务模块(Eureka). SpringCloud介绍 Spring Cloud是在Spring B ...
- SpringCloud学习成长之 十 高可用服务注册中心
文章 第一篇: 服务的注册与发现(Eureka) 介绍了服务注册与发现,其中服务注册中心Eureka Server,是一个实例,当成千上万个服务向它注册的时候,它的负载是非常高的,这在生产环境上是不太 ...
- spring cloud 入门系列三:使用Eureka 搭建高可用服务注册中心
在上一篇中分享了如何使用Eureka 进行服务治理,里面搭建的服务注册中心是单体的, 但是在实际的应用中,分布式系统为了防止单体服务宕机带来严重后果,一般都会采用服务器集群的形式,服务注册中心也是一样 ...
- springboot+cloud 学习(一)高可用服务注册中心(Eureka)
先说说Eureka Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的.SpringClo ...
- Spring Cloud Eureka 4 (高可用服务注册中心)
在微服务这样的分布式环境中,我们需要充分考虑发生故障的情况,所以在生产环境中必须考虑对各个组件进行高可用部署,对于服务注册中心也是一样. Eureka Server 的高可用实际上就是讲自己作为服务向 ...
随机推荐
- Java实现 LeetCode 263 丑数
263. 丑数 编写一个程序判断给定的数是否为丑数. 丑数就是只包含质因数 2, 3, 5 的正整数. 示例 1: 输入: 6 输出: true 解释: 6 = 2 × 3 示例 2: 输入: 8 输 ...
- java实现拼出漂亮的表格
/* * 在中文 Windows 环境下,控制台窗口中也可以用特殊符号拼出漂亮的表格来. 比如: ┌─┬─┐ │ │ │ ├─┼─┤ │ │ │ └─┴─┘ 其实,它是由如下的符号拼接的: 左上 = ...
- ReentrantReadWriteLock(读写锁)全部源码注释
package java.util.concurrent.locks; import java.util.concurrent.TimeUnit; import java.util.Collectio ...
- 重学 Java 设计模式:实战桥接模式(多支付渠道「微信、支付宝」与多支付模式「刷脸、指纹」场景)
作者:小傅哥 博客:https://bugstack.cn - 编写系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 为什么你的代码那么多ifelse 同类的业务.同样的功能, ...
- gitee+picgo搭建个人博客图床
gitee+picgo搭建个人博客图床 准备 首先需要去码云注册一个账号,并新建一个仓库.接着下载PicGO并安装好. 过程 点击左下方的插件设置. image 在搜索框中输入gitee搜索插件,安装 ...
- 链家网 + gevent
import gevent from gevent import monkey monkey.patch_all() from gevent.queue import Queue import tim ...
- ubuntu12.04 qtcreate支持中文输入
1.sudo apt-get install ibus-qt4 2.重启电脑 reboot
- Ubuntu安装protobuf步骤
1.从谷歌官网获取源码 protobuf-2.4.1.tar.gz 2.解压 tar -zxvf protobuf-2.4.1.tar.gz 3.配置 ./configure 4.编译 make 5. ...
- 并行处理框架Celery的Web监控管理服务-Flower
安装和使用 使用pip安装Flower: $ pip install flower或 pip install flower -U -i https://pypi.tuna.tsinghua.edu.c ...
- iphone手机卡顿解决方案
一.清除 safari缓存 设置->safari浏览器->清除历史记录与网站数据