Spring Cloud Eureka 入门学习

EurekaSpring Cloud Netflix 中的一部分, 基于 Netflix Eureka 做了二次封装, 主要是负责实现微服务架构中的服务治理工作, Eureka 是基于 Rest 的服务, 提供了基于 Java 的客户端组件, 能够非常方便的注册到 Spring Cloud Eureka 中进行统一的处理

编写 Eureka 注册中心

一、创建模块, 取名 eureka-registry, 添加依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.john</groupId>
    <artifactId>eureka-registry</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </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>

二、创建启动类

@EnableEurekaServer 表示开启 Eureka Server

package com.john.eureka;

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

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

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

}

三、配置 application.yml

server:
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  client:
    # 该应用为注册中心, 不需要想注册中心中注册自己
    register-with-eureka: false
    # 注册中心主要是维护服务实例, 不需要检索服务
    fetch-registry: false

四、运行服务并访问 Eureka 的控制台

我们配置的 server.port8761, 打开浏览器通过 http://localhost:8761/ 就可以访问 Eureka 注册中心的控制台

在这里插入图片描述

创建服务的提供者

一、创建服务提供者并注册到 Eureka 中, 添加依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.john</groupId>
    <artifactId>eureka-client-user-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-client-user-provider</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </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>

二、创建提供者的启动类

package com.john.provider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientUserProviderApplication {

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

}

三、编译 application.yml

完成 application.yml 之后就可以启动服务

server:
  port: 8080
spring:
  application:
    name: eureka-client-user-provider
eureka:
  client:
    service-url:
      # Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
      defaultZone: http://localhost:8761/eureka
  instance:
    # 采用 ip 方式注册
    prefer-ip-address: true
    # 定义实例 id 格式
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

四、创建 controller 给其他服务调用的接口

package com.john.provider.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: CaoJun
 * @Create: 2020-03-07 12:17
 **/
@RestController
@RequestMapping("/provider")
public class HelloWorldController {

    @GetMapping("/sayHello")
    public String sayHello() {
        return "Hello World";
    }
}

五、再次访问注册中心

我们创建的服务提供者已经将自己的信息注册到 Eureka 注册中心中

在这里插入图片描述

创建服务消费者

一、创建服务消费者并注册到 Eureka 中, 添加依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.john.consumer</groupId>
    <artifactId>eureka-client-user-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-client-user-consumer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </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>

二、创建消费者的启动类

package com.john.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientUserConsumerApplication {

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

}

三、编写 application.yml 配置文件

server:
  port: 8081
spring:
  application:
    name: eureka-client-user-consumer

四、创建配置类

  • 主要是创建 RestTemplate 实例, 用于访问提供者服务
  • @LoadBalanced 的功能是我们在 RestTemplate 进行远程调用的时候不用直接具体提供方的地址, 而是写提供方注册到 Eureka 中的服务名称
package com.john.consumer.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @Author: CaoJun
 * @Create: 2020-03-07 12:13
 **/
@Configuration
public class BeanConfiguration {
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

五、创建 RestTemplate 的调用接口

在启动服务的时候, 通过访问 http://localhost:8081/consumer/sayHello 就可以通过消费方调用提供者方的服, 然后返回数据

package com.john.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @Author: CaoJun
 * @Create: 2020-03-07 12:14
 **/
@RestController
@RequestMapping("/consumer")
public class HelloWorldController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/sayHello")
    public String sayHello( ) {
        // return this.restTemplate
        //         .getForObject("http://localhost:8080/provider/sayHello", String.class);

        return this.restTemplate
                .getForObject("http://eureka-client-user-provider/provider/sayHello", String.class);
    }

}


六、访问 Eureka 控制台

可以看到注册中心中注册了两个服务
在这里插入图片描述

Eureka 安全问题

Eureka 上自带了一个 Web 的管理页面, 可以让我们去查询注册上的实例信息, 但是在实际的项目中, 直接访问 Eureka 便能访问到, 这样会出现安全问题, 所以我们需要对 Eureka 进行权限控制

一、在 Eureka Registry 模块中添加依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

二、配置 application.yml

server:
  port: 8761
spring:
  application:
    name: eureka-server
  security:
    user:
      name: root
      password: 123456
eureka:
  client:
    # 该应用为注册中心, 不需要想注册中心中注册自己
    register-with-eureka: false
    # 注册中心主要是维护服务实例, 不需要检索服务
    fetch-registry: false

三、创建配置类

package com.john.eureka.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * @Author: CaoJun
 * @Create: 2020-03-07 14:36
 **/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 关闭 csrf
        http.csrf().disable();
        // 支持 httpBasic
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic();
    }
}

Eureka 实现高可用

在生产环境下, 一台注册中心宕机, 那么整个系统就宕机了. 所以需要搭建一个集群来实现高可用
Eureka 中是每一个 Eureka 在配置文件中指定另外的 nEureka 地址列表即可

一、创建 eureka-registry-cluster

eureka-registry 一致, 只是配置 application.yml 不太一样

二、引入依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.john.eureka</groupId>
    <artifactId>eureka-registry-cluster</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-registry-cluster</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </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>

二、创建启动类

package com.john.eureka;

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

@SpringBootApplication
@EnableEurekaServer
public class EurekaRegistryClusterApplication {

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

}

三、编写 application.yml 配置文件

