Browse Source

Ensure server port is registered late enough with Eureka server

Because we were using Lifecycle to kick off the eureka registration the
local server port wasn't available yet. The change is to use an
ApplicationListener and listen for the event that contains the container
with its port instead.

Fixes gh-15
pull/6/head
Dave Syer 10 years ago
parent
commit
21eb52fa27
  1. 11
      Guardfile
  2. 5
      spring-cloud-netflix-core/pom.xml
  3. 39
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java
  4. 80
      src/main/adoc/spring-cloud-netflix.adoc

11
Guardfile

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
require 'asciidoctor'
require 'erb'
options = {:mkdirs => true, :safe => :unsafe, :attributes => 'linkcss'}
guard 'shell' do
watch(/^[A-Za-z].*\.adoc$/) {|m|
Asciidoctor.render_file('src/main/adoc/README.adoc', options.merge(:to_file => './README.md'))
Asciidoctor.render_file('src/main/adoc/spring-cloud-netflix.adoc', options.merge(:to_dir => 'target/docs'))
}
end

5
spring-cloud-netflix-core/pom.xml

@ -108,6 +108,11 @@ @@ -108,6 +108,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-cypher-compiler-2.1</artifactId>
<version>2.1.2</version>
</dependency>
</dependencies>
</project>

39
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java

@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.servo.ServoMetricReader;
import org.springframework.context.ApplicationListener;
@ -34,7 +35,6 @@ import org.springframework.context.annotation.Configuration; @@ -34,7 +35,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;
import com.netflix.appinfo.ApplicationInfoManager;
@ -54,8 +54,7 @@ import com.netflix.discovery.EurekaClientConfig; @@ -54,8 +54,7 @@ import com.netflix.discovery.EurekaClientConfig;
EurekaInstanceConfigBean.class })
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnExpression("${eureka.client.enabled:true}")
public class EurekaClientConfiguration implements
ApplicationListener<ContextRefreshedEvent>, SmartLifecycle, Ordered {
public class EurekaClientConfiguration implements SmartLifecycle, Ordered {
private static final Logger logger = LoggerFactory
.getLogger(EurekaClientConfiguration.class);
@ -64,19 +63,14 @@ public class EurekaClientConfiguration implements @@ -64,19 +63,14 @@ public class EurekaClientConfiguration implements
private int order = 0;
private int port = 0;
@Autowired
private EurekaClientConfigBean clientConfig;
@Autowired
private EurekaInstanceConfigBean instanceConfig;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
logger.info("Registering application {} with eureka with status UP",
instanceConfig.getAppname());
ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.UP);
}
@PreDestroy
public void close() {
logger.info("Removing application {} from eureka", instanceConfig.getAppname());
@ -85,11 +79,20 @@ public class EurekaClientConfiguration implements @@ -85,11 +79,20 @@ public class EurekaClientConfiguration implements
@Override
public void start() {
DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig);
if (port != 0) {
instanceConfig.setNonSecurePort(port);
DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig);
logger.info("Registering application {} with eureka with status UP",
instanceConfig.getAppname());
ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.UP);
}
}
@Override
public void stop() {
logger.info("Unregistering application {} with eureka with status OUT_OF_SERVICE",
instanceConfig.getAppname());
ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.OUT_OF_SERVICE);
running = false;
}
@ -134,4 +137,18 @@ public class EurekaClientConfiguration implements @@ -134,4 +137,18 @@ public class EurekaClientConfiguration implements
new ServoMetricReader(server), config);
}
@Bean
protected ApplicationListener<EmbeddedServletContainerInitializedEvent> containerPortInitializer() {
return new ApplicationListener<EmbeddedServletContainerInitializedEvent>() {
@Override
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
// TODO: take SSL into account when Spring Boot 1.2 is available
EurekaClientConfiguration.this.port = event.getEmbeddedServletContainer()
.getPort();
EurekaClientConfiguration.this.start();
}
};
}
}

80
src/main/adoc/spring-cloud-netflix.adoc

@ -0,0 +1,80 @@ @@ -0,0 +1,80 @@
= Spring Cloud Netflix
This project provides Netflix OSS integrations for Spring Boot apps through autoconfiguration
and binding to the Spring Environment and other Spring programming model idioms.
== Service Discovery: Eureka Clients
Example eureka client:
```
@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
```
(i.e. utterly normal Spring Boot app). Configuration is required to locate the Eureka server. Example:
```
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8080/v2/
default.defaultZone: http://localhost:8080/v2/
```
The default application name, virtual host and non-secure port are taken from the `Environment` is
`${spring.application.name}`, `${spring.application.name}.mydomain.net` and `${server.port}` respectively.
== Service Discovery: Eureka Server
Example eureka server:
```
@Configuration
@EnableAutoConfiguration
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
```
The server has a home page with a UI, and HTTP API endpoints per the
normal Eureka functionality under `/v2/*`.
Eureka (apache -> tomcat) see https://github.com/cfregly/fluxcapacitor/wiki/NetflixOSS-FAQ#eureka-service-discovery-load-balancer[flux capacitor] and https://groups.google.com/forum/?fromgroups#!topic/eureka_netflix/g3p2r7gHnN0[google group discussion].
== Circuit Breaker: Hystrix Clients
== Circuit Breaker: Hystrix Dashboard
=== Turbine
== Declarative REST Client: Feign
== Client Side Load Balancer: Ribbon
== External Configuration: Archaius
== Router and Filter: Zuul
Loading…
Cancel
Save