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