Commit 948b176c by Spencer Gibb

Add loadBalancerRequest so that LoadBalancerStats().incrementNumRequests can be called after

parent 07a66fe8
...@@ -12,4 +12,12 @@ public interface LoadBalancerClient { ...@@ -12,4 +12,12 @@ public interface LoadBalancerClient {
* @return * @return
*/ */
public ServiceInstance choose(String serviceId); public ServiceInstance choose(String serviceId);
/**
* Choose a {@see ServiceInstance} from the LoadBalancer for the specified service
* @param serviceId The serviceId to use to look up the LoadBalancer
* @param request allows implementations to execute pre and post actions such as incrementing metrics
* @return
*/
public <T> T choose(String serviceId, LoadBalancerRequest<T> request);
} }
package org.springframework.cloud.client.loadbalancer;
import org.springframework.cloud.client.ServiceInstance;
/**
* @author Spencer Gibb
*/
public interface LoadBalancerRequest<T> {
public T apply(ServiceInstance instance);
}
...@@ -2,6 +2,7 @@ package org.springframework.cloud.netflix.ribbon; ...@@ -2,6 +2,7 @@ package org.springframework.cloud.netflix.ribbon;
import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpRequestInterceptor;
...@@ -28,14 +29,18 @@ public class RibbonInterceptor implements ClientHttpRequestInterceptor { ...@@ -28,14 +29,18 @@ public class RibbonInterceptor implements ClientHttpRequestInterceptor {
HttpRequestWrapper wrapper = new HttpRequestWrapper(request) { HttpRequestWrapper wrapper = new HttpRequestWrapper(request) {
@Override @Override
public URI getURI() { public URI getURI() {
URI originalUri = super.getURI(); final URI originalUri = super.getURI();
String serviceName = originalUri.getHost(); String serviceName = originalUri.getHost();
ServiceInstance instance = loadBalancer.choose(serviceName); URI uri = loadBalancer.choose(serviceName, new LoadBalancerRequest<URI>() {
URI uri = UriComponentsBuilder.fromUri(originalUri) @Override
.host(instance.getHost()) public URI apply(ServiceInstance instance) {
.port(instance.getPort()) return UriComponentsBuilder.fromUri(originalUri)
.build() .host(instance.getHost())
.toUri(); .port(instance.getPort())
.build()
.toUri();
}
});
return uri; return uri;
} }
}; };
......
...@@ -4,6 +4,7 @@ import java.util.HashMap; ...@@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.netflix.loadbalancer.AbstractLoadBalancer;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
...@@ -11,6 +12,7 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; ...@@ -11,6 +12,7 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import com.netflix.loadbalancer.BaseLoadBalancer; import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.Server;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
...@@ -34,20 +36,45 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient { ...@@ -34,20 +36,45 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
@Override @Override
public ServiceInstance choose(String serviceId) { public ServiceInstance choose(String serviceId) {
ribbonClientPreprocessor.preprocess(serviceId); return new RibbonServer(serviceId, getServer(serviceId));
ILoadBalancer loadBalancer = this.balancers.get(serviceId);
if (loadBalancer == null) {
loadBalancer = clientFactory.getNamedLoadBalancer(serviceId);
}
Server server = loadBalancer.chooseServer("default");
if (server == null) {
throw new IllegalStateException(
"Unable to locate ILoadBalancer for service: " + serviceId);
}
return new RibbonServer(serviceId, server);
} }
private class RibbonServer implements ServiceInstance { @Override
public <T> T choose(String serviceId, LoadBalancerRequest<T> request) {
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
Server server = getServer(serviceId, loadBalancer);
RibbonServer ribbonServer = new RibbonServer(serviceId, server);
try {
return request.apply(ribbonServer);
} finally {
if (loadBalancer instanceof AbstractLoadBalancer) {
AbstractLoadBalancer.class.cast(loadBalancer).getLoadBalancerStats().incrementNumRequests(server);
}
}
}
protected Server getServer(String serviceId) {
return getServer(serviceId, getLoadBalancer(serviceId));
}
protected Server getServer(String serviceId, ILoadBalancer loadBalancer) {
Server server = loadBalancer.chooseServer("default");
if (server == null) {
throw new IllegalStateException(
"Unable to locate ILoadBalancer for service: " + serviceId);
}
return server;
}
protected ILoadBalancer getLoadBalancer(String serviceId) {
ribbonClientPreprocessor.preprocess(serviceId);
ILoadBalancer loadBalancer = this.balancers.get(serviceId);
if (loadBalancer == null) {
loadBalancer = clientFactory.getNamedLoadBalancer(serviceId);
}
return loadBalancer;
}
private class RibbonServer implements ServiceInstance {
private String serviceId; private String serviceId;
private Server server; private Server server;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment