pull/441/merge
cheese8 3 years ago committed by GitHub
commit 5eb12043e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -9,3 +9,4 @@
- [Optimize: add EncodeTransferMedataRestTemplateInterceptor to RestTemplate](https://github.com/Tencent/spring-cloud-tencent/pull/434)
- [feat:enhance Feign and RestTemplate and support Polaris monitor.](https://github.com/Tencent/spring-cloud-tencent/pull/435)
- [Optimize: Specification apollo code reference notes](https://github.com/Tencent/spring-cloud-tencent/pull/442)
- [Feature: graceful service registration after ApplicationReadyEventg](https://github.com/Tencent/spring-cloud-tencent/pull/441)

@ -17,11 +17,11 @@
package com.tencent.cloud.polaris.registry;
import com.tencent.cloud.polaris.registry.graceful.AbstractGracefulServiceRegistration;
import com.tencent.cloud.polaris.registry.graceful.GracefulServiceRegistrationProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.util.StringUtils;
@ -29,16 +29,16 @@ import org.springframework.util.StringUtils;
/**
* Auto service registration of Polaris.
*
* @author Haotian Zhang, Andrew Shan, Jie Cheng
* @author Haotian Zhang, Andrew Shan, Jie Cheng, cheese8
*/
public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistration<Registration> {
public class PolarisAutoServiceRegistration extends AbstractGracefulServiceRegistration<Registration> {
private static final Logger LOG = LoggerFactory.getLogger(PolarisAutoServiceRegistration.class);
private final PolarisRegistration registration;
public PolarisAutoServiceRegistration(ServiceRegistry<Registration> serviceRegistry,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
GracefulServiceRegistrationProperties autoServiceRegistrationProperties,
PolarisRegistration registration) {
super(serviceRegistry, autoServiceRegistrationProperties);
this.registration = registration;

@ -47,7 +47,7 @@ import static org.springframework.util.ReflectionUtils.rethrowRuntimeException;
/**
* Service registry of Polaris.
*
* @author Haotian Zhang, Andrew Shan, Jie Cheng
* @author Haotian Zhang, Andrew Shan, Jie Cheng, cheese8
*/
public class PolarisServiceRegistry implements ServiceRegistry<Registration> {

@ -23,6 +23,9 @@ import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration;
import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler;
import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties;
import com.tencent.cloud.polaris.registry.graceful.GracefulServiceRegistrationAutoConfiguration;
import com.tencent.cloud.polaris.registry.graceful.GracefulServiceRegistrationConfiguration;
import com.tencent.cloud.polaris.registry.graceful.GracefulServiceRegistrationProperties;
import com.tencent.polaris.client.api.SDKContext;
import org.springframework.beans.factory.annotation.Autowired;
@ -30,23 +33,20 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Autoconfiguration of service registry of Polaris.
*
* @author Haotian Zhang, Andrew Shan, Jie Cheng
* @author Haotian Zhang, Andrew Shan, Jie Cheng, cheese8
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnPolarisRegisterEnabled
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
@AutoConfigureAfter({AutoServiceRegistrationConfiguration.class,
AutoServiceRegistrationAutoConfiguration.class,
@ConditionalOnProperty(value = "spring.cloud.service-registry.graceful-registration.enabled", matchIfMissing = false)
@AutoConfigureAfter({GracefulServiceRegistrationConfiguration.class,
GracefulServiceRegistrationAutoConfiguration.class,
PolarisDiscoveryAutoConfiguration.class})
public class PolarisServiceRegistryAutoConfiguration {
@ -58,7 +58,7 @@ public class PolarisServiceRegistryAutoConfiguration {
}
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
@ConditionalOnBean(GracefulServiceRegistrationProperties.class)
public PolarisRegistration polarisRegistration(
PolarisDiscoveryProperties polarisDiscoveryProperties,
@Autowired(required = false) ConsulContextProperties consulContextProperties,
@ -67,11 +67,11 @@ public class PolarisServiceRegistryAutoConfiguration {
}
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
@ConditionalOnBean(GracefulServiceRegistrationProperties.class)
public PolarisAutoServiceRegistration polarisAutoServiceRegistration(
PolarisServiceRegistry registry,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
GracefulServiceRegistrationProperties gracefulServiceRegistrationProperties,
PolarisRegistration registration) {
return new PolarisAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration);
return new PolarisAutoServiceRegistration(registry, gracefulServiceRegistrationProperties, registration);
}
}

@ -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;
}
}

@ -3,6 +3,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration,\
com.tencent.cloud.polaris.ribbon.PolarisDiscoveryRibbonAutoConfiguration,\
com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration,\
com.tencent.cloud.polaris.endpoint.PolarisDiscoveryEndpointAutoConfiguration
com.tencent.cloud.polaris.endpoint.PolarisDiscoveryEndpointAutoConfiguration,\
com.tencent.cloud.polaris.registry.graceful.GracefulServiceRegistrationAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.tencent.cloud.polaris.DiscoveryPropertiesBootstrapAutoConfiguration

@ -18,13 +18,13 @@
package com.tencent.cloud.polaris.registry;
import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.registry.graceful.GracefulServiceRegistrationProperties;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.context.ApplicationContext;
@ -42,16 +42,16 @@ import static org.mockito.Mockito.doReturn;
/**
* Test for {@link PolarisAutoServiceRegistration}.
*
* @author Haotian Zhang
* @author Haotian Zhang, cheese8
*/
@RunWith(MockitoJUnitRunner.class)
public class PolarisAutoServiceRegistrationTest {
public class PolarisGracefulServiceRegistrationTest {
@Mock
private ServiceRegistry<Registration> serviceRegistry;
@Mock
private AutoServiceRegistrationProperties autoServiceRegistrationProperties;
private GracefulServiceRegistrationProperties autoServiceRegistrationProperties;
@Mock
private PolarisDiscoveryProperties polarisDiscoveryProperties;

@ -43,7 +43,7 @@ import static org.mockito.Mockito.when;
/**
* Test for {@link PolarisServiceRegistry}.
*
* @author Haotian Zhang
* @author Haotian Zhang, cheese8
*/
public class PolarisServiceRegistryTest {
@ -57,6 +57,7 @@ public class PolarisServiceRegistryTest {
PolarisDiscoveryAutoConfiguration.class))
.withPropertyValues("spring.application.name=" + SERVICE_PROVIDER)
.withPropertyValues("server.port=" + PORT)
.withPropertyValues("spring.cloud.service-registry.graceful-registration.enabled=true")
.withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081")
.withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST)
.withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx");

@ -5,12 +5,15 @@ spring:
name: DiscoveryCalleeService
cloud:
polaris:
address: grpc://183.47.111.80:8091
address: grpc://127.0.0.1:8091
namespace: default
enabled: true
discovery:
enabled: true
register: true
service-registry:
graceful-registration:
enabled: true
stat:
enabled: true
port: 28082

@ -27,14 +27,16 @@ import org.springframework.web.client.RestTemplate;
/**
* Discovery caller application.
*
* @author Haotian Zhang
* @author Haotian Zhang, cheese8
*/
@SpringBootApplication
@EnableFeignClients
public class DiscoveryCallerService {
public static void main(String[] args) {
SpringApplication.run(DiscoveryCallerService.class, args);
SpringApplication app = new SpringApplication(DiscoveryCallerService.class);
app.addListeners(new SpringEventOrderListener());
app.run(args);
}
@Bean

@ -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;
}
}
}

@ -5,6 +5,11 @@ spring:
application:
name: DiscoveryCallerService
cloud:
service-registry:
graceful-registration:
enabled: true
auto-registration:
enabled: false
polaris:
address: grpc://183.47.111.80:8091
namespace: default

Loading…
Cancel
Save