Add support for redis configuration file to determine viable redis master and slave connections, that can be set to be region-dependant. Fix leakage issue with command manager with not properly returning broken jedis resources. Funnel all redis connection requests through ServerManager for easier configuration use.

This commit is contained in:
Ty Sayers 2015-05-16 13:01:21 -04:00
parent cf4caf8fc0
commit a8b0dddf17
4 changed files with 155 additions and 17 deletions

View File

@ -5,6 +5,7 @@ import mineplex.serverdata.servers.ServerManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -76,10 +77,19 @@ public class Utility
{
currentTime = Long.parseLong(jedis.time().get(0));
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
pool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (pool != null)
{
pool.returnResource(jedis);
}
}
return currentTime;
}
@ -98,10 +108,19 @@ public class Utility
{
currentTime = Long.parseLong(jedis.time().get(0));
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
pool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (pool != null)
{
pool.returnResource(jedis);
}
}
return currentTime * 1000;
}
@ -134,7 +153,9 @@ public class Utility
{
if (_slavePool == null)
{
_slavePool = generatePool(ServerManager.getSlaveConnection());
ConnectionData slave = ServerManager.getSlaveConnection();
_slavePool = generatePool(slave);
}
return _slavePool;

View File

@ -8,6 +8,7 @@ import mineplex.serverdata.servers.ServerManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;
public class ServerCommandManager
{
@ -55,15 +56,19 @@ public class ServerCommandManager
{
jedis.psubscribe(new ServerCommandListener(), SERVER_COMMANDS_CHANNEL + ":*");
}
catch (Exception exception)
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_readPool.returnBrokenResource(jedis);
}
finally
{
if (_readPool != null)
{
_readPool.returnResource(jedis);
}
}
}
};
thread.start();
@ -87,15 +92,20 @@ public class ServerCommandManager
String serializedCommand = Utility.serialize(serverCommand);
jedis.publish(SERVER_COMMANDS_CHANNEL + ":" + commandType, serializedCommand);
}
catch (Exception exception)
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_writePool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (_writePool != null)
{
_writePool.returnResource(jedis);
}
}
}
}).start();
}

View File

@ -0,0 +1,42 @@
package mineplex.serverdata.redis;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import mineplex.serverdata.servers.ConnectionData;
public class RedisConfig
{
private static Random random = new Random();
private ConnectionData _masterConnection;
private List<ConnectionData> _slaveConnections;
public RedisConfig(ConnectionData master, List<ConnectionData> slaves)
{
_masterConnection = master;
_slaveConnections = slaves;
}
public ConnectionData getConnection()
{
return getConnection(true);
}
public ConnectionData getConnection(boolean writeable)
{
if (writeable)
{
return _masterConnection;
}
else
{
int index = random.nextInt(_slaveConnections.size());
return _slaveConnections.get(index);
}
}
}

View File

@ -1,10 +1,15 @@
package mineplex.serverdata.servers;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import mineplex.serverdata.Region;
import mineplex.serverdata.redis.RedisConfig;
import mineplex.serverdata.redis.RedisServerRepository;
/**
@ -14,13 +19,8 @@ import mineplex.serverdata.redis.RedisServerRepository;
*/
public class ServerManager
{
// Connection host to server database
private static final String DATABASE_HOST = "10.33.53.16";
// Ports associated with slave redis instances
private static final int[] SLAVE_PORTS = {6377, 6378, 6380, 6381, 6382};
private static Random random = new Random();
// Configuration determining connection information
private static RedisConfig _config = getConfig();
// The cached repository instances
private static Map<Region, ServerRepository> repositories = new HashMap<Region, ServerRepository>();
@ -56,7 +56,7 @@ public class ServerManager
*/
public static ConnectionData getMasterConnection()
{
return new ConnectionData(DATABASE_HOST, 6379);
return getConnection(true);
}
/**
@ -65,7 +65,72 @@ public class ServerManager
*/
public static ConnectionData getSlaveConnection()
{
int port = SLAVE_PORTS[random.nextInt(SLAVE_PORTS.length)];
return new ConnectionData(DATABASE_HOST, port);
return getConnection(false);
}
public static ConnectionData getConnection(boolean writeable)
{
System.out.println("fETChing");
return getConfig().getConnection(writeable);
}
public static RedisConfig getConfig()
{
System.out.println("LOADING CONFIG");
if (_config == null)
{
try
{
System.out.println("STARTING");
File configFile = new File("redis-config.dat");
if (configFile.exists())
{
List<String> lines = Files.readAllLines(configFile.toPath());
ConnectionData master = deserializeConnection(lines.get(0));
List<ConnectionData> slaves = new ArrayList<ConnectionData>();
for (int i = 1; i < lines.size(); i++)
{
ConnectionData slave = deserializeConnection(lines.get(i));
slaves.add(slave);
}
System.out.println("LOADED " + (master != null) + " " + slaves.size());
_config = new RedisConfig(master, slaves);
System.out.println("Master connection " + master.getHost() + " port " + master.getPort());
}
else
{
System.out.println("DOES NOT EXIST AT PATH " + configFile.toPath().toString());
}
}
catch (Exception exception)
{
exception.printStackTrace();
System.out.println("---Unable To Parse Redis Configuration File---");
}
}
return _config;
}
private static ConnectionData deserializeConnection(String line)
{
String[] args = line.split(" ");
if (args.length == 2)
{
String ip = args[0];
int port = Integer.parseInt(args[1]);
return new ConnectionData(ip, port);
}
return null;
}
}