微服务ETCD服务注册和发现

发布于:2025-08-13 ⋅ 阅读:(25) ⋅ 点赞:(0)

1.什么是注册中心

注册中心主要有三种角色:

  • 服务提供者(RPC Server):在启动时,向 Registry 注册自身服务,并向 Registry 定期发送心跳汇报存活状态。

  • 服务消费者(RPC Client):在启动时,向 Registry 订阅服务,把 Registry 返回的服务节点列表缓存在本地内存中,并与 RPC Sever 建立连接。

  • 服务注册中心(Registry):用于保存 RPC Server 的注册信息,当 RPC Server 节点发生变更时,Registry 会同步变更,RPC Client 感知后会刷新本地 内存中缓存的服务节点列表。

2.框架版本

spring boot:2.7.13

spring cloud:2021.0.1

3.xxx-discovery-etcd

支持etcd作为服务的注册中心,在微服务中使用

3.1.使用

pom.xml中引入依赖

<dependency>
   <groupId>x.xx.xxx</groupId>
   <artifactId>xxx-discovery-etcd</artifactId>
</dependency>

application.yml中配置

spring:
    application:
        name: etcd-provider-example
   
xxx:
    discovery:
        etcd:
            server-addr: http://192.168.184.133:2379
            instance-name: provider1                

启动主类增加注解@EnableDiscoveryClient

4.Spring Cloud和xxx-etcd-discovery的结合

4.1.etcd-provider-demo

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>org.example</groupId>
    <artifactId>etcd-provider-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
​

    <dependencies>
        <dependency>
            <groupId>x.xx.xxx</groupId>
            <artifactId>xxx-discovery-etcd</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
​
    </dependencies>
​
</project>

bootstrap.yml

server:
    port: 18082
spring:
    application:
        name: etcd-provider-example
​
xxx:
    discovery:
        etcd:
            server-addr: http://192.168.184.133:2379
            instance-name: provider1
​
logging:
    level:
        root: DEBUG
        io:
            grpc:
                netty:
                    NettyClientHandler: INFO
​
        org:
            springframework:
                boot:
                    autoconfigure: INFO

EtcdProviderExampleApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
​
@SpringBootApplication
@EnableDiscoveryClient
public class EtcdProviderExampleApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(EtcdProviderExampleApplication.class, args);
    }
}

EchoController

package x.xx.xxx.etcd.demo;
​
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
​
@RestController
public class EchoController {
    @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
    public String echo(@PathVariable String string) {
        return System.currentTimeMillis() + "--Hello Etcd Discovery " + string;
    }
}

4.2.etcd-consumer-demo

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>org.example</groupId>
    <artifactId>etcd-consumer-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
​
    <dependencies>
       <dependency>
            <groupId>x.xx.xxx</groupId>
            <artifactId>xxx-discovery-etcd</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
​
    </dependencies>
​
</project>

bootstrap.yml

server:
    port: 18081
​
spring:
    application:
        name: etcd-consumer-example
​
xxx:
    discovery:
        etcd:
            server-addr: http://192.168.184.133:2379
            instance-name: consumer1
            
logging:
    level:
        root: DEBUG
        io:
            grpc:
                netty:
                    NettyClientHandler: INFO
​
        org:
            springframework:
                boot:
                    autoconfigure: INFO

EtcdConsumerExampleApplication

package x.xx.xxx.etcd.demo;

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;
import org.springframework.web.reactive.function.client.WebClient;

@SpringBootApplication
@EnableDiscoveryClient
public class EtcdConsumerExampleApplication {

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

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

    @Bean
    @LoadBalanced
    public WebClient.Builder loadBalancedWebClientBuilder() {
        return WebClient.builder();
    }
}

TestController

package x.xx.xxx.etcd.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;

@RestController
public class TestController {

    private final RestTemplate restTemplate;

    @Autowired
    public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

    @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
    public String echo(@PathVariable String str) {
        return restTemplate.getForObject("http://etcd-provider-example/echo/" + str, String.class);
    }

    @Autowired
    private WebClient.Builder webClientBuilder;

    @RequestMapping(value = "/echo/webClient/{str}", method = RequestMethod.GET)
    public String echoWebClient(@PathVariable String str) {
        WebClient webClient = webClientBuilder.build();
        webClient.get()
                .uri("http://etcd-provider-example/echo/" + str)
                .retrieve()
                .bodyToMono(String.class)
                .subscribe(response -> {
                    System.err.println("控制台响应结果:" + response);
                });

        return System.currentTimeMillis() + "--echoWebClient--" + str + "--请查看控制台是否执行成功!";
    }

}

4.3.启动主程序

EtcdProviderExampleApplication

EtcdConsumerExampleApplication

通过ETCD Manager查看,如下表示注册成功

请求etcd-consumer-demo中接口,查看服务发现功能,更改测试接口,可查看TestController

http://localhost:18081/echo/6666

浏览器返回如下信息表示服务发现成功

1705978409084--Hello Etcd Discovery 6666

5.xxx-etcd-discovery详解

5.1.可配置属性

5.2.存储到etcd的格式

5.3.监控ectd服务端事件,并发送事件

5.4.启动全量查所有服务列表并缓存


网站公告

今日签到

点亮在社区的每一天
去签到