spring:
  application:
    name: eureka-server-cluster
  profiles:
    # 使用指定的环境
    active: slaveone
  security:
    user:
      name: root
      password: 123456
eureka:
  client:
    # 该应用为注册中心, 不需要想注册中心中注册自己
    register-with-eureka: false
    # 检索服务
    fetch-registry: true
  instance:
    prefer-ip-address: true
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
---
spring:
  profiles: master
server:
  port: 8761
eureka:
  client:
    service-url:
      # Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
      defaultZone: http://root:123456@localhost:8762/eureka
---
spring:
  profiles: slaveone
server:
  port: 8762
eureka:
  client:
    service-url:
      # Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
      defaultZone: http://root:123456@localhost:8761/eureka/

①、修改提供者和消费者的 application.yml 文件

提供者

server:
  port: 8080
spring:
  application:
    name: eureka-client-user-provider
eureka:
  client:
    service-url:
      # Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
      defaultZone: http://root:123456@localhost:8761/eureka/,http://root:123456@localhost:8762/eureka/

②、消费者

server:
  port: 8081
spring:
  application:
    name: eureka-client-user-consumer
eureka:
  client:
    service-url:
      defaultZone: http://root:123456@localhost:8762/eureka/, http://root:123456@localhost:8761/eureka/

③、启动 Eureka

注意:

  • 在启动的时候需要修改配置文件 active: master/slave 方式, 当启动之后, 然后修改为另一种环境

在这里插入图片描述

四、最后启动服务提供者和服务消费者

目前所有的服务在 8761/8762 的注册中心注册了实例, 你会发现当你停止启动的一个服务后, 消费者也能够调用提供者的服务

在这里插入图片描述

Eureka 的自我保护模式

主要在一组客户端和 Eureka Server 之间存在网络分区场景下使用的, 当进入保护模式, Eureka Server 会尝试保护其服务注册表中的信息, 不再删除注册表中的信息, 在网络故障恢复之后, Eureka Server 节点就会自动地退出保护模式

在这里插入图片描述

①、通过配置文件关闭保护模式

eureka:
  server:
  	# 关闭自我保护模式
    enable-self-preservation: false

移除已经失效的服务信息

在开发的时候, 我们有可能会不断地重启服务, 因为 Eureka 有自己的保护机制, 所以在节点下线后, 服务的信息还会一直存储在注册中心中, 可以在 application.yml 中配置服务在 Eureka 中的移除时间, 在生产环境推荐还是使用默认的

# 服务端配置
eureka: 
  server:
    # 清理的间隔时间, 默认 6000
    eviction-interval-timer-in-ms: 5000
# 客户端配置
eureka:
  instance:
    # 默认 30s, 客户端给服务端发送心跳的频率
    lease-renewal-interval-in-seconds: 5
    # 默认 90s, 服务端在上一次接收到客户端心跳后, 等待下一次心跳的超时时间, 在这个时间内还没接受到心跳, 就移除该客户端的实例
    lease-expiration-duration-in-seconds: 5

注册中心 application.yml 配置文件

spring:
  application:
    # 服务的应用名称
    name: eureka-server-cluster
  profiles:
    # 使用指定的环境
    active: master
  security:
    # 配置 Eureka 注册中心的控制台权限
    user:
      name: root
      password: 123456
eureka:
  client:
    # 该应用为注册中心, 不需要想注册中心中注册自己
    register-with-eureka: false
    # 检索服务
    fetch-registry: true
  instance:
    prefer-ip-address: true
    # 自定义 Eureka 的 instance-id, 主要是在控制台查看服务注册信息时能方便地查看哪些服务注册上了
    # 例: eureka-client-user-consumer:192.168.73.1:8081
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
  server:
  	# 关闭自我保护模式
    enable-self-preservation: false
    # 清理的间隔时间, 默认 6000
    eviction-interval-timer-in-ms: 5000
# --- 表示分隔 yml 文件, 以下是另一个的环境配置信息
---
spring:
  profiles: master
server:
  port: 8761
eureka:
  client:
    service-url:
      # Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
      defaultZone: http://root:123456@localhost:8762/eureka
---
spring:
  profiles: slaveone
server:
  port: 8762
eureka:
  client:
    service-url:
      # Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
      defaultZone: http://root:123456@localhost:8761/eureka/

客户端 application.yml 配置文件

# 服务端口号
server:
  port: 8080
spring:
  application:
    # 应用名称
    name: eureka-client-user-provider
eureka:
  client:
    service-url:
      # Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
      defaultZone: http://root:123456@localhost:8761/eureka/,http://root:123456@localhost:8762/eureka/
  instance:
    # 采用 ip 方式注册
    prefer-ip-address: true
    # 定义实例 id 格式
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    # 默认 30s, 客户端给服务端发送心跳的频率
    lease-renewal-interval-in-seconds: 5
    # 默认 90s, 服务端在上一次接收到客户端心跳后, 等待下一次心跳的超时时间, 在这个时间内还没接受到心跳, 就移除该客户端的实例
    lease-expiration-duration-in-seconds: 5
  • 如果还需要参考更多 Eureka 的配置可以看源码类 org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean
发布了22 篇原创文章 · 获赞 3 · 访问量 794

猜你喜欢

转载自blog.csdn.net/weixin_38251871/article/details/104711482