chore(project): 添加项目配置文件和忽略规则

- 添加 Babel 配置文件支持 ES6+ 语法转换
- 添加 ESLint 忽略规则和配置文件
- 添加 Git 忽略规则文件
- 添加 Travis CI 配置文件
- 添加 1.4.2 版本变更日志文件
- 添加 Helm 图表辅助模板文件
- 添加 Helm 忽略规则文件
This commit is contained in:
2026-03-27 17:36:48 +08:00
commit c2453d6434
1703 changed files with 277582 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 1999-2019 Seata.io Group.
~
~ Licensed 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>io.seata</groupId>
<artifactId>seata-discovery</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>seata-discovery-redis</artifactId>
<name>seata-discovery-redis ${project.version}</name>
<dependencies>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,39 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* Licensed 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 io.seata.discovery.registry.redis;
/**
* The RedisListener
*
* @author kl @kailing.pub
*/
public interface RedisListener {
/**
* The constant REGISTER.
*/
String REGISTER = "register";
/**
* The constant UN_REGISTER.
*/
String UN_REGISTER = "unregister";
/**
* use for redis event
*
* @param event the event
*/
void onEvent(String event);
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* Licensed 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 io.seata.discovery.registry.redis;
import io.seata.common.loader.LoadLevel;
import io.seata.discovery.registry.RegistryProvider;
import io.seata.discovery.registry.RegistryService;
/**
* @author xingfudeshi@gmail.com
*/
@LoadLevel(name = "Redis", order = 1)
public class RedisRegistryProvider implements RegistryProvider {
@Override
public RegistryService provide() {
return RedisRegistryServiceImpl.getInstance();
}
}

View File

@@ -0,0 +1,259 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* Licensed 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 io.seata.discovery.registry.redis;
import java.lang.management.ManagementFactory;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.stream.Collectors;
import io.seata.common.exception.ShouldNeverHappenException;
import io.seata.common.thread.NamedThreadFactory;
import io.seata.common.util.NetUtil;
import io.seata.common.util.StringUtils;
import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
import io.seata.discovery.registry.RegistryService;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.Protocol;
/**
* The type Redis registry service.
*
* @author kl @kailing.pub
*/
public class RedisRegistryServiceImpl implements RegistryService<RedisListener> {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisRegistryServiceImpl.class);
private static final String PRO_SERVER_ADDR_KEY = "serverAddr";
private static final String REDIS_FILEKEY_PREFIX = "registry.redis.";
private static final String DEFAULT_CLUSTER = "default";
private static final String REGISTRY_CLUSTER_KEY = "cluster";
private String clusterName;
private static final String REDIS_DB = "db";
private static final String REDIS_PASSWORD = "password";
private static final ConcurrentMap<String, List<RedisListener>> LISTENER_SERVICE_MAP = new ConcurrentHashMap<>();
private static final ConcurrentMap<String, Set<InetSocketAddress>> CLUSTER_ADDRESS_MAP = new ConcurrentHashMap<>();
private static volatile RedisRegistryServiceImpl instance;
private static volatile JedisPool jedisPool;
private ExecutorService threadPoolExecutor = new ScheduledThreadPoolExecutor(1,
new NamedThreadFactory("RedisRegistryService", 1));
private RedisRegistryServiceImpl() {
Configuration seataConfig = ConfigurationFactory.CURRENT_FILE_INSTANCE;
this.clusterName = seataConfig.getConfig(REDIS_FILEKEY_PREFIX + REGISTRY_CLUSTER_KEY, DEFAULT_CLUSTER);
String password = seataConfig.getConfig(getRedisPasswordFileKey());
String serverAddr = seataConfig.getConfig(getRedisAddrFileKey());
String[] serverArr = serverAddr.split(":");
String host = serverArr[0];
int port = Integer.parseInt(serverArr[1]);
int db = seataConfig.getInt(getRedisDbFileKey());
GenericObjectPoolConfig redisConfig = new GenericObjectPoolConfig();
redisConfig.setTestOnBorrow(seataConfig.getBoolean(REDIS_FILEKEY_PREFIX + "test.on.borrow", true));
redisConfig.setTestOnReturn(seataConfig.getBoolean(REDIS_FILEKEY_PREFIX + "test.on.return", false));
redisConfig.setTestWhileIdle(seataConfig.getBoolean(REDIS_FILEKEY_PREFIX + "test.while.idle", false));
int maxIdle = seataConfig.getInt(REDIS_FILEKEY_PREFIX + "max.idle", 0);
if (maxIdle > 0) {
redisConfig.setMaxIdle(maxIdle);
}
int minIdle = seataConfig.getInt(REDIS_FILEKEY_PREFIX + "min.idle", 0);
if (minIdle > 0) {
redisConfig.setMinIdle(minIdle);
}
int maxActive = seataConfig.getInt(REDIS_FILEKEY_PREFIX + "max.active", 0);
if (maxActive > 0) {
redisConfig.setMaxTotal(maxActive);
}
int maxTotal = seataConfig.getInt(REDIS_FILEKEY_PREFIX + "max.total", 0);
if (maxTotal > 0) {
redisConfig.setMaxTotal(maxTotal);
}
int maxWait = seataConfig.getInt(REDIS_FILEKEY_PREFIX + "max.wait",
seataConfig.getInt(REDIS_FILEKEY_PREFIX + "timeout", 0));
if (maxWait > 0) {
redisConfig.setMaxWaitMillis(maxWait);
}
int numTestsPerEvictionRun = seataConfig.getInt(REDIS_FILEKEY_PREFIX + "num.tests.per.eviction.run", 0);
if (numTestsPerEvictionRun > 0) {
redisConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
}
int timeBetweenEvictionRunsMillis = seataConfig.getInt(
REDIS_FILEKEY_PREFIX + "time.between.eviction.runs.millis", 0);
if (timeBetweenEvictionRunsMillis > 0) {
redisConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
}
int minEvictableIdleTimeMillis = seataConfig.getInt(REDIS_FILEKEY_PREFIX + "min.evictable.idle.time.millis",
0);
if (minEvictableIdleTimeMillis > 0) {
redisConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
}
if (StringUtils.isNullOrEmpty(password)) {
jedisPool = new JedisPool(redisConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, db);
} else {
jedisPool = new JedisPool(redisConfig, host, port, Protocol.DEFAULT_TIMEOUT, password, db);
}
}
/**
* Gets instance.
*
* @return the instance
*/
static RedisRegistryServiceImpl getInstance() {
if (instance == null) {
synchronized (RedisRegistryServiceImpl.class) {
if (instance == null) {
instance = new RedisRegistryServiceImpl();
}
}
}
return instance;
}
@Override
public void register(InetSocketAddress address) {
NetUtil.validAddress(address);
String serverAddr = NetUtil.toStringAddress(address);
try (Jedis jedis = jedisPool.getResource()) {
jedis.hset(getRedisRegistryKey(), serverAddr, ManagementFactory.getRuntimeMXBean().getName());
jedis.publish(getRedisRegistryKey(), serverAddr + "-" + RedisListener.REGISTER);
}
}
@Override
public void unregister(InetSocketAddress address) {
NetUtil.validAddress(address);
String serverAddr = NetUtil.toStringAddress(address);
try (Jedis jedis = jedisPool.getResource()) {
jedis.hdel(getRedisRegistryKey(), serverAddr);
jedis.publish(getRedisRegistryKey(), serverAddr + "-" + RedisListener.UN_REGISTER);
}
}
@Override
public void subscribe(String cluster, RedisListener listener) {
String redisRegistryKey = REDIS_FILEKEY_PREFIX + cluster;
LISTENER_SERVICE_MAP.computeIfAbsent(cluster, key -> new ArrayList<>())
.add(listener);
threadPoolExecutor.submit(() -> {
try {
try (Jedis jedis = jedisPool.getResource()) {
jedis.subscribe(new NotifySub(LISTENER_SERVICE_MAP.get(cluster)), redisRegistryKey);
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
});
}
@Override
public void unsubscribe(String cluster, RedisListener listener) {
}
@Override
public List<InetSocketAddress> lookup(String key) {
String clusterName = getServiceGroup(key);
if (clusterName == null) {
return null;
}
if (!LISTENER_SERVICE_MAP.containsKey(clusterName)) {
String redisRegistryKey = REDIS_FILEKEY_PREFIX + clusterName;
Map<String, String> instances;
try (Jedis jedis = jedisPool.getResource()) {
instances = jedis.hgetAll(redisRegistryKey);
}
if (instances != null && !instances.isEmpty()) {
Set<InetSocketAddress> newAddressSet = instances.keySet().stream()
.map(NetUtil::toInetSocketAddress)
.collect(Collectors.toSet());
CLUSTER_ADDRESS_MAP.put(clusterName, newAddressSet);
}
subscribe(clusterName, msg -> {
String[] msgr = msg.split("-");
String serverAddr = msgr[0];
String eventType = msgr[1];
switch (eventType) {
case RedisListener.REGISTER:
CLUSTER_ADDRESS_MAP.get(clusterName).add(NetUtil.toInetSocketAddress(serverAddr));
break;
case RedisListener.UN_REGISTER:
CLUSTER_ADDRESS_MAP.get(clusterName).remove(NetUtil.toInetSocketAddress(serverAddr));
break;
default:
throw new ShouldNeverHappenException("unknown redis msg:" + msg);
}
});
}
return new ArrayList<>(CLUSTER_ADDRESS_MAP.getOrDefault(clusterName, Collections.emptySet()));
}
@Override
public void close() throws Exception {
jedisPool.destroy();
}
private static class NotifySub extends JedisPubSub {
private final List<RedisListener> redisListeners;
/**
* Instantiates a new Notify sub.
*
* @param redisListeners the redis listeners
*/
NotifySub(List<RedisListener> redisListeners) {
this.redisListeners = redisListeners;
}
@Override
public void onMessage(String key, String msg) {
for (RedisListener listener : redisListeners) {
listener.onEvent(msg);
}
}
}
private String getRedisRegistryKey() {
return REDIS_FILEKEY_PREFIX + clusterName;
}
private String getRedisAddrFileKey() {
return REDIS_FILEKEY_PREFIX + PRO_SERVER_ADDR_KEY;
}
private String getRedisPasswordFileKey() {
return REDIS_FILEKEY_PREFIX + REDIS_PASSWORD;
}
private String getRedisDbFileKey() {
return REDIS_FILEKEY_PREFIX + REDIS_DB;
}
}

View File

@@ -0,0 +1 @@
io.seata.discovery.registry.redis.RedisRegistryProvider