Estimated Time: 25 minutes
- How to use Ribbon as a client side load balancer
- How to use a Ribbon enabled
RestTemplate
- Start the
config-server
in a terminal window. You may have terminal windows still open from previous labs. They may be reused for this lab.
$ cd $SPRING_CLOUD_SERVICES_LABS_HOME/config-server
$ mvn clean spring-boot:run
- Start the
service-registry
$ cd $SPRING_CLOUD_SERVICES_LABS_HOME/service-registry
$ mvn clean spring-boot:run
- Start the
fortune-service
$ cd $SPRING_CLOUD_SERVICES_LABS_HOME/fortune-service
$ mvn clean spring-boot:run
No additions to the pom.xml
In this case, we don't need to explicitly include Ribbon support in the pom.xml
. Ribbon support is pulled in through transitive dependencies (dependencies of the dependencies we have already defined).
- Review the the following file:
$SPRING_CLOUD_SERVICES_LABS_HOME/greeting-ribbon/src/main/java/io/pivotal/greeting/GreetingController.java
. Notice theloadBalancerClient
. It is a client side load balancer (Ribbon). Review thefetchFortuneServiceUrl()
method. Ribbon is integrated with Eureka so that it can discover services as well. Notice how theloadBalancerClient
chooses a service instance by name.
@Controller
public class GreetingController {
Logger logger = LoggerFactory
.getLogger(GreetingController.class);
@Autowired
private LoadBalancerClient loadBalancerClient;
@RequestMapping("/")
String getGreeting(Model model){
logger.debug("Adding greeting");
model.addAttribute("msg", "Greetings!!!");
RestTemplate restTemplate = new RestTemplate();
String fortune = restTemplate.getForObject(fetchFortuneServiceUrl(), String.class);
logger.debug("Adding fortune");
model.addAttribute("fortune", fortune);
//resolves to the greeting.vm velocity template
return "greeting";
}
private String fetchFortuneServiceUrl() {
ServiceInstance instance = loadBalancerClient.choose("fortune-service");
logger.debug("uri: {}",instance.getUri().toString());
logger.debug("serviceId: {}", instance.getServiceId());
return instance.getUri().toString();
}
}
- Open a new terminal window. Start the
greeting-ribbon
app.
$ cd $SPRING_CLOUD_SERVICES_LABS_HOME/greeting-ribbon
$ mvn clean spring-boot:run
-
After the a few moments, check the
service-registry
dashboard. Confirm thegreeting-ribbon
app is registered. -
Browse to the
greeting-ribbon
application. Confirm you are seeing fortunes. Refresh as desired. Also review the terminal output for thegreeting-ribbon
app. See theuri
andserviceId
being logged. -
Stop the
greeting-ribbon
application.
No additions to the pom.xml
In this case, we don't need to explicitly include Ribbon support in the pom.xml
. Ribbon support is pulled in through transitive dependencies (dependencies of the dependencies we have already defined).
- Review the the following file:
$SPRING_CLOUD_SERVICES_LABS_HOME/greeting-ribbon-rest/src/main/java/io/pivotal/greeting/GreetingController.java
. Notice theRestTemplate
. It is not the usualRestTemplate
, it is load balanced by Ribbon. The@LoadBalanced
annotation is a qualifier to ensure we get the load balancedRestTemplate
injected. This further simplifies application code.
@Controller
public class GreetingController {
Logger logger = LoggerFactory
.getLogger(GreetingController.class);
@Autowired
@LoadBalanced
private RestTemplate restTemplate;
@RequestMapping("/")
String getGreeting(Model model){
logger.debug("Adding greeting");
model.addAttribute("msg", "Greetings!!!");
String fortune = restTemplate.getForObject("http://fortune-service", String.class);
logger.debug("Adding fortune");
model.addAttribute("fortune", fortune);
//resolves to the greeting.vm velocity template
return "greeting";
}
}
- Open a new terminal window. Start the
greeting-ribbon-rest
app.
$ cd $SPRING_CLOUD_SERVICES_LABS_HOME/greeting-ribbon-rest
$ mvn clean spring-boot:run
-
After the a few moments, check the
service-registry
dashboard. Confirm thegreeting-ribbon-rest
app is registered. -
Browse to the
greeting-ribbon-rest
application. Confirm you are seeing fortunes. Refresh as desired. Also review the terminal output for thegreeting-ribbon-rest
app. -
When done stop the
config-server
,service-registry
,fortune-service
andgreeting-ribbon-rest
applications.
- Package and push the
greeting-ribbon-rest
application.
$ mvn clean package
$ cf push greeting-ribbon-rest -p target/greeting-ribbon-rest-0.0.1-SNAPSHOT.jar -m 512M --random-route --no-start
- Bind services for the
greeting-ribbon-rest
application.
$ cf bind-service greeting-ribbon-rest config-server
$ cf bind-service greeting-ribbon-rest service-registry
You can safely ignore the TIP: Use 'cf restage' to ensure your env variable changes take effect message from the CLI. We don't need to restage at this time.
- If using self signed certificates, set the
CF_TARGET
environment variable for thegreeting-ribbon-rest
application.
$ cf set-env greeting-ribbon-rest CF_TARGET <your api endpoint - make sure it starts with "https://">
You can safely ignore the TIP: Use 'cf restage' to ensure your env variable changes take effect message from the CLI. We don't need to restage at this time.
- Start the
greeting-ribbon-rest
app.
$ cf start greeting-ribbon-rest
-
After the a few moments, check the
service-registry
. Confirm thegreeting-ribbon-rest
app is registered. -
Refresh the
greeting-ribbon-rest
/
endpoint.
Note About This Lab
If services (e.g. fortune-service
) are registering using the first Cloud Foundry URI (using the route
registration method) this means that requests to them are being routed through the router
and subsequently load balanced at that layer. Therefore, client side load balancing doesn't occur.
Pivotal Cloud Foundry has recently added support for allowing cross container communication. This will allow applications to communicate with each other without passing through the router
. As applied to client-side load balancing, services such as fortune-service
would register with Eureka using their container IP addresses. Allowing clients to reach them without going through the router
. This is known as using the direct
registration method.
For more details, please read the following.