# demo-springcloud-netflix-eureka **Repository Path**: xiaojianhx/demo-springcloud-netflix-eureka ## Basic Information - **Project Name**: demo-springcloud-netflix-eureka - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-11-16 - **Last Updated**: 2023-11-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README @[TOC] # 前言 略 ## 角色(三个) - **服务注册中心(Register Service)**: Eureka Server,提供注册和发现功能; - **服务提供者(Provider Service)**:Eureka Client,将自己提供的服务注册到服务注册中心,以供服务消费者发现和调用; - **服务消费者(Consumer Service)**:Eureka Client,从服务注册中心获取服务列表; # 工程说明 ## 基础运行环境 ```base JDK: jdk-20.0.2 spring cloud: 2022.0.4 spring boot: 3.1.5 ``` ## 工程目录说明 ```shell 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) ``` ***注意:*** 示例中,为了方便看效果,**服务注册中心**和**服务提供者**分别提供两个工程,内部代码都一样,只是端口不同。 ## 启动顺序(建议): ```base 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 ``` ## 运行效果 ### 注册与发现中心 [http://localhost:7001](http://localhost:7001) 或 [http://localhost:7002](http://localhost:7002) ![注册与发现中心](https://img-blog.csdnimg.cn/f8ab562c74fe48458a3d33e04bf32390.png) ### 服务消费者: 访问这个地址,将随机返回结果:[http://localhost:8000/main2?name=abc123](http://localhost:8000/main2?name=abc123) ```base hello: abc123, I'm 9001 ``` ```base hello: abc123, I'm 9002 ``` # 代码说明 ## 服务注册中心(Register Service) **demo-springcloud-netflix-eureka-register1**,端口:**7001** 关键依赖(pom.xml) ```xml org.springframework.cloud spring-cloud-starter-netflix-eureka-server ``` 关键配置(application.properties) ```yaml 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 ``` 启动类: ```java @SpringBootApplication @EnableEurekaServer public class SpringCloudNetflixEurekaRegister1 { public static void main(String[] args) { SpringApplication.run(SpringCloudNetflixEurekaRegister1.class, args); } } ``` **demo-springcloud-netflix-eureka-register2**,端口:**7002** 与*demo-springcloud-netflix-eureka-register1*代码完全一样,只是application.properties中的server.port=7002 ```yaml spring.application.name=demo-springcloud-netflix-eureka-register server.port=7002 .... ``` ## 服务提供者(Provider Service) **demo-springcloud-netflix-eureka-provider-impl1**,端口:**9001** 关键依赖(pom.xml) ```xml org.springframework.cloud spring-cloud-starter-netflix-eureka-client ``` 关键配置(application.properties) ```yaml 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/ ``` 启动类: ```java @SpringBootApplication @EnableDiscoveryClient public class SpringcloudNetflixEurekaProvider1 { public static void main(String[] args) { SpringApplication.run(SpringcloudNetflixEurekaProvider1.class, args); } } ``` **demo-springcloud-netflix-eureka-provider2**,端口:**9002** 与*demo-springcloud-netflix-eureka-provider1*代码完全一样,只是application.properties中的server.port=9002 ```yaml spring.application.name=demo-springcloud-netflix-eureka-provider server.port=9002 .... ``` ## 服务消费者(Consumer Service) **demo-springcloud-netflix-eureka-consumer**,端口:**8000** 关键依赖(pom.xml) ```xml org.springframework.cloud spring-cloud-starter-netflix-eureka-client ``` 关键配置(application.properties) ```yaml 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/ ``` 启动类: ```java @SpringBootApplication @EnableDiscoveryClient public class SpringCloudNetflixEurekaConsumer { public static void main(String[] args) { SpringApplication.run(SpringCloudNetflixEurekaConsumer.class, args); } } ``` ## 服务提供者SDK(Provider Service sdk) 实际工作中,该工程应该由**服务提供者**开发团队开发,供**服务消费者**依赖调用,来实现远程调用。本实例使用openfeign。 关键依赖(pom.xml) ```xml org.springframework.cloud spring-cloud-starter-openfeign ``` 关键代码(demo-springcloud-netflix-eureka-provider-sdk工程ProviderService类): ```java // 接口,无需手写实现类 @Component @FeignClient(name = ProviderConstants.SERVICE_ID) public interface ProviderService { // 服务提供者需提供“/sub”接口服务 @RequestMapping(value = "/sub") String test(@RequestParam("name") String name); // 其他服务.... } ``` 服务提供者依赖后使用(demo-springcloud-netflix-eureka-provider-impl1工程) ```java @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); } } ``` 服务消费者依赖后使用(demo-springcloud-netflix-eureka-consumer工程) ```java @Autowired private ProviderService providerService; @ResponseBody @RequestMapping("/main2") public String main2(String name) { return providerService.test(name); } ``` # 负载均衡 客户端负载:(demo-springcloud-netflix-eureka-consumer工程) ```java @Configuration(proxyBeanMethods = false) public class CustomLoadBalancerConfig { @Bean @ConditionalOnMissingBean public ReactorLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { var name = ProviderConstants.SERVICE_ID; return new CustomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); } } ``` ```java // CustomLoadBalancer.java private Response getInstanceResponse(List 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); } ``` # 源码地址 [https://gitee.com/xiaojianhx/demo-springcloud-netflix-eureka](https://gitee.com/xiaojianhx/demo-springcloud-netflix-eureka)