为什么我的mycraft bukkit插件会出现mysql延迟?

时间:2014-06-17 23:17:54

标签: java mysql minecraft bukkit

我用mysql制作了一个bukkit插件,我需要知道为什么我的滞后每当这个代码运行时我运行我的系统上的服务器和带有hostgator的mysql服务器继承我的代码

    openConnection();
                try{
                    int level1 = 0;

                    if(playerDataConatinsPlayer(p)){
                        PreparedStatement sql = connection.prepareStatement("SELECT level FROM `player_data` WHERE player=?;");
                        sql.setString(1, p.getName());

                        ResultSet result = sql.executeQuery();

                        result.next();

                        level1 = result.getInt("level");

                        PreparedStatement levelUpdate = connection.prepareStatement("UPDATE `player_data` SET level=? WHERE player=?;");

                        levelUpdate.setInt(1, level1+1);
                        levelUpdate.setString(2, p.getName());
                        levelUpdate.executeUpdate();

                        levelUpdate.close();
                        sql.close();
                        result.close();
                    }else{
                        PreparedStatement newPlayer = connection.prepareStatement("INSERT INTO `player_data` values(?,0,1,0);");
                        newPlayer.setString(1, p.getName());

                        newPlayer.execute();
                        newPlayer.close();
                    }

                }catch(Exception e1){
                    e1.printStackTrace();
                }finally{
                    closeConnection();
                }

这是我的openconnection方法

    public synchronized static void openConnection(){
    try{
        connection = DriverManager.getConnection(""); //i know its empty cause i dont wanna give that info out
    }catch(Exception e){
        e.printStackTrace();
    }
}

继承我的密切联系

public synchronized static void closeConnection(){
    try{
        connection.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}

2 个答案:

答案 0 :(得分:1)

您可以采取一些措施来加快查询延迟:

  • 如果您的应用是查询密集型的,请使用持久连接并保持打开状态,而不是每次需要访问数据库时都打开新连接。

  • 在本地运行MySQL服务器以加快连接速度。

  • 为表格的搜索字段编制索引(例如player上的player_data),以便让搜索速度更快。

  • 在具有SSD驱动器和大量RAM的功能强大的专用计算机上运行MySQL服务器,并在my.cnf上设置正确的参数(工作线程,最大进程,最大连接数,内存限制,缓冲区大小)利用该RAM和处理能力,加快搜索和处理时间。像this question and answers这样的东西可以帮助你进行内存设置,但你能做的最好的就是你自己的,详尽的在线研究和测试。做你的作业!

  • 使用某种缓存系统加快阅读速度(如memcached)。

  • 如果您的应用是数据密集型的,并且必须支持大量连接,请获得更高的带宽,甚至考虑设置群集以平衡负载。

  • 减少查询次数!您不需要两次查询数据库以提高级别!

尝试:

if (playerDataContainsPlayer(p)){

    PreparedStatement levelUpdate = connection.prepareStatement(
        "UPDATE player_data SET level=level+1 WHERE player=?;"
    );
    levelUpdate.setString(1, p.getName());
    levelUpdate.executeUpdate();
    levelUpdate.close();
    sql.close();

} else {
    ...
}

答案 1 :(得分:1)

听起来好像是在主服务器Thread上运行查询。如果您的SQL服务器不在本地计算机上,您真的不应该这样做。

有一个read of the tutorial关于如何在后台运行更多CPU密集型或更长时间运行的任务,以避免此类性能损失。

您需要做的是将代码放入BukkitRunnable

public class ExampleTask extends BukkitRunnable {

    private final JavaPlugin plugin;

    public ExampleTask(JavaPlugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public void run() {
        // Put your task's code here
    }

}

然后,为了让你在自己的线程中运行代码,让主服务器Thread不间断地处理游戏,请像这样调用你的任务:

BukkitTask task = new ExampleTask(this.plugin).runTask(this.plugin);

这应该避免你提到的滞后。请注意并发问题,并注意Bukkit的文档指出在异步任务中不应发生Bukkit API交互。因此,只需在Task中执行查询和任何验证/解析,并将结果传递回服务器线程,以便在需要时在游戏中使用。