Spring Cloud Zuul Overview
Zuul serves as an edge service providing load balancing, reverse proxying, authentication, dynamic routing, monitoring, and security. It acts as a protective layer for microservice architectures by handling non-business logic concerns at the routing level.
Routing Gateway Patterns
Consider three architectural approaches:
- Direct Service Access: Clients connect directly to individual services
- Gateway Routing: All requests pass through a single gateway before reaching services
- Registry-Integrated Gateway: Gateway integrates with service discovery for dynamic routing
Development Environment
- Java Development Kit: 1.8+
- Spring Boot: 2.0.6.RELEASE
- Spring Cloud: Finchley.SR2
Service Implementation
Service Registry Configuration
Create a Eureka registry service with the following configuration:
Maven Dependencies
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
Application Properties
application.name=service-registry
server.port=8006
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.default-zone=http://localhost:${server.port}/eureka/
Registry Main Class
@EnableEurekaServer
@SpringBootApplication
public class RegistryMain {
public static void main(String[] args) {
SpringApplication.run(RegistryMain.class, args);
}
}
Gateway Configuration
Gateway Dependencies
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
Gateway Properties
application.name=api-gateway
server.port=9009
eureka.client.service-url.default-zone=http://localhost:8006/eureka/
zuul.routes.service-a.path=/greeting/**
zuul.routes.service-a.url=http://localhost:9010/greeting
zuul.routes.service-b.path=/salutation/**
zuul.routes.service-b.url=http://localhost:9011/salutation
Gateway Main Class
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayMain {
public static void main(String[] args) {
SpringApplication.run(GatewayMain.class, args);
}
}
Service Implementations
Service A Configuration
application.name=service-a
server.port=9010
eureka.client.service-url.default-zone=http://localhost:8006/eureka/
Service A Controller
@RestController
public class GreetingController {
@GetMapping("/greeting/{user}")
public String greetUser(@PathVariable String user) {
return user + ", welcome!";
}
}
Service B Configuraton
application.name=service-b
server.port=9011
eureka.client.service-url.default-zone=http://localhost:8006/eureka/
Service B Controller
@RestController
public class SalutationController {
@GetMapping("/salutation")
public String saluteUser(@RequestParam String name) {
return name + ", greetings!";
}
}
Verification Process
Start all services in sequence: registry, gateway, service A, and service B. Validate routing functionality through these endpoints:
| Endpoint | Expected Response |
|---|---|
| http://localhost:9010/greeting/John | John, welcome! |
| http://localhost:9011/salutation?name=Jane | Jane, greetings! |
| http://localhost:9009/greeting/John | John, welcome! |
| http://localhost:9009/salutation?name=Jane | Jane, greetings! |