欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

服务治理SpringCloud Eureka

程序员文章站 2022-04-26 10:45:45
...

服务治理SpringCloud Eureka


eureka 9001 9004

userservice 9003 9006

ribbonconsumer 9005

一、搭建服务注册中心

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.zk.springcloud.eureka</groupId>
    <artifactId>springcloud-eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

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

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.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>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <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>
        </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 注册启动一个服务注册中心提供给其他应用

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

@SpringBootApplication
@EnableEurekaServer
public class SpringcloudEurekaApplication {

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

配置文件

server.port=9001
spring.application.name=service-eureka

#eureka
eureka.instance.hostname=localhost
#不像注册中心注册自己
eureka.client.register-with-eureka=false
#该服务维护服务实例,不需要检索服务
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
eureka.server.wait-time-in-ms-when-sync-empty=0

启动应用并访问 http://localhost:9001/ 可以看到 Eureka 信息面板

二、注册服务提供者

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.zk.springcloud.service</groupId>
    <artifactId>springcloud-user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.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>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <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>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </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>
        </plugins>
    </build>

</project>

启动类

package com.zk.springcloud.service;

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

@SpringBootApplication
@EnableDiscoveryClient
public class SpringcloudUserServiceApplication {

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

Controller 类


package com.zk.springcloud.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@Slf4j
public class HelloController {

    @GetMapping(value = "/hello")
    public String hello() {
        return "Hello World 9003";
    }

}

配置文件

server.port=9003
spring.application.name=serivce-user

#客户端 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:9001/eureka/

服务启动后,在 service-user 服务控制台打印该服务的注册信息

2018-09-26 16:47:00.959  INFO 13036 --- [           main] c.n.discovery.InstanceInfoReplicator     : InstanceInfoReplicator onDemand update allowed rate per min is 4
2018-09-26 16:47:00.962  INFO 13036 --- [           main] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1537951620962 with initial instances count: 1
2018-09-26 16:47:00.965  INFO 13036 --- [           main] o.s.c.n.e.s.EurekaServiceRegistry        : Registering application serivce-user with eureka with status UP

在注册中心的控制台,打印注册信息 serivce-user 的服务被注册成功

2018-09-26 16:47:00.996  INFO 41944 --- [nio-9001-exec-8] c.n.e.registry.AbstractInstanceRegistry  : Registered instance SERIVCE-USER/DESKTOP-NV4FG13.mshome.net:serivce-user:9003 with status UP (replication=false)

也可以通过 Eureka 的信息面板,在 Instances currently registered with Eureka 一栏看到服务的注册信息

访问 http://localhost:9003/hello , 直接向该服务发起请求

三、高可用注册中心

重新创建 一 操作中的 Eureka 项目,修改 一 中的 配置文件为:

server.port=9001
spring.application.name=service-eureka

#eureka
eureka.instance.hostname=localhost
#不像注册中心注册自己
#eureka.client.register-with-eureka=false
#该服务维护服务实例,不需要检索服务
#eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:9004/eureka/
eureka.server.wait-time-in-ms-when-sync-empty=0

修改 三 中的 配置文件为:

server.port=9004
spring.application.name=service-eureka

#eureka
eureka.instance.hostname=localhost
#不像注册中心注册自己
#eureka.client.register-with-eureka=false
#该服务维护服务实例,不需要检索服务
#eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:9001/eureka/
eureka.server.wait-time-in-ms-when-sync-empty=0

一 和 三 项目重启,在 http://localhost:9001/http://localhost:9004/ 可以看到已经注册的 Eureka

设置多节点注册中心后,服务提供方需要进行如下配置才能将服务注册到 Eureka Server 集群中

server.port=9003
spring.application.name=serivce-user

#客户端 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:9001/eureka/,http://localhost:9004/eureka/

spring eurake中使用IP注册

使用 ip 进行服务注册,修改配置文件添加如下配置:

eureka.instance.hostname=localhost
eureka.instance.preferIpAddress=true
eureka.instance.instance-id=${eureka.instance.hostname}:${server.port}

四、服务发现与消费

复制 二 中 SERIVCE-USER 项目,修改端口号为 9006 , 修改 HelloController 中返回为 “Hello World 9006”

创建 ribbon-consumer 项目

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.zk.springcloud</groupId>
    <artifactId>springcloud-ribbon-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.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>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <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-web</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </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>

启动类

@LoadBalanced 注解开启客户端负载均衡

package com.zk.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class SpringcloudRibbonConsumerApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return  new RestTemplate();
    }

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

调用类,这里访问的地址是服务名 SERIVCE-USER , 而不是一个具体的地址

package com.zk.springcloud;

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

@RestController
public class ConsumerController {
    @Autowired
    RestTemplate restTemplate;

    @GetMapping(value = "ribbon-consumer")
    public String helloConsumer(){
        return restTemplate.getForEntity("http://SERIVCE-USER/hello",String.class).getBody();
    }
}

配置文件

server.port=9005
spring.application.name=ribbon-consumer

eureka.client.service-url.defaultZone=http://localhost:9001/eureka/,http://localhost:9004/eureka/
eureka.instance.hostname=localhost
eureka.instance.preferIpAddress=true
eureka.instance.instance-id=${eureka.instance.hostname}:${server.port}

启动 ribbon-consumer 后,在 Eureka 信息面板可以看到 RIBBON-CONSUMER 服务

调用 http://localhost:9005/ribbon-consumer 发起 GET 请求,多次刷新返回结果在 “Hello World 9003” 和 “Hello World 9006” 之间进行切换

五、服务治理机制

SpringCloud源码-Eureka客户端的服务注册、服务获取与服务续约

关于Spring Cloud Eureka对服务的监控(上线,下线,续约等)

深入理解Eureka之源码解析

1. 服务注册:

服务提供者(eureka客户端)在启动后,如果参数eureka.client.register-with-eureka为true,那么会将自己注册到服务注册中心中,注册的动作会将自己的元数据发送给注册中心,注册中心将接受的元数据保存在一个注册列表中,该列表是一个双层Map结构,具体为:Map<服务名, Map<实例名,服务实例>>

2. 服务续约:

成功注册的eureka服务(eureka客户端)会在注册之后维护一个心跳来告诉注册中心“我还活着”,这样注册中心就不会从注册列表中将这个服务实例剔除,关于这个心跳机制涉及到两个配置参数: eureka.instance.lease-renewal-interval-in-seconds(默认30):心跳间隔时间 eureka.instance.lease-expiration-duration-in-seconds(默认90):定义服务失效时间

3. 服务获取:

前两个概念是针对服务提供者,而服务获取是针对服务消费者(也属于eureka客户端),即调用服务方才需要获取服务列表以便选择调用哪一个服务实例。在服务消费者启动后,会向服务注册中心请求一份服务清单,该清单记录了已经注册到服务中心的服务实例。该请求动作不会仅限于启动的时候,因为消费者需要访问正确的、健康的服务实例,因此会定时发送请求。间隔时间通过配置参数: eureka.instance.registry-fetch-interval-seconds(默认30)

相关标签: springcloud