Merge remote-tracking branch 'origin/1.4.x' into 2.0.x
This commit is contained in:
@@ -453,6 +453,38 @@ In fact, the `eureka.instance.hostname` is not needed if you are running on a ma
|
||||
You can add multiple peers to a system, and, as long as they are all connected to each other by at least one edge, they synchronize
|
||||
the registrations amongst themselves.
|
||||
If the peers are physically separated (inside a data center or between multiple data centers), then the system can, in principle, survive "`split-brain`" type failures.
|
||||
You can add multiple peers to a system, and as long as they are all
|
||||
directly connected to each other, they will synchronize
|
||||
the registrations amongst themselves.
|
||||
|
||||
.application.yml (Three Peer Aware Eureka Servers)
|
||||
----
|
||||
eureka:
|
||||
client:
|
||||
serviceUrl:
|
||||
defaultZone: http://peer1/eureka/,http://peer2/eureka/,http://peer3/eureka/
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: peer1
|
||||
eureka:
|
||||
instance:
|
||||
hostname: peer1
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: peer2
|
||||
eureka:
|
||||
instance:
|
||||
hostname: peer2
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: peer3
|
||||
eureka:
|
||||
instance:
|
||||
hostname: peer3
|
||||
----
|
||||
|
||||
[[spring-cloud-eureka-server-prefer-ip-address]]
|
||||
=== When to Prefer IP Address
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"properties": [
|
||||
{
|
||||
"defaultValue": "true",
|
||||
"name": "archaius.propagate.environmentChangedEvent",
|
||||
"description": "Propagates EnvironmentChanged events to Archaius ConfigurationManager.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": true,
|
||||
"name": "eureka.client.healthcheck.enabled",
|
||||
"description": "Enables the Eureka health check handler.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": "true",
|
||||
"name": "management.metrics.binders.hystrix.enabled",
|
||||
"description": "Enables creation of OK Http Client factory beans.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": false,
|
||||
"name": "hystrix.shareSecurityContext",
|
||||
"description": "Enables auto-configuration of the Hystrix concurrency strategy plugin hook who will transfer the `SecurityContext` from your main thread to the one used by the Hystrix command.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": false,
|
||||
"name": "ribbon.restclient.enabled",
|
||||
"description": "Enables the use of the deprecated Ribbon RestClient.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": false,
|
||||
"name": "ribbon.http.client.enabled",
|
||||
"description": "Deprecated property to enable Ribbon RestClient.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": true,
|
||||
"name": "ribbon.eureka.enabled",
|
||||
"description": "Enables the use of Eureka with Ribbon.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": false,
|
||||
"name": "ribbon.okhttp.enabled",
|
||||
"description": "Enables the use of the OK HTTP Client with Ribbon.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": true,
|
||||
"name": "turbine.stream.enabled",
|
||||
"description": "Enables Autoconfiguration for a Spring Cloud Turbine using Spring Cloud Stream.",
|
||||
"type": "java.lang.Boolean"
|
||||
},
|
||||
{
|
||||
"defaultValue": false,
|
||||
"name": "zuul.ribbon.eager-load.enabled",
|
||||
"description": "Enables eager loading of Ribbon clients on startup.",
|
||||
"type": "java.lang.Boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.DefaultClientConfigImpl;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractLoadBalancer;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.LoadBalancerStats;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerStats;
|
||||
import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.Request.Options;
|
||||
import feign.RequestTemplate;
|
||||
import org.hamcrest.CustomMatcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class FeignRibbonClientTests {
|
||||
|
||||
private AbstractLoadBalancer loadBalancer = mock(AbstractLoadBalancer.class);
|
||||
private Client delegate = mock(Client.class);
|
||||
private RibbonLoadBalancedRetryPolicyFactory retryPolicyFactory = mock(RibbonLoadBalancedRetryPolicyFactory.class);
|
||||
|
||||
private SpringClientFactory factory = new SpringClientFactory() {
|
||||
@Override
|
||||
public IClientConfig getClientConfig(String name) {
|
||||
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
|
||||
config.set(CommonClientConfigKey.ConnectTimeout, 1000);
|
||||
config.set(CommonClientConfigKey.ReadTimeout, 500);
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C> C getInstance(String name, Class<C> type) {
|
||||
if (type.isAssignableFrom(ServerIntrospector.class)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
C instance = (C) new DefaultServerIntrospector();
|
||||
return instance;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILoadBalancer getLoadBalancer(String name) {
|
||||
return FeignRibbonClientTests.this.loadBalancer;
|
||||
}
|
||||
};
|
||||
|
||||
// Even though we don't maintain FeignRibbonClient, keep these tests
|
||||
// around to make sure the expected behaviour doesn't break
|
||||
private Client client = new LoadBalancerFeignClient(this.delegate, new CachingSpringLoadBalancerFactory(this.factory,
|
||||
retryPolicyFactory), this.factory);
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
when(this.loadBalancer.chooseServer(any())).thenReturn(
|
||||
new Server("foo.com", 8000));
|
||||
//to fix NPE
|
||||
LoadBalancerStats stats = mock(LoadBalancerStats.class);
|
||||
when(this.loadBalancer.getLoadBalancerStats()).thenReturn(stats);
|
||||
when(stats.getSingleServerStat(any(Server.class))).thenReturn(mock(ServerStats.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remoteRequestIsSent() throws Exception {
|
||||
Request request = new RequestTemplate().method("GET").append("http://foo/")
|
||||
.request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("http://foo.com:8000/");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remoteRequestIsSentAtRoot() throws Exception {
|
||||
Request request = new RequestTemplate().method("GET").append("http://foo")
|
||||
.request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("http://foo.com:8000/");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remoteRequestIsSecure() throws Exception {
|
||||
Request request = new RequestTemplate().method("GET").append("https://foo/")
|
||||
.request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("https://foo.com:8000/");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
}
|
||||
|
||||
private final static class RequestMatcher extends CustomMatcher<Request> {
|
||||
private String url;
|
||||
|
||||
private RequestMatcher(String url) {
|
||||
super("request has URI: " + url);
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object item) {
|
||||
Request request = (Request) item;
|
||||
return request.url().equals(this.url);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,6 +30,16 @@
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec-http</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
|
||||
Reference in New Issue
Block a user