如何实现单体Spring应用通过Spring Discovery Server连接微服务X/Y?
这事儿我熟,咱们一步步来搞定——核心就是让微服务X/Y注册到Eureka Server,再让你的单体应用成为Eureka客户端,通过服务名调用而不是硬编码IP端口,彻底摆脱地址依赖。
第一步:让微服务X和Y注册到Eureka Server
首先得把X和Y“上报”给Eureka Server,这样服务注册表才会有它们的信息:
1. 添加Eureka客户端依赖
如果用Maven,在X/Y的pom.xml里加:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
如果是Gradle,在build.gradle里加:
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
2. 配置注册信息
在X/Y的application.yml(或application.properties)里填好Eureka地址和自身服务名:
spring: application: name: service-x # 微服务X用这个,Y改成service-y就行 eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ # 你的Eureka Server地址 register-with-eureka: true # 开启注册到Eureka fetch-registry: true # 拉取服务注册表(后续扩容也能自动感知)
3. 启用服务注册
在X/Y的启动类上加上@EnableDiscoveryClient注解:
@SpringBootApplication @EnableDiscoveryClient public class ServiceXApplication { public static void main(String[] args) { SpringApplication.run(ServiceXApplication.class, args); } }
启动X/Y后,打开http://localhost:8761就能看到它们出现在Eureka的服务列表里了。
第二步:把单体应用变成Eureka客户端
接下来让你的单体应用能“看到”Eureka里的服务:
1. 加同样的Eureka客户端依赖
和X/Y一样,给单体应用的pom/gradle加上Eureka客户端依赖。
2. 配置Eureka客户端信息
在单体应用的application.yml里添加:
eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ fetch-registry: true # 必须开启,才能拉取服务注册表
这里不用开register-with-eureka,因为单体应用是服务消费者,不需要注册到Eureka(如果以后要把它也变成微服务,再打开就行)。
3. 启用服务发现
在单体应用的启动类上加上@EnableDiscoveryClient:
@SpringBootApplication @EnableDiscoveryClient public class MonolithicAppApplication { public static void main(String[] args) { SpringApplication.run(MonolithicAppApplication.class, args); } }
第三步:通过服务名调用微服务
现在关键来了——不能再写localhost:8888这种硬编码地址,要改用服务名,还要让调用工具支持负载均衡:
用RestTemplate的方式(传统Spring MVC场景)
先配置一个带@LoadBalanced注解的RestTemplate Bean:
@Configuration public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
然后在业务代码里用服务名代替IP端口:
@Autowired private RestTemplate restTemplate; public String callServiceX() { // 原来的http://localhost:8888/api/xxx → 现在用http://service-x/api/xxx return restTemplate.getForObject("http://service-x/api/xxx", String.class); } public String callServiceY() { return restTemplate.getForObject("http://service-y/api/xxx", String.class); }
用WebClient的方式(Spring WebFlux场景推荐)
配置带负载均衡的WebClient:
@Configuration public class WebClientConfig { @Bean @LoadBalanced public WebClient.Builder webClientBuilder() { return WebClient.builder(); } @Bean public WebClient webClient(WebClient.Builder builder) { return builder.build(); } }
调用示例:
@Autowired private WebClient webClient; public Mono<String> callServiceX() { return webClient.get() .uri("http://service-x/api/xxx") .retrieve() .bodyToMono(String.class); }
最后验证一下
按顺序启动:Eureka Server → 微服务X → 微服务Y → 单体应用,调用单体应用里的接口,就能通过服务名成功访问X和Y了。以后X/Y扩容、换地址,Eureka会自动更新注册表,你的应用不用改任何配置就能继续正常调用。
内容的提问来源于stack exchange,提问作者Swastik

