@Configuration
@RibbonClient(name = "default-test")
public class DefaultConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@Service
1、public class DefaultService {
@Autowired
private RestTemplate restTemplate;
public void testDefaultRibbon() {
String forObject = restTemplate.getForObject("Eureka服务实例ID", String.class);
System.out.println("**********************");
System.out.println(forObject);
}
}
2、(RestTemplate)
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor) throws RestClientException {
ClientHttpResponse response = null;
try {
ClientHttpRequest request = createRequest(url, method);//InterceptingClientHttpRequest
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
if (responseExtractor != null) {
return responseExtractor.extractData(response);
}
}
3、 请求执行 response = request.execute();
-->protected abstract ClientHttpResponse executeInternal(HttpHeaders var1);//(AbstractClientHttpRequest)
-->protected ClientHttpResponse executeInternal(HttpHeaders headers) (AbstractBufferingClientHttpRequest)
-->protected final ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput){
InterceptingClientHttpRequest.InterceptingRequestExecution requestExecution = new InterceptingClientHttpRequest.InterceptingRequestExecution();
requestExecution.execute(this, bufferedOutput)
}(InterceptingClientHttpRequest)
4、requestExecution.execute(this, bufferedOutput)
@Override
public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOException {
if (this.iterator.hasNext()) {
//遍历所有的拦截器执行拦截,主要是LoadBalancerInterceptor。
ClientHttpRequestInterceptor nextInterceptor = this.iterator.next();
return nextInterceptor.intercept(request, body, this);
}else {
//普通调用过程
ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), request.getMethod());
for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
List<String> values = entry.getValue();
for (String value : values) {
delegate.getHeaders().add(entry.getKey(), value);
}
}
if (body.length > 0) {
StreamUtils.copy(body, delegate.getBody());
}
return delegate.execute();
}
}
5、负载均衡拦截器中拦截处理过程。
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
------>requestFactory.createRequest(request, body, execution)
-------->public LoadBalancerRequest<ClientHttpResponse> createRequest(final HttpRequest request,final byte[] body, final ClientHttpRequestExecution execution) {
return new LoadBalancerRequest<ClientHttpResponse>() {
@Override
public ClientHttpResponse apply(final ServiceInstance instance)throws Exception {
HttpRequest serviceRequest = new ServiceRequestWrapper(request, instance, loadBalancer);
if (transformers != null) {
for (LoadBalancerRequestTransformer transformer : transformers) {
serviceRequest = transformer.transformRequest(serviceRequest, instance);
}
}
return execution.execute(serviceRequest, body);
6、@Override//loadBalancer(RibbonLoadBalancerClient)
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
Server server = getServer(loadBalancer);
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
}
RibbonServer ribbonServer = new RibbonServer(serviceId, server, isSecure(server,serviceId), serverIntrospector(serviceId).getMetadata(server));
return execute(serviceId, ribbonServer, request);
}
7、//根据不同的服务ID生成一个Spring容器。采用微服务的名称作为key,容器作为value。如果存在容器则从容器中获取bean,如果不存在直接新生成一个容器,并且进行初始化。
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
protected ILoadBalancer getLoadBalancer(String serviceId) {
return this.clientFactory.getLoadBalancer(serviceId);
}
(SpringClientFactory)public ILoadBalancer getLoadBalancer(String name) {
return getInstance(name, ILoadBalancer.class);
}
@Override
public <C> C getInstance(String name, Class<C> type) {
C instance = super.getInstance(name, type);
if (instance != null) {
return instance;
}
IClientConfig config = getInstance(name, IClientConfig.class);
return instantiateWithConfig(getContext(name), type, config);
}
(NamedContextFactory)public <T> T getInstance(String name, Class<T> type) {
//根据微服务的名字获取Spring容器
AnnotationConfigApplicationContext context = getContext(name);
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,type).length > 0) {
return context.getBean(type);
}
return null;
}
(NamedContextFactory)protected AnnotationConfigApplicationContext getContext(String name) {
if (!this.contexts.containsKey(name)) {
synchronized (this.contexts) {
if (!this.contexts.containsKey(name)) {
this.contexts.put(name, createContext(name));
}
}
}
return this.contexts.get(name);
}
protected AnnotationConfigApplicationContext createContext(String name) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(PropertyPlaceholderAutoConfiguration.class,this.defaultConfigType);
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
this.propertySourceName,
Collections.<String, Object> singletonMap(this.propertyName, name)));
context.refresh();
return context;
}
8、获取服务Server server = getServer(loadBalancer);
protected Server getServer(String serviceId) {
return getServer(getLoadBalancer(serviceId));
}
protected Server getServer(ILoadBalancer loadBalancer) {
if (loadBalancer == null) {
return null;
}
return loadBalancer.chooseServer("default"); // TODO: better handling of key
}
(ZoneAwareLoadBalancer默认)public Server chooseServer(Object key) {
//因为没有指定zone所以直接采用默认的zone
if (!ENABLED.get() || getLoadBalancerStats().getAvailableZones().size() <= 1) {
return super.chooseServer(key);
}
}
(ZoneAvoidanceRule)public Server chooseServer(Object key) {
return rule.choose(key);
}
9、选取完服务之后进行调用 execute(serviceId, ribbonServer, request);
@Override
public <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException {
Server server = null;
if(serviceInstance instanceof RibbonServer) {
server = ((RibbonServer)serviceInstance).getServer();
}
RibbonLoadBalancerContext context = this.clientFactory.getLoadBalancerContext(serviceId);
RibbonStatsRecorder statsRecorder = new RibbonStatsRecorder(context, server);
try {
T returnVal = request.apply(serviceInstance);
statsRecorder.recordStats(returnVal);
return returnVal;
}
}
public ClientHttpResponse apply(final ServiceInstance instance)throws Exception {
HttpRequest serviceRequest = new ServiceRequestWrapper(request, instance, loadBalancer);
if (transformers != null) {
for (LoadBalancerRequestTransformer transformer : transformers) {
serviceRequest = transformer.transformRequest(serviceRequest, instance);
}
return execution.execute(serviceRequest, body);
}
10.一直等到等到把所有的拦截器都执行完成,之后执行请求。
@Override
public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOException {
if (this.iterator.hasNext()) {
ClientHttpRequestInterceptor nextInterceptor = this.iterator.next();
return nextInterceptor.intercept(request, body, this);
}else {
ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), request.getMethod());
for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
List<String> values = entry.getValue();
for (String value : values) {
delegate.getHeaders().add(entry.getKey(), value);
}
}
if (body.length > 0) {
StreamUtils.copy(body, delegate.getBody());
}
return delegate.execute();
}
}
11、return delegate.execute();
(SimpleBufferingClientHttpRequest)public final ClientHttpResponse execute() throws IOException {
assertNotExecuted();
ClientHttpResponse result = executeInternal(this.headers);
this.executed = true;
return result;
}