[Change] CacheStore-Redis 使用 Json 代替 Properties 作为 Redis 连接配置的存储格式;

[Add] RedisConnectionProperties 添加 Redis 连接配置对象;
[Change] RedisConnectionPool 调整 JedisPool 配置读取来源的类型(URL -> RedisConnectionProperties);
[Change] RedisCacheStoreFactory 更改 Redis 连接配置的读取形式;
[Add] RedisUtils 添加 'PROPERTIES_FILE_NAME' 常量;
[Add] com.google.code.gson:gson 添加 Gson 依赖项, 以转换 Json 为 RedisConnectionProperties 对象;
This commit is contained in:
LamGC 2021-01-15 20:18:20 +08:00
parent a090abc9a4
commit 48404fc0fc
Signed by: LamGC
GPG Key ID: 6C5AE2A913941E1D
5 changed files with 190 additions and 44 deletions

View File

@ -52,6 +52,12 @@
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
</project>

View File

@ -17,7 +17,7 @@
package net.lamgc.cgj.bot.cache.redis;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
@ -25,10 +25,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
/**
*
@ -39,19 +36,11 @@ public class RedisCacheStoreFactory implements CacheStoreFactory {
private final static Logger log = LoggerFactory.getLogger(RedisCacheStoreFactory.class);
private final static String PROP_HOST = "redis.host";
private final static String PROP_PORT = "redis.port";
private final static String PROP_USE_SSL = "redis.useSSL";
private final static String PROP_USERNAME = "redis.username";
private final static String PROP_PASSWORD = "redis.password";
private final static String PROP_DATABASE = "redis.databaseId";
private final static String PROP_CLIENT_NAME = "redis.clientName";
private final RedisConnectionPool connectionPool = new RedisConnectionPool();
@Override
public void initial(File dataDirectory) {
final File propertiesFile = new File(dataDirectory, "redis.properties");
final File propertiesFile = new File(dataDirectory, RedisUtils.PROPERTIES_FILE_NAME);
if (!propertiesFile.exists()) {
log.warn("未找到 Redis 配置文件, 使用默认配置.");
return;
@ -59,27 +48,14 @@ public class RedisCacheStoreFactory implements CacheStoreFactory {
log.warn("Redis 配置文件不是一个文件, 使用默认配置.");
return;
}
Properties properties = new Properties();
try (Reader propertiesReader = new BufferedReader(
new InputStreamReader(new FileInputStream(propertiesFile), StandardCharsets.UTF_8))) {
properties.load(propertiesReader);
RedisConnectionProperties properties = new Gson()
.fromJson(propertiesReader, RedisConnectionProperties.class);
connectionPool.setConnectionProperties(properties);
log.debug("Redis 配置文件已成功读取: {}", properties);
} catch (IOException e) {
log.error("读取 Redis 配置文件时发生异常", e);
}
try {
String queryString = "/?" + "ssl=" + properties.getProperty(PROP_USE_SSL, "false") + '&' +
"user=" + Strings.nullToEmpty(properties.getProperty(PROP_USERNAME)) + '&' +
"passwd=" + Strings.nullToEmpty(properties.getProperty(PROP_PASSWORD)) + '&' +
"database=" + properties.getProperty(PROP_DATABASE, "0") + '&' +
"clientName=" + Strings.nullToEmpty(properties.getProperty(PROP_CLIENT_NAME));
URL url = new URL("redis",
properties.getProperty(PROP_HOST, "localhost"),
Integer.parseInt(properties.getProperty(PROP_PORT, "6379")),
queryString);
connectionPool.setConnectionUrl(url);
} catch (MalformedURLException e) {
log.error("构造连接 URL 时发生异常", e);
log.error("读取 Redis 配置文件时发生异常, 将使用默认配置连接 Redis.", e);
}
}

View File

@ -17,17 +17,14 @@
package net.lamgc.cgj.bot.cache.redis;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
@ -42,13 +39,18 @@ class RedisConnectionPool {
private final static Logger log = LoggerFactory.getLogger(RedisConnectionPool.class);
private final AtomicReference<JedisPool> POOL = new AtomicReference<>();
private final AtomicReference<URL> CONNECTION_URL = new AtomicReference<>();
private final AtomicReference<RedisConnectionProperties> connectionProperties = new AtomicReference<>();
private final Map<LuaScript, String> scriptMap = new HashMap<>();
public synchronized void setConnectionUrl(URL connectionUrl) {
if(CONNECTION_URL.get() != null) {
CONNECTION_URL.set(connectionUrl);
public RedisConnectionPool() {
Runtime.getRuntime().addShutdownHook(new Thread(this::close,
"Shutdown-RedisConnectionPool@" + Integer.toHexString(this.hashCode())));
}
public synchronized void setConnectionProperties(RedisConnectionProperties properties) {
if(connectionProperties.get() != null) {
connectionProperties.set(properties);
}
}
@ -60,12 +62,35 @@ class RedisConnectionPool {
JedisPoolConfig config = new JedisPoolConfig();
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
URL connectionUrl = CONNECTION_URL.get();
if (connectionUrl == null) {
RedisConnectionProperties properties = connectionProperties.get();
if (properties == null) {
jedisPool = new JedisPool(config);
} else {
jedisPool = new JedisPool(config, connectionUrl.getHost(), connectionUrl.getPort(),
connectionUrl.getPath().toLowerCase().contains("ssl=true"));
String userName = properties.getUserName();
if (Strings.isNullOrEmpty(userName)) {
jedisPool = new JedisPool(config,
properties.getHost(),
properties.getPort(),
properties.getConnectionTimeout(),
properties.getSocketTimeout(),
properties.getPassword(),
properties.getDatabaseId(),
properties.getClientName(),
properties.enableSsl()
);
} else {
jedisPool = new JedisPool(config,
properties.getHost(),
properties.getPort(),
properties.getConnectionTimeout(),
properties.getSocketTimeout(),
userName,
properties.getPassword(),
properties.getDatabaseId(),
properties.getClientName(),
properties.enableSsl()
);
}
}
POOL.set(jedisPool);
loadScript();
@ -198,4 +223,10 @@ class RedisConnectionPool {
}
public void close() {
JedisPool jedisPool = POOL.get();
if (jedisPool != null && !jedisPool.isClosed()) {
jedisPool.close();
}
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright (C) 2021 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.redis;
import com.google.common.base.Strings;
import redis.clients.jedis.Protocol;
/**
* Redis 连接配置对象.
* @author LamGC
*/
@SuppressWarnings({"FieldCanBeLocal", "unused"})
public class RedisConnectionProperties {
private int connectionTimeout = Protocol.DEFAULT_TIMEOUT;
private int socketTimeout = Protocol.DEFAULT_TIMEOUT;
private String host = Protocol.DEFAULT_HOST;
private int port = Protocol.DEFAULT_PORT;
private boolean ssl = false;
private String userName = null;
private String password = null;
private int databaseId = Protocol.DEFAULT_DATABASE;
private String clientName = null;
@Override
public String toString() {
int showPasswordLength = password.length() / 4;
return "RedisConnectionProperties{" +
"connectionTimeout=" + connectionTimeout +
", socketTimeout=" + socketTimeout +
", host='" + host + '\'' +
", port=" + port +
", ssl=" + ssl +
", userName='" + userName + '\'' +
", password='" + password.substring(0, showPasswordLength) +
Strings.repeat("*", password.length() - showPasswordLength) + '\'' +
", databaseId=" + databaseId +
", clientName='" + clientName + '\'' +
'}';
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public int getSocketTimeout() {
return socketTimeout;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public boolean enableSsl() {
return ssl;
}
public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}
public int getDatabaseId() {
return databaseId;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public void setDatabaseId(int databaseId) {
this.databaseId = databaseId;
}
public void setHost(String host) {
this.host = host;
}
public void setPassword(String password) {
this.password = password;
}
public void setPort(int port) {
this.port = port;
}
public void setSocketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
}
public void setEnableSsl(boolean ssl) {
this.ssl = ssl;
}
public void setUserName(String userName) {
this.userName = userName;
}
}

View File

@ -49,6 +49,11 @@ public class RedisUtils {
*/
public final static String KEY_SEPARATOR = ":";
/**
* Redis 组件配置文件名.
*/
public final static String PROPERTIES_FILE_NAME = "redis.properties.json";
/**
* 检查字符串返回结果是否为操作成功.
* @param result 字符串返回结果.