• 服务注册发现 springcloud netflix eureka


    前言

    角色(三个)

    • 服务注册中心(Register Service): Eureka Server,提供注册和发现功能;
    • 服务提供者(Provider Service):Eureka Client,将自己提供的服务注册到服务注册中心,以供服务消费者发现和调用;
    • 服务消费者(Consumer Service):Eureka Client,从服务注册中心获取服务列表;

    工程说明

    基础运行环境

    	JDK: jdk-20.0.2
    	spring cloud: 2022.0.4
    	spring boot: 3.1.5
    
    • 1
    • 2
    • 3

    工程目录说明

    demo-springcloud-netflix-eureka (父工程)
    ├── demo-springcloud-netflix-eureka-consumer (服务消费者,端口:8000)
    ├── demo-springcloud-netflix-eureka-provider-impl1 (服务提供者,端口:9001)
    ├── demo-springcloud-netflix-eureka-provider-impl2(服务提供者,端口:9002)
    ├── demo-springcloud-netflix-eureka-provider-sdk(服务端,SDK)
    ├── demo-springcloud-netflix-eureka-register1(服务注册中心,端口:7001)
    └── demo-springcloud-netflix-eureka-register2(服务注册中心,端口:7002)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意: 示例中,为了方便看效果,服务注册中心服务提供者分别提供两个工程,内部代码都一样,只是端口不同。

    启动顺序(建议):

    demo-springcloud-netflix-eureka-register1
    demo-springcloud-netflix-eureka-register2
    demo-springcloud-netflix-eureka-provider-impl1
    demo-springcloud-netflix-eureka-provider-impl2
    demo-springcloud-netflix-eureka-consumer
    
    • 1
    • 2
    • 3
    • 4
    • 5

    运行效果

    注册与发现中心

    http://localhost:7001http://localhost:7002

    注册与发现中心

    服务消费者:

    访问这个地址,将随机返回结果:http://localhost:8000/main2?name=abc123

    hello: abc123, I'm 9001
    
    • 1
    hello: abc123, I'm 9002
    
    • 1

    代码说明

    服务注册中心(Register Service)

    demo-springcloud-netflix-eureka-register1,端口:7001

    关键依赖(pom.xml)

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    关键配置(application.properties)

    spring.application.name=demo-springcloud-netflix-eureka-register
    server.port=7001
    
    eureka.instance.hostname=${spring.application.name}
    eureka.instance.instance-id=${spring.application.name}:${server.port}
    eureka.instance.prefer-ip-address=true
    
    # 是否将自己注册到Eureka-Register中,默认的为true,单机设置为false,集群设置为true
    eureka.client.register-with-eureka=true
    
    # 是否从Eureka-Register中获取服务注册信息,默认为true
    eureka.client.fetch-registry=false
    
    # 这里是配置
    eureka.client.service-url.defaultZone=http://localhost:7001/eureka/,http://localhost:7002/eureka/
    
    # 测试时关闭自我保护机制,保证不可用服务及时踢出
    eureka.server.enable-self-preservation=false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    启动类:

    @SpringBootApplication
    @EnableEurekaServer
    public class SpringCloudNetflixEurekaRegister1 {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudNetflixEurekaRegister1.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    demo-springcloud-netflix-eureka-register2,端口:7002
    demo-springcloud-netflix-eureka-register1代码完全一样,只是application.properties中的server.port=7002

    spring.application.name=demo-springcloud-netflix-eureka-register
    server.port=7002
    ....
    
    • 1
    • 2
    • 3

    服务提供者(Provider Service)

    demo-springcloud-netflix-eureka-provider-impl1,端口:9001

    关键依赖(pom.xml)

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    关键配置(application.properties)

    spring.application.name=demo-springcloud-netflix-eureka-provider
    server.port=9001
    
    eureka.instance.instance-id=${spring.application.name}:${server.port}
    eureka.instance.prefer-ip-address=true
    
    # 每间隔2s,向服务端发送一次心跳,证明自己依然”存活“
    eureka.instance.lease-renewal-interval-in-seconds=2
    
    # 告诉服务端,如果我10s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
    eureka.instance.lease-expiration-duration-in-seconds=10
    
    # 是否将自己注册到Eureka-Register中,默认的为true
    eureka.client.register-with-eureka=true
    
    # 是否从Eureka-Server中获取服务注册信息,默认为true
    eureka.client.fetch-registry=true
    eureka.client.service-url.defaultZone=http://localhost:7001/eureka/,http://localhost:7002/eureka/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    启动类:

    @SpringBootApplication
    @EnableDiscoveryClient
    public class SpringcloudNetflixEurekaProvider1 {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringcloudNetflixEurekaProvider1.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    demo-springcloud-netflix-eureka-provider2,端口:9002
    demo-springcloud-netflix-eureka-provider1代码完全一样,只是application.properties中的server.port=9002

    spring.application.name=demo-springcloud-netflix-eureka-provider
    server.port=9002
    ....
    
    • 1
    • 2
    • 3

    服务消费者(Consumer Service)

    demo-springcloud-netflix-eureka-consumer,端口:8000

    关键依赖(pom.xml)

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    关键配置(application.properties)

    spring.application.name=demo-springcloud-netflix-eureka-consumer
    server.port=8000
    
    eureka.instance.instance-id=${spring.application.name}:${server.port}
    eureka.instance.prefer-ip-address=true
    eureka.instance.app-group-name=demo-springcloud-eureka-client-a
    eureka.instance.lease-renewal-interval-in-seconds=2
    
    # 是否将自己注册到Eureka-Server中,默认的为true,这里设置为false,表示不注册,不希望被别的服务发现
    eureka.client.register-with-eureka=false
    eureka.client.registry-fetch-interval-seconds=2
    
    # 是否从Eureka-Server中获取服务注册信息,默认为true
    eureka.client.fetch-registry=true
    eureka.client.service-url.defaultZone=http://localhost:7001/eureka/,http://localhost:7002/eureka/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    启动类:

    @SpringBootApplication
    @EnableDiscoveryClient
    public class SpringCloudNetflixEurekaConsumer {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudNetflixEurekaConsumer.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    服务提供者SDK(Provider Service sdk)

    实际工作中,该工程应该由服务提供者开发团队开发,供服务消费者依赖调用,来实现远程调用。本实例使用openfeign。

    关键依赖(pom.xml)

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    关键代码(demo-springcloud-netflix-eureka-provider-sdk工程ProviderService类):

    // 接口,无需手写实现类
    @Component
    @FeignClient(name = ProviderConstants.SERVICE_ID)
    public interface ProviderService {
    
        // 服务提供者需提供“/sub”接口服务
        @RequestMapping(value = "/sub")
        String test(@RequestParam("name") String name);
    
        // 其他服务....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    服务提供者依赖后使用(demo-springcloud-netflix-eureka-provider-impl1工程)

    @Service
    public class DemoService implements ProviderService {
    
        @Autowired
        private Environment env;
    
        public String test(String name) {
            return "hello: " + name + ", I'm " + env.getProperty("server.port");
        }
    }
    
    @Controller
    public class DemoController {
    
        @Autowired
        private DemoService service;
    
        @ResponseBody
        @RequestMapping("/sub")
        public String test(String name) {
            return service.test(name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    服务消费者依赖后使用(demo-springcloud-netflix-eureka-consumer工程)

    
    @Autowired
    private ProviderService providerService;
    
    @ResponseBody
    @RequestMapping("/main2")
    public String main2(String name) {
        return providerService.test(name);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    负载均衡

    客户端负载:(demo-springcloud-netflix-eureka-consumer工程)

    @Configuration(proxyBeanMethods = false)
    public class CustomLoadBalancerConfig {
    
        @Bean
        @ConditionalOnMissingBean
        public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
                LoadBalancerClientFactory loadBalancerClientFactory) {
            var name = ProviderConstants.SERVICE_ID;
            return new CustomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    // CustomLoadBalancer.java
        private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
    
            if (instances.isEmpty()) {
                if (log.isWarnEnabled()) {
                    log.warn("No servers available for service: " + serviceId);
                }
                return new EmptyResponse();
            }
    
            // 随机
            var index = ThreadLocalRandom.current().nextInt(instances.size());
    
            var instance = instances.get(index);
    
            return new DefaultResponse(instance);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    源码地址

    https://gitee.com/xiaojianhx/demo-springcloud-netflix-eureka

  • 相关阅读:
    实训二十:RIP-2 路由协议单播更新配置
    元素定位(绝对、相对、粘滞、固定)
    这可能是我见过最可爱的乒乓女孩了!
    Linux 字符设备
    人体的神经元有多少个,人体的神经元有多少支
    SpringBoot 开放HTTPS HTTP ,并且强制HTTP转HTTPS端口
    网络安全如何利用ReconPal将自然语言处理技术应用于信息安全
    bash: nvcc: command not found
    Linux 命令个人学习笔记
    Java8新特性:流式计算
  • 原文地址:https://blog.csdn.net/xiaojianhx/article/details/134432585