天天看點

eureka叢集高可用配置[通俗易懂]

大家好,又見面了,我是你們的朋友全棧君。

網上講這個東西的很多,抄來抄去的,大部分類似,多數沒講明白為什麼那麼配置。

譬如eureka.client.register-with-eureka和fetch-registry是否要配置,配不配差別在哪裡;eureka的用戶端添加service-url時,是不是需要把所有的eureka的server位址都寫上,還是隻需要寫一個server就可以了(因為server之間已經互相注冊了)?如果寫上了所有的server位址,那相當于将每個client服務都往所有的server都添加了一遍,那還配置server間的互相注冊有什麼意義?

上面的這些問題在多數講eureka叢集教程裡都沒有說明白,上來就是配server互相注冊,client添加所有的server位址,大大的誤導了我一把。專門從頭建立了項目來看看到底eureka叢集是該怎麼配置。

server端配置

建立個eureka server項目

pom.xml如下:

<?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.tianyalei</groupId>
	<artifactId>eureka_server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>eureka_server</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.7.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>
		<spring-cloud.version>Dalston.SR4</spring-cloud.version>
	</properties>

	<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-web</artifactId>
		</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-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>           

複制

application.yml如下

spring:
  application:
    name: eureka
  profiles:
    active: server1           

複制

我用同一個項目打算啟動兩個server服務,占用不同的端口,以此模拟eureka服務叢集。

添加了一個application-server1.yml

server:
  port: 20001
eureka:
  instance:
    hostname: server1
  client:
    # 表示是否注冊自身到eureka伺服器
    # register-with-eureka: false
    # 是否從eureka上擷取注冊資訊
    # fetch-registry: false
    service-url:
      defaultZone: http://server2:20002/eureka/           

複制

再添加一個application-server2.yml

server:
  port: 20002
eureka:
  instance:
    hostname: server2
  client:
    #register-with-eureka: false
    #fetch-registry: false
    service-url:
      defaultZone: http://server1:20001/eureka/           

複制

可以看到我指定了不同的端口,并且service-url這裡是重點,我将server1的service-url設定為server2,将server2的設定為server1.以此完成兩個server服務間的互相注冊,這和别的文章裡講的是一樣的,照着敲就OK。還有我把register和fetch那兩個配置注釋掉了,後面我們會放開,看看有沒有這個配置的差別。

instance.hostname是唯一辨別。

由于我們使用了http://server1這種寫法,需要配一下host。Windows的host在/etc/host,mac的在/private/etc

eureka叢集高可用配置[通俗易懂]

然後在啟動類上加上EnableEurekaServer注解即可。

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

複制

下面我們來看如何分别用server1和server2兩個配置啟動兩個server服務。

在idea右上角run,選擇edit configrations

eureka叢集高可用配置[通俗易懂]
eureka叢集高可用配置[通俗易懂]

原本應該隻有一個啟動項,點選+号,給兩個啟動項都設定一下Program arguments,就是–spring.profiles.active分别設定為server1和server2,代表分别以兩個不同的配置來啟動項目。

然後把兩個啟動項都啟動起來,分别通路各自的端口

eureka叢集高可用配置[通俗易懂]
eureka叢集高可用配置[通俗易懂]

可以看到圖上registered-replicas和available-replicas分别有了對方的位址。

eureka服務端的配置就這樣就OK了。

client端配置

建立一個eureka client項目。

pom如下

<?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.tianyalei</groupId>
	<artifactId>eureka_client</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>eureka_client</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.7.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>
		<spring-cloud.version>Dalston.SR4</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</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-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>           

複制

application.yml如下

spring:
  application:
    name: eureka_client
eureka:
  client:
    service-url:
      defaultZone: http://server1:20001/eureka/           

複制

defaultZone這裡代表eureka server的位址,很多文章在這裡會将所有的server都配置上去,用逗号分隔,我們這裡隻配置一個server1,然後測試一下如果server1挂掉了,服務中心還能不能起作用。

在啟動類上加注解eurekaClient注解

@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {

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

複制

然後啟動項目

再看看server端的界面

eureka叢集高可用配置[通俗易懂]
eureka叢集高可用配置[通俗易懂]

可以看到eureka_client已經在兩個server上都注冊上了,雖然我們在client的yml裡default_zone隻配置了server1。這是因為eureka是通過在各個節點進行複制來達到高可用的目的。

測試很簡單,我們直接關掉server1,然後看看server2是否還能維持住client的發現。

關掉server1,20001的網頁已經打不開了,20002上也已經沒有了20001的服務發現,控制台在一直報錯。

eureka叢集高可用配置[通俗易懂]
eureka叢集高可用配置[通俗易懂]

但是我們看到client的注冊資訊還在,這說明server2還能繼續提供注冊發現的服務,這樣就避免了單點故障後的整體服務發現的癱瘓。

但是需要注意的是,因為大家都在server1進行的注冊,如果server1挂掉了,那麼後續的client就無法再注冊上來,重新開機Client後也無法再注冊到eureka上來。

這就是為什麼很多人在Client端添加多個eureka位址的原因!是避免自己注冊的eureka單點挂掉。隻要自己注冊的eureka還在,那麼後續添加N個eureka的其他server,所有注冊資訊都會被複制過去。

而事實上,eureka的注冊資訊不僅僅複制在server端,也會複制到client端。也就是說,即便eureka的server全部挂掉,client間任然是可以互通的!譬如client1 client2都已經注冊在了server1 server2上,即便server1 server2全死掉了,Client1還是可以和client2進行互通,因為eureka的用戶端也會複制所有的注冊資訊,當server全死掉後,用戶端會根據自己本地的備份進行連接配接。

下面我們可以測試一下把server端yml裡配置register-with-eureka: false的那兩行注釋給放開,看看eureka的server忽略自己後,是否能完成服務發現的高可用。

測試很簡單,可以看到和上面的最終結果是一樣的,都是server1關閉後,server2依舊能進行client的發現。差別在于

eureka叢集高可用配置[通俗易懂]

這個就是和之前注釋掉後界面不同的地方。

至于在client端配置所有的server位址,各位可以自行嘗試。

釋出者:全棧程式員棧長,轉載請注明出處:https://javaforall.cn/130246.html原文連結:https://javaforall.cn