Merge 4053f9e177
into 3c4bddd6d1
commit
5eb12043e4
@ -0,0 +1,266 @@
|
||||
package com.tencent.cloud.polaris.registry.graceful;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext;
|
||||
import org.springframework.cloud.client.discovery.ManagementServerPortUtils;
|
||||
import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent;
|
||||
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
|
||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* Lifecycle methods that may be useful and common to {@link ServiceRegistry}
|
||||
* implementations.
|
||||
*
|
||||
* TODO: Document the lifecycle.
|
||||
*
|
||||
* @param <R> Registration type passed to the {@link ServiceRegistry}.
|
||||
* @author Spencer Gibb, cheese8
|
||||
*/
|
||||
public abstract class AbstractGracefulServiceRegistration<R extends Registration>
|
||||
implements GracefulServiceRegistration, ApplicationContextAware,
|
||||
ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(AbstractGracefulServiceRegistration.class);
|
||||
|
||||
private final ServiceRegistry<R> serviceRegistry;
|
||||
|
||||
private boolean autoStartup = true;
|
||||
|
||||
private AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
||||
private int order = 0;
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private AtomicInteger port = new AtomicInteger(0);
|
||||
|
||||
private GracefulServiceRegistrationProperties properties;
|
||||
|
||||
@Deprecated
|
||||
protected AbstractGracefulServiceRegistration(ServiceRegistry<R> serviceRegistry) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
protected AbstractGracefulServiceRegistration(ServiceRegistry<R> serviceRegistry,
|
||||
GracefulServiceRegistrationProperties properties) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
protected ApplicationContext getContext() {
|
||||
return this.context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
bind(event);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void bind(ApplicationReadyEvent event) {
|
||||
ApplicationContext context = event.getApplicationContext();
|
||||
if (context instanceof ConfigurableWebServerApplicationContext) {
|
||||
if ("management".equals(((ConfigurableWebServerApplicationContext) context)
|
||||
.getServerNamespace())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Do it need to support random server port?
|
||||
this.port.compareAndSet(0, Integer.parseInt(environment.getProperty("server.port")));
|
||||
this.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.context = applicationContext;
|
||||
this.environment = this.context.getEnvironment();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected Environment getEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected AtomicInteger getPort() {
|
||||
return this.port;
|
||||
}
|
||||
|
||||
public boolean isAutoStartup() {
|
||||
return this.autoStartup;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (!isEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Discovery Lifecycle disabled. Not starting");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// only initialize if nonSecurePort is greater than 0 and it isn't already running
|
||||
// because of containerPortInitializer below
|
||||
if (!this.running.get()) {
|
||||
this.context.publishEvent(
|
||||
new InstancePreRegisteredEvent(this, getRegistration()));
|
||||
register();
|
||||
if (shouldRegisterManagement()) {
|
||||
registerManagement();
|
||||
}
|
||||
this.context.publishEvent(
|
||||
new InstanceRegisteredEvent<>(this, getConfiguration()));
|
||||
this.running.compareAndSet(false, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the management service should be registered with the
|
||||
* {@link ServiceRegistry}.
|
||||
*/
|
||||
protected boolean shouldRegisterManagement() {
|
||||
if (this.properties == null || this.properties.isRegisterManagement()) {
|
||||
return getManagementPort() != null
|
||||
&& ManagementServerPortUtils.isDifferent(this.context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The object used to configure the registration.
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract Object getConfiguration();
|
||||
|
||||
/**
|
||||
* @return True, if this is enabled.
|
||||
*/
|
||||
protected abstract boolean isEnabled();
|
||||
|
||||
/**
|
||||
* @return The serviceId of the Management Service.
|
||||
*/
|
||||
@Deprecated
|
||||
protected String getManagementServiceId() {
|
||||
// TODO: configurable management suffix
|
||||
return this.context.getId() + ":management";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The service name of the Management Service.
|
||||
*/
|
||||
@Deprecated
|
||||
protected String getManagementServiceName() {
|
||||
// TODO: configurable management suffix
|
||||
return getAppName() + ":management";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The management server port.
|
||||
*/
|
||||
@Deprecated
|
||||
protected Integer getManagementPort() {
|
||||
return ManagementServerPortUtils.getPort(this.context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The app name (currently the spring.application.name property).
|
||||
*/
|
||||
@Deprecated
|
||||
protected String getAppName() {
|
||||
return this.environment.getProperty("spring.application.name", "application");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
stop();
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return this.running.get();
|
||||
}
|
||||
|
||||
protected AtomicBoolean getRunning() {
|
||||
return this.running;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public int getPhase() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected ServiceRegistry<R> getServiceRegistry() {
|
||||
return this.serviceRegistry;
|
||||
}
|
||||
|
||||
protected abstract R getRegistration();
|
||||
|
||||
protected abstract R getManagementRegistration();
|
||||
|
||||
/**
|
||||
* Register the local service with the {@link ServiceRegistry}.
|
||||
*/
|
||||
protected void register() {
|
||||
this.serviceRegistry.register(getRegistration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the local management service with the {@link ServiceRegistry}.
|
||||
*/
|
||||
protected void registerManagement() {
|
||||
R registration = getManagementRegistration();
|
||||
if (registration != null) {
|
||||
this.serviceRegistry.register(registration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* De-register the local service with the {@link ServiceRegistry}.
|
||||
*/
|
||||
protected void deregister() {
|
||||
this.serviceRegistry.deregister(getRegistration());
|
||||
}
|
||||
|
||||
/**
|
||||
* De-register the local management service with the {@link ServiceRegistry}.
|
||||
*/
|
||||
protected void deregisterManagement() {
|
||||
R registration = getManagementRegistration();
|
||||
if (registration != null) {
|
||||
this.serviceRegistry.deregister(registration);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (this.getRunning().compareAndSet(true, false) && isEnabled()) {
|
||||
deregister();
|
||||
if (shouldRegisterManagement()) {
|
||||
deregisterManagement();
|
||||
}
|
||||
this.serviceRegistry.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.tencent.cloud.polaris.registry.graceful;
|
||||
|
||||
public interface GracefulServiceRegistration {
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.tencent.cloud.polaris.registry.graceful;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb, cheese8
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(GracefulServiceRegistrationConfiguration.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.graceful-registration.enabled", matchIfMissing = true)
|
||||
public class GracefulServiceRegistrationAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private GracefulServiceRegistration gracefulServiceRegistration;
|
||||
|
||||
@Autowired
|
||||
private GracefulServiceRegistrationProperties properties;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
if (this.gracefulServiceRegistration == null && this.properties.isFailFast()) {
|
||||
throw new IllegalStateException("Graceful Service Registration has "
|
||||
+ "been requested, but there is no GracefulServiceRegistration bean");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.tencent.cloud.polaris.registry.graceful;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(GracefulServiceRegistrationProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.graceful-registration.enabled", matchIfMissing = true)
|
||||
public class GracefulServiceRegistrationConfiguration {
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.tencent.cloud.polaris.registry.graceful;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties("spring.cloud.service-registry.graceful-registration")
|
||||
public class GracefulServiceRegistrationProperties {
|
||||
|
||||
/** Whether service graceful-registration is enabled. Defaults to true. */
|
||||
private boolean enabled = true;
|
||||
|
||||
/** Whether to register the management as a service. Defaults to true. */
|
||||
private boolean registerManagement = true;
|
||||
|
||||
/**
|
||||
* Whether startup fails if there is no AutoServiceRegistration. Defaults to false.
|
||||
*/
|
||||
private boolean failFast = false;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isRegisterManagement() {
|
||||
return this.registerManagement;
|
||||
}
|
||||
|
||||
public void setRegisterManagement(boolean registerManagement) {
|
||||
this.registerManagement = registerManagement;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean shouldRegisterManagement() {
|
||||
return this.registerManagement;
|
||||
}
|
||||
|
||||
public boolean isFailFast() {
|
||||
return this.failFast;
|
||||
}
|
||||
|
||||
public void setFailFast(boolean failFast) {
|
||||
this.failFast = failFast;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.tencent.cloud.polaris.discovery.service.caller;
|
||||
|
||||
import org.springframework.boot.web.context.WebServerInitializedEvent;
|
||||
import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent;
|
||||
import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
|
||||
public class SpringEventOrderListener implements ApplicationListener {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
switch (event.getClass().getSimpleName()) {
|
||||
case "ApplicationStartingEvent":
|
||||
System.out.println("Event ApplicationStartingEvent occurred");
|
||||
break;
|
||||
case "ApplicationEnvironmentPreparedEvent":
|
||||
System.out.println("Event ApplicationEnvironmentPreparedEvent occurred");
|
||||
break;
|
||||
case "ApplicationContextInitializedEvent":
|
||||
System.out.println("Event ApplicationContextInitializedEvent occurred");
|
||||
break;
|
||||
case "ApplicationPreparedEvent":
|
||||
System.out.println("Event ApplicationPreparedEvent occurred");
|
||||
break;
|
||||
case "ContextRefreshedEvent":
|
||||
System.out.println("Event ContextRefreshedEvent occurred");
|
||||
break;
|
||||
case "ApplicationStartedEvent":
|
||||
System.out.println("Event ApplicationStartedEvent occurred");
|
||||
break;
|
||||
case "AvailabilityChangeEvent":
|
||||
System.out.println("Event AvailabilityChangeEvent occurred");
|
||||
break;
|
||||
case "ServletWebServerInitializedEvent":
|
||||
if (event instanceof WebServerInitializedEvent) {
|
||||
System.out.println("Event WebServerInitializedEvent occurred");
|
||||
}
|
||||
if (event instanceof ServletWebServerInitializedEvent) {
|
||||
System.out.println("Event ServletWebServerInitializedEvent occurred");
|
||||
}
|
||||
if (event instanceof ReactiveWebServerInitializedEvent) {
|
||||
System.out.println("Event ReactiveWebServerInitializedEvent occurred");
|
||||
}
|
||||
break;
|
||||
case "ApplicationReadyEvent":
|
||||
System.out.println("Event ApplicationReadyEvent occurred");
|
||||
break;
|
||||
case "ApplicationFailedEvent":
|
||||
System.out.println("Event ApplicationFailedEvent occurred");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue