Navigating Spring Cloud’s Future: Service Discovery, Config, and API Gateway Without Netflix OSS
This article explains how Spring Cloud modules formerly backed by Netflix OSS are moving to maintenance mode and shows how to replace them with Consul for service discovery and configuration, use Spring Cloud Gateway as the API gateway, and adopt Spring Cloud LoadBalancer for client‑side load balancing in modern cloud‑native microservices.
If you think of Spring Cloud, the first thing that comes to mind is often Netflix OSS support. With the Spring Cloud Greenwich release, Netflix OSS modules such as Archaius, Hystrix, Ribbon, and Zuul have entered maintenance mode, meaning no new features will be added and only bug fixes and security patches will be applied. Eureka remains supported.
1. Service Discovery
Eureka is the only Netflix‑based discovery module not yet in maintenance mode, but its development is uncertain. Consul is presented as a strong alternative, offering service discovery, configuration, and key/value storage. To enable Consul discovery, add the following Maven dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>Configure the Consul client (default address is localhost:8500) in application.yml if you need to override the host and port:
spring:
cloud:
consul:
host: 192.168.99.100
port: 8500You can test the setup with a local Consul container:
$ docker run -d --name consul -p 8500:8500 consulConsul is maintained by HashiCorp, integrates with Spring Cloud Consul, and can also serve as a configuration server, giving it an advantage over Eureka.
2. Distributed Configuration
Netflix Archaius is now in maintenance mode, while Spring Cloud Config provides a more popular solution for externalized configuration. Consul can also act as a configuration server. Add the Consul Config starter:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>Example bootstrap.yml to enable Consul‑backed configuration for the callme-service application:
spring:
application:
name: callme-service
cloud:
consul:
host: 192.168.99.100
port: 8500
config:
format: YAMLWhen using Consul as a config source, you may need to set the instance ID and enable dynamic port generation, as shown in the accompanying screenshots.
3. API Gateway
Spring Cloud Netflix Zuul has been superseded by Spring Cloud Gateway, which runs on Netty and cannot be used with traditional servlet containers. Add the following dependencies (using the latest snapshot version):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<version>2.2.0.BUILD‑SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
<version>2.2.0.BUILD‑SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.0.BUILD‑SNAPSHOT</version>
</dependency>Gateway routes can be defined in Consul’s key/value store as YAML. A sample route configuration that integrates with service discovery:
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: caller-service
uri: lb://caller-service
predicates:
- Path=/caller/**
filters:
- RewritePath=/caller/(?.*), /${path}
- id: callme-service
uri: lb://callme-service
predicates:
- Path=/callme/**
filters:
- RewritePath=/callme/(?.*), /${path}4. Client Load Balancer
Ribbon remains the default HTTP client load balancer in Spring Cloud Commons 2.2.0, but Spring Cloud LoadBalancer is slated to replace it. Add the LoadBalancer starter:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>2.2.0.BUILD‑SNAPSHOT</version>
</dependency>Exclude the old Netflix modules when using Consul discovery:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<version>2.2.0.BUILD‑SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
</exclusion>
...
</exclusions>
</dependency>Load‑balancer configuration class example:
@SpringBootApplication
@LoadBalancerClients({
@LoadBalancerClient(name = "callme-service", configuration = ClientConfiguration.class)
})
public class CallerApplication {
public static void main(String[] args) {
SpringApplication.run(CallerApplication.class, args);
}
@Bean
RestTemplate template() {
return new RestTemplate();
}
}
public class ClientConfiguration {
@Bean
RoundRobinLoadBalancer roundRobinContextLoadBalancer(LoadBalancerClientFactory clientFactory, Environment env) {
String serviceId = clientFactory.getName(env);
return new RoundRobinLoadBalancer(serviceId, clientFactory.getLazyProvider(serviceId, ServiceInstanceSupplier.class), -1);
}
}Caller controller that uses the load balancer to invoke callme-service:
@RestController
@RequestMapping("/caller")
public class CallerController {
@Autowired Environment environment;
@Autowired RestTemplate template;
@Autowired LoadBalancerClientFactory clientFactory;
@GetMapping
public String call() {
RoundRobinLoadBalancer lb = clientFactory.getInstance("callme-service", RoundRobinLoadBalancer.class);
ServiceInstance instance = lb.choose().block().getServer();
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/callme";
String response = template.getForObject(url, String.class);
return "I'm Caller running on port " + environment.getProperty("local.server.port") + " calling-> " + response;
}
}5. Summary
The sample system consists of two instances of callme-service and one instance of caller-service. The caller uses Spring Cloud LoadBalancer to discover available callme-service instances. An API gateway (Spring Cloud Gateway) hides the internal topology and forwards external requests on port 8080 to the appropriate downstream services. After startup, all services register with the Consul node, and you can access the caller endpoint via http://localhost:8080/caller. The full source code is available at GitHub .
Original link: https://piotrminkowski.wordpress.com/2019/04/05/the-future-of-spring-cloud-microservices-after-netflix-era/ Author: Piotr Mińkowski Translator: Yunooa
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
