Load balancing is the process of distributing traffic among different instances of the same application. To create a fault-tolerant system, it's common to run multiple instances of each application. Thus, whenever one service needs to communicate with another, it needs to pick a particular instance to send its request.
A load balanced RestTemplate can be configured to retry failed requests. By default this logic is disabled, you can enable it by adding Spring Retry to your application's classpath. The load balanced RestTemplate will honor some of the Ribbon configuration values related to retrying failed requests.
Regarding Zuul, there is a RibbonRoutingFilter that routes your request to an actual service instance. RibbonRoutingFilter is using Ribbon to choose a server from the list that is given from your configuration or from Eureka. So if you want to use Zuul as a load-balanced reverse proxy, Zuul needs Ribbon.
6.6 Example: How to Use Ribbon Without Eureka Eureka is a convenient way to abstract the discovery of remote servers so that you do not have to hard code their URLs in clients. However, if you prefer not to use Eureka, Ribbon and Feign also work.
TL;DR: @LoadBalanced
is a marker annotation & @RibbonClient
is used for configuration purposes.
@LoadBalanced
Used as a marker annotation indicating that the annotated RestTemplate
should use a RibbonLoadBalancerClient
for interacting with your service(s).
In turn, this allows you to use "logical identifiers" for the URLs you pass to the RestTemplate
. These logical identifiers are typically the name of a service. For example:
restTemplate.getForObject("http://some-service-name/user/{id}", String.class, 1);
where some-service-name
is the logical identifier.
@RibbonClient
Used for configuring your Ribbon client(s).
Is @RibbonClient required?
No! If you're using Service Discovery and you're ok with all of the default Ribbon settings, you don't even need to use the @RibbonClient
annotation.
When should I use @RibbonClient
?
There are at least two cases where you need to use @RibbonClient
Customizing your Ribbon settings:
Define a @RibbonClient
@RibbonClient(name = "some-service", configuration = SomeServiceConfig.class)
name
- set it to the same name of the service you're calling with Ribbon but need additional customizations for how Ribbon interacts with that service.configuration
- set it to an @Configuration
class with all of your customizations defined as @Beans
. Make sure this class is not picked up by @ComponentScan
otherwise it will override the defaults for ALL Ribbon clients.See the section "Customizing the RibbonClient` in the Spring Cloud Netflix documentation (link)
Using Ribbon without Service Discovery
If you're not using Service Discovery, the name
field of the @RibbonClient
annotation will be used to prefix your configuration in the application.properties
as well as "logical identifier" in the URL you pass to RestTemplate
.
Define a @RibbonClient
@RibbonClient(name = "myservice")
then in your application.properties
myservice.ribbon.eureka.enabled=false
myservice.ribbon.listOfServers=http://localhost:5000, http://localhost:5001
RestTemplate
supports load balancing, using @LoadBalanced
tells Spring Cloud that we want to take advantage of its load balancing support(If you are using Ribbon then the effect of using @LoadBalanced will be that RestTemplate will use RibbionClient to get the server address).
You can also check how LoadBalancerAutoConfiguration works here
Using @RibbonClients you can provide declarative configuration for a ribbon client.
E.g.
@SpringBootApplication
@RestController
@RibbonClient(name = "app", configuration = RibbonConfig.class)
public class App {
@LoadBalanced
@Bean
RestTemplate restTemplate(){
return new RestTemplate();
}
//...
}
Then you create RibbonConfig.class
to override any Ribbon related bean.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.PingUrl;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
public class RibbonConfig {
@Autowired
IClientConfig ribbonClientConfig;
@Bean
public IPing ribbonPing (IClientConfig config) {
return new PingUrl();//we override default Iping which is a NoOpPing
}
@Bean
public IRule ribbonRule(IClientConfig config) {
return new AvailabilityFilteringRule(); // we override the default ZoneAvoidanceRule
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With