SpringCloud 第十篇: 高可用的服务注册中心

时间:2022-09-17 01:24:30

前言:

必需学会SpringBoot基础知识

简介:

spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。

工具:

JDK8

apache-maven-3.5.2

IntelliJ IDEA 2017.3 x64

 

文章 SpringCloud 教程 第一篇: 服务的注册与发现(Eureka) 介绍了服务注册与发现,其中服务注册中心Eureka Server,是一个实例,当成千上万个服务向它注册的时候,它的负载是非常高的,这在生产环境上是不太合适的,这篇文章主要介绍怎么将Eureka Server集群化。

                              SpringCloud 第十篇: 高可用的服务注册中心

一、准备工作

创建三个实例:

  1. eureka-server-peer1
  2. eureka-server-peer2
  3. eureka-server-peer3

 

二、Code.View

2.0 peer*
<?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.lwc</groupId>
    <artifactId>eureka-server-peer1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>eureka-server-peer1</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.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>Edgware.SR3</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-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>

2.1 peer1
package com.lwc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author Eddie
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerPeer1Application {

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

server:
  port: 8861
spring:
  application:
      name: eureka-server-peer1
  profiles:
    active: peer1
eureka:
  instance:
    hostname: eureka-server-peer1
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://eureka-server-peer2:8862/eureka/,http://eureka-server-peer3:8863/eureka/
2.2 peer2
package com.lwc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author Eddie
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerPeer2Application {

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

server:
  port: 8862
spring:
  application:
      name: eureka-server-peer2
  profiles:
    active: peer2
eureka:
  instance:
    hostname: eureka-server-peer2
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://eureka-server-peer2:8861/eureka/,http://eureka-server-peer3:8863/eureka/
2.3 peer3
package com.lwc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author Eddie
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerPeer3Application {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerPeer3Application.class, args);
    }
}
server:
  port: 8863
spring:
  application:
      name: eureka-server-peer3
  profiles:
    active: peer3
eureka:
  instance:
    hostname: eureka-server-peer3
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://eureka-server-peer2:8862/eureka/,http://eureka-server-peer3:8861/eureka/
2.4 改造 eureka-client
package com.lwc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author eddie.lee
 * @Package com.lwc.controller
 * @ClassName EurekaClientController
 * @description
 * @date created in 2018-03-26 17:19
 * @modified by
 */
@RestController
@RequestMapping("/eureka")
public class EurekaClientController {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/client")
    public String home(@RequestParam String name) {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>(16);
        List<String> stringList = discoveryClient.getServices();
        stringList.forEach(str -> {
            List<ServiceInstance> serviceInstances = discoveryClient.getInstances(str);
            serviceInstances.forEach(ins -> {
                map.put("host", ins.getHost());
                map.put("port", ins.getPort());
                map.put("serviceId", ins.getServiceId());
                map.put("uri", ins.getUri());
                list.add(map);
            });
        });

        String url = null;

        for (Map<String, Object> m : list) {
            for (String k : m.keySet()) {
                System.out.println(k + " : " + m.get(k));
                url = "欢迎点击:  "+m.get("uri") + "/eureka/client?name=" + name;
            }
        }
        return url;
    }

}
eureka:
  client:
    serviceUrl:
      #defaultZone: http://localhost:8761/eureka/
      defaultZone: http://eureka-server-peer1:8861/eureka/
server:
  port: 8762

 

三、测试

启动:

SpringCloud 第十篇: 高可用的服务注册中心

 

访问: http://localhost:8861/

SpringCloud 第十篇: 高可用的服务注册中心

 

最后改造 client 是为了让大家学习一下获取信息,访问:  http://localhost:8762/eureka/client?name=eddie

欢迎点击: http://EDDIE-THINKPAD:8762/eureka/client?name=eddie

 

题外话:

也可以通过原来第一篇的项目结构, 修改配置文件的端口达到效果;

1. 通过Maven打包之后

2. CMD下运行:

java -jar eureka-server-0.0.1-SNAPSHOT.jar - -spring.profiles.active=peer1

java -jar eureka-server-0.0.1-SNAPSHOT.jar - -spring.profiles.active=peer2

3. 在运行:

java -jar eureka-client-0.0.1-SNAPSHOT.jar

技巧:

eureka.instance.preferIpAddress=true是通过设置ip让eureka让其他服务注册它。也许能通过去改变去通过改变host的方式。

原理:

peer1 8861,peer2 8862,peer2 8863 相互感应,当有服务注册时,两个Eureka-server是对等的,它们都存有相同的信息,这就是通过服务器的冗余来增加可靠性,当有一台服务器宕机了,服务并不会终止,因为另一台服务存有相同的数据。

 

三、源码下载

标签 10-1

https://github.com/eddie-code/SpringCloudDemo