Creating a Rest Client
To recap, first consider a case where a simple service needs to be called:
A typical way to make this call using Spring is to inject in a RestTemplate and use it make this call, the following way:
public class RestTemplateBasedPongClient implements PongClient { @Autowired private RestTemplate restTemplate; @Override public MessageAcknowledgement sendMessage(Message message) { String pongServiceUrl = "http://serviceurl/message"; HttpEntity<Message> requestEntity = new HttpEntity<>(message); ResponseEntity<MessageAcknowledgement> response = this.restTemplate.exchange(pongServiceUrl, HttpMethod.POST, requestEntity, MessageAcknowledgement.class, Maps.newHashMap()); return response.getBody(); } }
There is nothing special here. When using Spring Cloud however the same code behaves differently, now the RestTemplate internally uses Netflix OSS Ribbon libraries to make the call. This helps as the typical call flow is to first find the instances running the service and then to loadbalance the calls across the instances and to maintain this state.
Rest Client With Ribbon
Let me digress a little to touch on Ribbon, Ribbon uses an abstraction called a "Named client" to control the behavior of a remote service call - the name by which the service has registered with Eureka, timeout for service calls, how many retries in case of failures etc. These are specified through configuration files, and the entries are typically along these lines, note that the "Named client" here is "samplepong" and the properties have this as a prefix:
samplepong.ribbon.MaxAutoRetries=2 samplepong.ribbon.MaxAutoRetriesNextServer=2 samplepong.ribbon.OkToRetryOnAllOperations=true samplepong.ribbon.ServerListRefreshInterval=2000 samplepong.ribbon.ConnectTimeout=5000 samplepong.ribbon.ReadTimeout=90000 samplepong.ribbon.EnableZoneAffinity=false samplepong.ribbon.DeploymentContextBasedVipAddresses=sample-pong samplepong.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
Coming back to Spring Cloud, it supports the concept of a "Named Client" in a very clever way through the Url hostname, so the RestTemplate call would now look like this:
ResponseEntity<MessageAcknowledgement> response = this.restTemplate.exchange("http://samplepong/message", HttpMethod.POST, requestEntity, MessageAcknowledgement.class, Maps.newHashMap());
The "samplepong" in the url is the "Named client" and any customization for the behavior of the underlying Ribbon can be made by specifying the properties using this prefix. Since this is a Spring Cloud applications the properties can be specified cleanly in a yaml format along these lines:
samplepong: ribbon: DeploymentContextBasedVipAddresses: sample-pong ReadTimeout: 5000 MaxAutoRetries: 2
No comments:
Post a Comment