我们搭建了一个Eureka服务注册中心,就是Eureka Server,他提供了服务的注册和发现,那么其实对于Eureka服务注册
中心来讲,我们整个微服务开发当中,它是一个非常重要的环节,我们所有的服务都是依赖于这个服务注册中心,来注册的,
所以一旦他出现问题了,势必会影响其他服务的运行,所以我们实际在使用Eureka服务注册中心的时候,我们会想到将来
会有单点故障的问题,那么怎么解决这种单点故障呢,我们肯定要搭建高可用的,那么所谓的高可用是什么含义呢,其实就是
搭建Eureka集群,那么我们再来讲解一下,如何去搭建Eureka集群,首先我们先来创建一个项目,创建一个Eureka注册中心,
我们把上一节的项目,拷贝,然后我们给他起个名字,加一个ha
springcloud-eureka-server-ha
我们再去修改一下他的pom文件,把这里的artifactId和Name改一下,这样一个项目就创建好了,我们先说一下Eureka的高可用
注册中心,它是一个什么样的运行原理,现在我要把这个注册中心,部署到多态物理节点上,让他们形成一个集群,那么集群当中的
多个节点,是要相互通信的,那么我们如何去搭建或者编写集群版的Eureka呢,也非常简单,每一个实例,他都需要加载自己的配置
文件,根据配置文件里配置的一些信息,来与其他节点进行通信,那么这里就用到哪个技术呢,我们之前讲SpringBoot实战的时候,
讲过springboot的一个配置文件的多环境的配置,我们这里就需要用到这样的一个技术了,虽然在同一个项目当中,但是我们会给他
建立不同的配置文件,然后未来每个实例在自己的环境当中,去加载自己的配置文件,这样每个实例在解析自己的配置文件的时候,
可以拿到其他节点的配置信息,这样我们每一个节点就串联起来了,其实SpringCloud,他也意识到这个问题了,也就是说什么呢,
Eureka注册中心未来必须得保证它是高可用的,所以他在集群的搭建过程当中,在代码这一层次,为我们做了一个很好地封装,也就是
我们现在要搭建一个Eureka的注册中心的集群,非常的容易,我们只要在配置文件里,去为每个节点做相应的配置就可以了,那么接下来
我们就来完成代码的编写,首先我们本次案例,做两个节点的一个集群,当然做三个,做四个,做五个,跟两个没有太大的区别,只是配置
文件会多一些,配置项会多一些,仅此而已,我们项目构建好了,然后接下来我们来编写他的配置文件,首先配置文件,我们只有一个了,
刚刚我提到过,每个配置文件,对应这一个实例,表示每个物理节点下的启动时都要加载属于自己的配置文件,所以我们要给他创建
多个配置文件,我们给配置文件加个后缀,融入多环境配置就可以了,比如这个叫eureka1
application-eureka1.properties
然后这个叫eureka2
application-eureka2.properties
当然如果你要做多节点,拷贝多份就可以了,打开配置文件,我们来看一下,这是在我们原来项目当中拷贝过来的,配置当前服务的
名称,这两个是单击注册中心的时候
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
避免自己在自己服务里注册,这个我们可以去掉,我们需要加上,但是呢,在eureka集群当中,这个是可加可不加的,如果你要不加,
什么意思呢,你要把他去掉,将来在服务注册列表,显示服务注册的列表当中,我们就看不到了,这个表示不让自己注册了,如果你要
把他去掉呢,那未来在集群当中,集群当中一旦启动了,在管理界面是可以看到已注册的服务,服务本身也注册了,那为什么在集群下
不加他也可以启动呢,由于它有多个节点,我不能在自己注册,但是我可以在其他节点注册,是不是,但是单机版为什么要加他,因为
单机版只有他自己,不能在你自己这里注册,这是集群和单击的区别,那么假设就把它去掉,允许他注册,只不过然他在其他节点上注册
不就可以了,把它去掉,我们再来看,首先在eureka1这个节点里,对于名字我们就不用改,我们都叫eureka-server没有问题
spring.application.name=eureka-server
然后端口我们都让他监听8761,那有人会说,不会的,我们在部署的时候,模拟真实的生产环境,也就是说,我会给大家装两台虚拟机,
这样两台虚拟机的IP已经是不同的了,所以并不需要监听不同的端口了,当然你也可以在一个设备上,一个物理节点上,运行,但是在
一个物理节点上,你的端口是有强占性的,因为IP是相同的,所以你需要把端口改变一下,那么我们之所以要部署在两条虚拟机上呢,
原因是尽量的模拟生产环境来演示,明白我的意思吧,那么接下来我们在配置文件里要加什么呢,在笔记里已经写了,我们把这两个
拿过来
eureka.instance.hostname=eureka1
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/
只要在配置文件里加这两个就可以了,我们来说一下这是什么意思,eureka.instance.hostname=eureka1这个是给你的主机名设置
一个名称,那么这个主机名的作用是什么呢,就是你这个实例的主机名,未来我们说到,集群节点和节点之间是要通信的,那么通信
要知道怎么去访问你这个节点,默认的都是用域名来访问的,所以我们给他起一个hostname,然后这一块,我后面加了一句话,与配置
文件的变量名为主,这个是什么意思呢,一般我们这个主机名呢,我们会以配置文件的后面的名称作为主机名,这样的好处就是我们
未来要看配置文件,我一看域名就知道,他指向的是哪个配置文件,现在是哪个实例,去访问哪个实例,所以我们一般会以他为主,
那么现在在我的eureka1当中,hostname应该叫eureka1,相当于给我们起了一个域名,然后再往下看,这个设置,这个是设置服务注册
中心地址指向另一个注册中心,也就是你这两个节点要通信,我要知道另一个注册中心的地址,那么这个就是设置他的注册地址,
那么在这个访问地址当中,需要注意的是这一块,首先是你要访问的另一个节点,端口是多少,我们未来这个放到另外一个地址下,
肯定会加载这个配置文件,那么他监听的也是8761,这是另外一个节点的域名,我们可以先把他拿过来
eureka.instance.hostname=eureka2
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/
然后这个就叫eureka2,他的hostname就叫eureka2就可以了,我未来跟你通信,访问他的时候是不是要交eureka2:8761,这样才能
加载未来这个配置文件的实例,回过来在eureka2的配置文件里,他的主机名是eureka2,那么未来他要和加载了eureka1的通信,
他的地址里是不是应该是eureka1,这样两个实例在加载两个配置文件以后,两个节点通过配置的这个信息,是不是就可以知道地址
响应通信了,所以这块我们应该能理解吧,这样我们eureka服务注册中心就搭建好了,我们先把笔记整理一下,在搭建Eureka集群时,
需要添加多个配置文件,并且使用SpringBoot的多环境配置,集群中需要多少节点,就添加多少个配置文件,这是一个需要注意的地方,
在配置文件当中,配置集群节点,eureka1,这是我们第一个,然后还有一个是eureka2,然后我们把配置文件copy过来,这是eureka1的,
然后这是eureka2的,我们项目最好要把日志加进来,因为我们在启动的时候,对于启动的时候是否有问题,我们只要把logback的配置
文件,放到resources目录下就可以了,我们去找一下logback配置文件,在我这里正好有一个,拿过来,放到我们的resources目录下,
其它的什么都不用动,这样我们一个集群版的eureka就搭建完毕了,添加logback日志文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.learn.cloud</groupId>
<artifactId>springcloud-eureka-server-ha</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.12.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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<!-- 这个插件,可以将应用打包成一个可执行的jar包 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring.application.name=eureka-server
server.port=8761
eureka.instance.hostname=eureka1
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/
spring.application.name=eureka-server
server.port=8761
eureka.instance.hostname=eureka2
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="${catalina.base}/logs/" />
<!-- 控制台输出 -->
<appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="DEBUG">
<appender-ref ref="Stdout" />
<appender-ref ref="RollingFile" />
</root>
<!--日志异步到数据库 -->
<!-- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
日志异步到数据库
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
连接池
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
<user>root</user>
<password>root</password>
</dataSource>
</connectionSource>
</appender> -->
</configuration>
package com.learn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaHAApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaHAApplication.class, args);
}
}