Feature: 补充客户端实例注册信息.

pull/10/head
chen.ma 4 years ago
parent 6549da27b8
commit d1bec90bd0

@ -1,8 +1,11 @@
package com.github.dynamic.threadpool.starter.config;
import cn.hutool.core.util.StrUtil;
import com.github.dynamic.threadpool.common.model.InstanceInfo;
import com.github.dynamic.threadpool.common.toolkit.ContentUtil;
import com.github.dynamic.threadpool.starter.core.DiscoveryClient;
import com.github.dynamic.threadpool.starter.remote.HttpAgent;
import com.github.dynamic.threadpool.starter.toolkit.inet.InetUtils;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.context.annotation.Bean;
@ -10,7 +13,6 @@ import org.springframework.core.env.ConfigurableEnvironment;
import java.net.InetAddress;
import static com.github.dynamic.threadpool.common.constant.Constants.CLIENT_IDENTIFICATION_VALUE;
import static com.github.dynamic.threadpool.starter.toolkit.CloudCommonIdUtil.getDefaultInstanceId;
import static com.github.dynamic.threadpool.starter.toolkit.CloudCommonIdUtil.getIpApplicationName;
@ -23,7 +25,11 @@ import static com.github.dynamic.threadpool.starter.toolkit.CloudCommonIdUtil.ge
@AllArgsConstructor
public class DiscoveryConfig {
private ConfigurableEnvironment environment;
private final ConfigurableEnvironment environment;
private final BootstrapProperties properties;
private final InetUtils inetUtils;
@Bean
@SneakyThrows
@ -32,16 +38,22 @@ public class DiscoveryConfig {
instanceInfo.setInstanceId(getDefaultInstanceId(environment))
.setIpApplicationName(getIpApplicationName(environment))
.setHostName(InetAddress.getLocalHost().getHostAddress())
.setIdentify(CLIENT_IDENTIFICATION_VALUE)
.setGroupKey(properties.getItemId() + "+" + properties.getNamespace())
.setAppName(environment.getProperty("spring.application.name"))
.setClientBasePath(environment.getProperty("server.servlet.context-path"));
.setClientBasePath(environment.getProperty("server.servlet.context-path"))
.setGroupKey(ContentUtil.getGroupKey(properties.getItemId(), properties.getNamespace()));
String callBackUrl = new StringBuilder().append(instanceInfo.getHostName()).append(":")
.append(environment.getProperty("server.port")).append(instanceInfo.getClientBasePath())
.toString();
instanceInfo.setCallBackUrl(callBackUrl);
String ip = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
String port = environment.getProperty("server.port");
String identification = StrUtil.builder(ip, ":", port).toString();
instanceInfo.setIdentify(identification);
return instanceInfo;
}

@ -1,11 +1,16 @@
package com.github.dynamic.threadpool.starter.config;
import cn.hutool.core.util.StrUtil;
import com.github.dynamic.threadpool.common.config.ApplicationContextHolder;
import com.github.dynamic.threadpool.starter.controller.PoolRunStateController;
import com.github.dynamic.threadpool.starter.core.*;
import com.github.dynamic.threadpool.starter.core.ConfigService;
import com.github.dynamic.threadpool.starter.core.DynamicThreadPoolPostProcessor;
import com.github.dynamic.threadpool.starter.core.ThreadPoolConfigService;
import com.github.dynamic.threadpool.starter.core.ThreadPoolOperation;
import com.github.dynamic.threadpool.starter.enable.MarkerConfiguration;
import com.github.dynamic.threadpool.starter.handler.DynamicThreadPoolBannerHandler;
import com.github.dynamic.threadpool.starter.remote.HttpAgent;
import com.github.dynamic.threadpool.starter.toolkit.inet.InetUtils;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@ -14,6 +19,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* DynamicTp auto configuration.
@ -25,11 +31,21 @@ import org.springframework.core.annotation.Order;
@AllArgsConstructor
@ConditionalOnBean(MarkerConfiguration.Marker.class)
@EnableConfigurationProperties(BootstrapProperties.class)
@ImportAutoConfiguration({HttpClientConfig.class, DiscoveryConfig.class, MessageAlarmConfig.class})
@ImportAutoConfiguration(
{
HttpClientConfig.class,
DiscoveryConfig.class,
MessageAlarmConfig.class,
UtilAutoConfiguration.class,
CorsConfig.class
}
)
public class DynamicThreadPoolAutoConfiguration {
private final BootstrapProperties properties;
private final ConfigurableEnvironment environment;
@Bean
public DynamicThreadPoolBannerHandler threadPoolBannerHandler() {
return new DynamicThreadPoolBannerHandler(properties);
@ -43,8 +59,11 @@ public class DynamicThreadPoolAutoConfiguration {
@Bean
@SuppressWarnings("all")
public ConfigService configService(HttpAgent httpAgent) {
return new ThreadPoolConfigService(httpAgent);
public ConfigService configService(HttpAgent httpAgent, InetUtils inetUtils) {
String ip = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
String port = environment.getProperty("server.port");
String identification = StrUtil.builder(ip, ":", port).toString();
return new ThreadPoolConfigService(httpAgent, identification);
}
@Bean

@ -0,0 +1,24 @@
package com.github.dynamic.threadpool.starter.config;
import com.github.dynamic.threadpool.starter.toolkit.inet.InetUtils;
import com.github.dynamic.threadpool.starter.toolkit.inet.InetUtilsProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* Util auto configuration.
*
* @author Spencer Gibb
* @date 2021/11/12 21:34
*/
@EnableConfigurationProperties(InetUtilsProperties.class)
public class UtilAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public InetUtils inetUtils(InetUtilsProperties properties) {
return new InetUtils(properties);
}
}

@ -36,6 +36,8 @@ public class ClientWorker {
private final HttpAgent agent;
private final String identification;
private final ScheduledExecutorService executor;
private final ScheduledExecutorService executorService;
@ -45,8 +47,9 @@ public class ClientWorker {
private final ConcurrentHashMap<String, CacheData> cacheMap = new ConcurrentHashMap(16);
@SuppressWarnings("all")
public ClientWorker(HttpAgent httpAgent) {
public ClientWorker(HttpAgent httpAgent, String identification) {
this.agent = httpAgent;
this.identification = identification;
this.timeout = CONFIG_LONG_POLL_TIMEOUT;
this.executor = Executors.newScheduledThreadPool(1, r -> {
@ -144,7 +147,7 @@ public class ClientWorker {
sb.append(cacheData.tpId).append(WORD_SEPARATOR);
sb.append(cacheData.itemId).append(WORD_SEPARATOR);
sb.append(cacheData.tenantId).append(WORD_SEPARATOR);
sb.append(CLIENT_IDENTIFICATION_VALUE).append(WORD_SEPARATOR);
sb.append(identification).append(WORD_SEPARATOR);
sb.append(cacheData.getMd5()).append(LINE_SEPARATOR);
if (cacheData.isInitializing()) {
@ -163,7 +166,7 @@ public class ClientWorker {
headers.put(LONG_PULLING_TIMEOUT, "" + timeout);
// 确认客户端身份, 修改线程池配置时可单独修改
headers.put(LONG_PULLING_CLIENT_IDENTIFICATION, CLIENT_IDENTIFICATION_VALUE);
headers.put(LONG_PULLING_CLIENT_IDENTIFICATION, identification);
// told server do not hang me up if new initializing cacheData added in
if (isInitializingCacheList) {

@ -12,13 +12,10 @@ import java.util.Arrays;
*/
public class ThreadPoolConfigService implements ConfigService {
private final HttpAgent httpAgent;
private final ClientWorker clientWorker;
public ThreadPoolConfigService(HttpAgent httpAgent) {
this.httpAgent = httpAgent;
clientWorker = new ClientWorker(httpAgent);
public ThreadPoolConfigService(HttpAgent httpAgent, String identification) {
clientWorker = new ClientWorker(httpAgent, identification);
}
@Override

@ -0,0 +1,217 @@
package com.github.dynamic.threadpool.starter.toolkit.inet;
import com.github.dynamic.threadpool.starter.toolkit.thread.ThreadPoolBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.Closeable;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* Inet utils.
*
* @author Spencer Gibb
* @date 2021/11/12 21:33
*/
public class InetUtils implements Closeable {
private final ExecutorService executorService;
private final InetUtilsProperties properties;
private final Log log = LogFactory.getLog(InetUtils.class);
public InetUtils(InetUtilsProperties properties) {
this.properties = properties;
this.executorService = ThreadPoolBuilder.builder()
.threadFactory(InetUtilsProperties.PREFIX, Boolean.TRUE)
.corePoolSize(1)
.build();
}
@Override
public void close() {
this.executorService.shutdown();
}
public HostInfo findFirstNonLoopbackHostInfo() {
InetAddress address = findFirstNonLoopbackAddress();
if (address != null) {
return convertAddress(address);
}
HostInfo hostInfo = new HostInfo();
hostInfo.setHostname(this.properties.getDefaultHostname());
hostInfo.setIpAddress(this.properties.getDefaultIpAddress());
return hostInfo;
}
public InetAddress findFirstNonLoopbackAddress() {
InetAddress result = null;
try {
int lowest = Integer.MAX_VALUE;
for (Enumeration<NetworkInterface> nics = NetworkInterface
.getNetworkInterfaces(); nics.hasMoreElements(); ) {
NetworkInterface ifc = nics.nextElement();
if (ifc.isUp()) {
this.log.trace("Testing interface: " + ifc.getDisplayName());
if (ifc.getIndex() < lowest || result == null) {
lowest = ifc.getIndex();
} else if (result != null) {
continue;
}
// @formatter:off
if (!ignoreInterface(ifc.getDisplayName())) {
for (Enumeration<InetAddress> addrs = ifc
.getInetAddresses(); addrs.hasMoreElements(); ) {
InetAddress address = addrs.nextElement();
if (address instanceof Inet4Address
&& !address.isLoopbackAddress()
&& isPreferredAddress(address)) {
this.log.trace("Found non-loopback interface: "
+ ifc.getDisplayName());
result = address;
}
}
}
// @formatter:on
}
}
} catch (IOException ex) {
this.log.error("Cannot get first non-loopback address", ex);
}
if (result != null) {
return result;
}
try {
return InetAddress.getLocalHost();
} catch (UnknownHostException e) {
this.log.warn("Unable to retrieve localhost");
}
return null;
}
boolean isPreferredAddress(InetAddress address) {
if (this.properties.isUseOnlySiteLocalInterfaces()) {
final boolean siteLocalAddress = address.isSiteLocalAddress();
if (!siteLocalAddress) {
this.log.trace("Ignoring address: " + address.getHostAddress());
}
return siteLocalAddress;
}
final List<String> preferredNetworks = this.properties.getPreferredNetworks();
if (preferredNetworks.isEmpty()) {
return true;
}
for (String regex : preferredNetworks) {
final String hostAddress = address.getHostAddress();
if (hostAddress.matches(regex) || hostAddress.startsWith(regex)) {
return true;
}
}
this.log.trace("Ignoring address: " + address.getHostAddress());
return false;
}
boolean ignoreInterface(String interfaceName) {
for (String regex : this.properties.getIgnoredInterfaces()) {
if (interfaceName.matches(regex)) {
this.log.trace("Ignoring interface: " + interfaceName);
return true;
}
}
return false;
}
public HostInfo convertAddress(final InetAddress address) {
HostInfo hostInfo = new HostInfo();
Future<String> result = this.executorService.submit(address::getHostName);
String hostname;
try {
hostname = result.get(this.properties.getTimeoutSeconds(), TimeUnit.SECONDS);
} catch (Exception e) {
this.log.info("Cannot determine local hostname");
hostname = "localhost";
}
hostInfo.setHostname(hostname);
hostInfo.setIpAddress(address.getHostAddress());
return hostInfo;
}
/**
* Host information pojo.
*/
public static class HostInfo {
/**
* Should override the host info.
*/
public boolean override;
private String ipAddress;
private String hostname;
public HostInfo(String hostname) {
this.hostname = hostname;
}
public HostInfo() {
}
public int getIpAddressAsInt() {
InetAddress inetAddress = null;
String host = this.ipAddress;
if (host == null) {
host = this.hostname;
}
try {
inetAddress = InetAddress.getByName(host);
} catch (final UnknownHostException e) {
throw new IllegalArgumentException(e);
}
return ByteBuffer.wrap(inetAddress.getAddress()).getInt();
}
public boolean isOverride() {
return this.override;
}
public void setOverride(boolean override) {
this.override = override;
}
public String getIpAddress() {
return this.ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public String getHostname() {
return this.hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
}
}

@ -0,0 +1,108 @@
package com.github.dynamic.threadpool.starter.toolkit.inet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
/**
* Inet utils properties.
*
* @author chen.ma
* @date 2021/11/12 21:34
*/
@ConfigurationProperties(InetUtilsProperties.PREFIX)
public class InetUtilsProperties {
/**
* Prefix for the Inet Utils properties.
*/
public static final String PREFIX = "spring.cloud.inetutils";
/**
* The default hostname. Used in case of errors.
*/
private String defaultHostname = "localhost";
/**
* The default IP address. Used in case of errors.
*/
private String defaultIpAddress = "127.0.0.1";
/**
* Timeout, in seconds, for calculating hostname.
*/
@Value("${spring.util.timeout.sec:${SPRING_UTIL_TIMEOUT_SEC:1}}")
private int timeoutSeconds = 1;
/**
* List of Java regular expressions for network interfaces that will be ignored.
*/
private List<String> ignoredInterfaces = new ArrayList<>();
/**
* Whether to use only interfaces with site local addresses. See
* {@link InetAddress#isSiteLocalAddress()} for more details.
*/
private boolean useOnlySiteLocalInterfaces = false;
/**
* List of Java regular expressions for network addresses that will be preferred.
*/
private List<String> preferredNetworks = new ArrayList<>();
public static String getPREFIX() {
return PREFIX;
}
public String getDefaultHostname() {
return this.defaultHostname;
}
public void setDefaultHostname(String defaultHostname) {
this.defaultHostname = defaultHostname;
}
public String getDefaultIpAddress() {
return this.defaultIpAddress;
}
public void setDefaultIpAddress(String defaultIpAddress) {
this.defaultIpAddress = defaultIpAddress;
}
public int getTimeoutSeconds() {
return this.timeoutSeconds;
}
public void setTimeoutSeconds(int timeoutSeconds) {
this.timeoutSeconds = timeoutSeconds;
}
public List<String> getIgnoredInterfaces() {
return this.ignoredInterfaces;
}
public void setIgnoredInterfaces(List<String> ignoredInterfaces) {
this.ignoredInterfaces = ignoredInterfaces;
}
public boolean isUseOnlySiteLocalInterfaces() {
return this.useOnlySiteLocalInterfaces;
}
public void setUseOnlySiteLocalInterfaces(boolean useOnlySiteLocalInterfaces) {
this.useOnlySiteLocalInterfaces = useOnlySiteLocalInterfaces;
}
public List<String> getPreferredNetworks() {
return this.preferredNetworks;
}
public void setPreferredNetworks(List<String> preferredNetworks) {
this.preferredNetworks = preferredNetworks;
}
}
Loading…
Cancel
Save