Skip to content

Commit

Permalink
fix #1276
Browse files Browse the repository at this point in the history
  • Loading branch information
呈铭 committed Feb 23, 2024
1 parent f3ce43c commit a490c0d
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
*/
package com.alipay.sofa.boot.actuator.autoconfigure.rpc;

import com.alipay.sofa.boot.actuator.health.ReadinessCheckListener;
import com.alipay.sofa.boot.actuator.health.ReadinessEndpoint;
import com.alipay.sofa.boot.actuator.rpc.HealthCheckProviderConfigDelayRegisterChecker;
import com.alipay.sofa.boot.actuator.rpc.RpcAfterHealthCheckCallback;
import com.alipay.sofa.boot.actuator.rpc.SofaRpcEndpoint;
import com.alipay.sofa.boot.autoconfigure.rpc.SofaBootRpcProperties;
import com.alipay.sofa.boot.autoconfigure.rpc.SofaRpcAutoConfiguration;
import com.alipay.sofa.rpc.boot.context.RpcStartApplicationListener;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
Expand All @@ -40,6 +43,19 @@
@ConditionalOnBean(RpcStartApplicationListener.class)
public class RpcActuatorAutoConfiguration {

@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint(endpoint = ReadinessEndpoint.class)
public HealthCheckProviderConfigDelayRegisterChecker providerConfigDelayRegisterCheckerSupport(ReadinessCheckListener readinessCheckListener,
SofaBootRpcProperties sofaBootRpcProperties) {
HealthCheckProviderConfigDelayRegisterChecker healthCheckProviderConfigDelayRegisterChecker = new HealthCheckProviderConfigDelayRegisterChecker();
healthCheckProviderConfigDelayRegisterChecker
.setReadinessCheckListener(readinessCheckListener);
healthCheckProviderConfigDelayRegisterChecker.setEnableDelayRegister(sofaBootRpcProperties
.getEnableDelayRegister());
return healthCheckProviderConfigDelayRegisterChecker;
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint(endpoint = ReadinessEndpoint.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alipay.sofa.boot.actuator.extension;
package com.alipay.sofa.boot.actuator.rpc;

import com.alipay.sofa.boot.actuator.health.ReadinessCheckListener;
import com.alipay.sofa.rpc.boot.extension.ProviderConfigDelayRegisterChecker;
import org.springframework.beans.BeansException;
import com.alipay.sofa.rpc.boot.container.ProviderConfigDelayRegisterChecker;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ProviderConfigDelayRegisterCheckerSupport implements ApplicationContextAware,
ProviderConfigDelayRegisterChecker {
/**
* ProviderConfigDelayRegisterChecker的具体实现
*/
public class HealthCheckProviderConfigDelayRegisterChecker implements
ProviderConfigDelayRegisterChecker {

private ReadinessCheckListener readinessCheckListener;

private ApplicationContext applicationContext;
private boolean enableDelayRegister;

@Override
public boolean isDelayRegisterHealthCheck() {
ReadinessCheckListener readinessCheckListener = applicationContext
.getBean(ReadinessCheckListener.class);
public boolean allowRegister() {
return ReadinessState.ACCEPTING_TRAFFIC.equals(readinessCheckListener.getReadinessState());
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
public void setReadinessCheckListener(ReadinessCheckListener readinessCheckListener) {
this.readinessCheckListener = readinessCheckListener;
}

public void setEnableDelayRegister(boolean enableDelayRegister) {
this.enableDelayRegister = enableDelayRegister;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.alipay.sofa.boot.actuator.rpc;

import com.alipay.sofa.boot.actuator.health.ReadinessCheckListener;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.availability.ReadinessState;

import static org.junit.jupiter.api.Assertions.assertTrue;

/**
* Test for {@link HealthCheckProviderConfigDelayRegisterChecker}
*/
@ExtendWith(MockitoExtension.class)
public class HealthCheckProviderConfigDelayRegisterCheckerTest {

@InjectMocks
private HealthCheckProviderConfigDelayRegisterChecker healthCheckProviderConfigDelayRegisterChecker;

@Mock
private ReadinessCheckListener readinessCheckListener;

@Test
public void testAllowRegister() {
// Setup
Mockito.doReturn(ReadinessState.ACCEPTING_TRAFFIC).when(readinessCheckListener)
.getReadinessState();
// Run the test
boolean result = healthCheckProviderConfigDelayRegisterChecker.allowRegister();

// Verify the results
assertTrue(result);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,19 @@ public class SofaBootRpcProperties implements EnvironmentAware {

private List<String> providerRegisterBlackList;

/**
* 是否开启延时注册功能
*/
private Boolean enableDelayRegister;

public Boolean getEnableDelayRegister() {
return enableDelayRegister;
}

public void setEnableDelayRegister(Boolean enableDelayRegister) {
this.enableDelayRegister = enableDelayRegister;
}

public boolean isEnableAutoPublish() {
return enableAutoPublish;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/
package com.alipay.sofa.boot.autoconfigure.rpc;

import com.alipay.sofa.boot.actuator.extension.ProviderConfigDelayRegisterCheckerSupport;
import com.alipay.sofa.boot.actuator.rpc.HealthCheckProviderConfigDelayRegisterChecker;
import com.alipay.sofa.boot.autoconfigure.condition.ConditionalOnSwitch;
import com.alipay.sofa.boot.autoconfigure.rpc.SofaRpcAutoConfiguration.RegistryConfigurationImportSelector;
import com.alipay.sofa.boot.autoconfigure.runtime.SofaRuntimeAutoConfiguration;
Expand Down Expand Up @@ -56,6 +56,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* {@link EnableAutoConfiguration Auto-configuration} for sofa Rpc.
Expand All @@ -71,23 +72,20 @@
RestFilterConfiguration.class })
public class SofaRpcAutoConfiguration {

@Bean
@ConditionalOnMissingBean
public ProviderConfigDelayRegisterCheckerSupport providerConfigDelayRegisterCheckerSupport() {
return new ProviderConfigDelayRegisterCheckerSupport();
}

@Bean
@ConditionalOnMissingBean
public ProviderConfigContainer providerConfigContainer(SofaBootRpcProperties sofaBootRpcProperties,
ProviderConfigDelayRegisterCheckerSupport providerConfigDelayRegisterCheckerSupport) {
ObjectProvider<HealthCheckProviderConfigDelayRegisterChecker> healthCheckProviderConfigDelayRegisterChecker) {
ProviderConfigContainer providerConfigContainer = new ProviderConfigContainer();
providerConfigContainer.setProviderRegisterWhiteList(sofaBootRpcProperties
.getProviderRegisterWhiteList());
providerConfigContainer.setProviderRegisterBlackList(sofaBootRpcProperties
.getProviderRegisterBlackList());
providerConfigContainer
.setProviderConfigDelayRegister(providerConfigDelayRegisterCheckerSupport);
.setProviderConfigDelayRegister(healthCheckProviderConfigDelayRegisterChecker.stream()
.collect(Collectors.toList()));
providerConfigContainer.setEnableDelayRegister(sofaBootRpcProperties
.getEnableDelayRegister());
return providerConfigContainer;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
*/
package com.alipay.sofa.rpc.boot.container;

import com.alipay.sofa.common.thread.SofaScheduledThreadPoolExecutor;
import com.alipay.sofa.rpc.boot.config.SofaBootRpcConfigConstants;
import com.alipay.sofa.rpc.boot.extension.ProviderConfigDelayRegisterChecker;
import com.alipay.sofa.rpc.boot.log.SofaBootRpcLoggerFactory;
import com.alipay.sofa.rpc.boot.runtime.binding.RpcBinding;
import com.alipay.sofa.rpc.config.ProviderConfig;
Expand All @@ -34,8 +34,6 @@
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
Expand Down Expand Up @@ -65,15 +63,24 @@ public class ProviderConfigContainer {
/**
* 用来延时发布的线程池
*/
private ScheduledExecutorService scheduledExecutorService;
private SofaScheduledThreadPoolExecutor scheduledExecutorService;

/**
* 延时发布时健康检查
*/
private ProviderConfigDelayRegisterChecker providerConfigDelayRegisterChecker;
private List<ProviderConfigDelayRegisterChecker> providerConfigDelayRegisterCheckerList;

public void setProviderConfigDelayRegister(ProviderConfigDelayRegisterChecker providerConfigDelayRegisterChecker) {
this.providerConfigDelayRegisterChecker = providerConfigDelayRegisterChecker;
/**
* 是否开启延时加载,兼容老逻辑
*/
private boolean enableDelayRegister;

public void setProviderConfigDelayRegister(List<ProviderConfigDelayRegisterChecker> providerConfigDelayRegisterCheckerList) {
this.providerConfigDelayRegisterCheckerList = providerConfigDelayRegisterCheckerList;
}

public void setEnableDelayRegister(boolean enableDelayRegister) {
this.enableDelayRegister = enableDelayRegister;
}

/**
Expand Down Expand Up @@ -147,27 +154,43 @@ public void publishAllProviderConfig() {
for (ProviderConfig providerConfig : getAllProviderConfig()) {
int delay = providerConfig.getDelay();
// 没有配置延时加载则直接去注册中心注册服务
if (delay <= 0) {
doPublishProviderConfig(providerConfig, false);
if (delay <= 0 && !enableDelayRegister) {
doPublishProviderConfig(providerConfig);
} else {
// 根据延时时间异步去注册中心注册服务
if (scheduledExecutorService == null) {
scheduledExecutorService = Executors.newScheduledThreadPool(16);
scheduledExecutorService = new SofaScheduledThreadPoolExecutor(16);
}
scheduledExecutorService.schedule(() -> doPublishProviderConfig(providerConfig, true), delay, TimeUnit.MILLISECONDS);
scheduledExecutorService.schedule(() -> doDelayPublishProviderConfig(providerConfig,
allRegisterCheckerPass(providerConfigDelayRegisterCheckerList)), delay, TimeUnit.MILLISECONDS);
}
}
}

private void doPublishProviderConfig(ProviderConfig providerConfig, boolean needHealthCheck) {
if (needHealthCheck && !providerConfigDelayRegisterChecker.isDelayRegisterHealthCheck()) {
private void doDelayPublishProviderConfig(ProviderConfig providerConfig,
boolean allRegisterCheckerPass) {
if (!allRegisterCheckerPass) {
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("service publish failed, interfaceId["
+ providerConfig.getInterfaceId() + "], please check.");
}
return;
}
doPublishProviderConfig(providerConfig);
}

private boolean allRegisterCheckerPass(List<ProviderConfigDelayRegisterChecker> providerConfigDelayRegisterCheckerList) {
boolean allTrue = true;
for (ProviderConfigDelayRegisterChecker providerConfigDelayRegisterChecker : providerConfigDelayRegisterCheckerList) {
if (!providerConfigDelayRegisterChecker.allowRegister()) {
allTrue = false;
break;
}
}
return allTrue;
}

private void doPublishProviderConfig(ProviderConfig providerConfig) {
ServerConfig serverConfig = (ServerConfig) providerConfig.getServer().get(0);
if (!serverConfig.getProtocol().equalsIgnoreCase(
SofaBootRpcConfigConstants.RPC_PROTOCOL_DUBBO)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alipay.sofa.rpc.boot.extension;
package com.alipay.sofa.rpc.boot.container;

/**
* 延时发布后注册服务到注册中心的健康检查
*/
public interface ProviderConfigDelayRegisterChecker {

boolean isDelayRegisterHealthCheck();
/**
* 是否允许注册服务到注册中心
*
* @return
*/
boolean allowRegister();
}

0 comments on commit a490c0d

Please sign in to comment.