高流量 php ajax 聊天设计选项

High traffic php ajax chat design options

我有一个高流量网站,并且我实现了网络聊天功能。 问题是,我需要在同一页面上同时有 10k 到 20k 用户在线。我有一个 16gb Ram/8 核/ssd 服务器,但是当我达到大约 7k 并发用户时,服务器出现故障。

现在我正在使用 php/ajax/mysql 聊天,每 1 秒向服务器询问一次新消息 - 我知道我不应该这样做,所以,可以我有吗?

有人建议在文件上使用时间戳并检查文件而不是 MySQL?我不确定这是否是一个好的解决方案。

这是我的 Ajax 代码:

function verifychat() {
    //RUN THIS EVERY 1 SEC
    setTimeout(function () {
        // LAST MESSAGE ID
        var lastid = $(".chat-message-list .line:last-child").attr("data-row-id");

        // PAGE ID
        var channel = "<?php echo $channelname; ?>";

        $.ajax({
            type: "GET",
            url: "includes/ajax/channelchat.php",
            data: "verify&lastid="+lastid+"&channel="+channel,
            cache: false,
            success: function (html) {

                // IF PHP ANSWER IS "old"
                // THE ANSWER TELL IF HAVE NEW MESSAGES OR NOT
                if ($.trim(html) != "old") {

                    //APPEND TO BODY
                    $(".chat-message-list").append(html);
                    $(".chat-message-list .line:hidden").fadeIn()
                    setTimeout(function () {
                        $('.chat-message-list').scrollTop($('.chat-message-list')[0].scrollHeight);
                    }, 100);
                };
            },
            complete: verifychat
        });
    }, 1000);
}

这是 PHP 代码:

if (isset($_GET['verify'])) {
    //VERIFY IF HAS NEW MESSAGES // RETURN BOOLEAN
    $doit = $users->channel_chat_last_message($_GET["channel"], $_GET["lastid"]);

    //NO! NO! No comments about this "== false" ok? I like this way :)
    if ($doit == false) {
        echo "old";
    }else{
        foreach ($doit as $row){ ?>

        //GET THIS FOREACH USER INFO
        <?php $uinfo = $system->getLine("`id`, `rank`, `username`, `image_status`, `image_location`, `gender`", "users", "id", $row["user"]); ?>

        <div style="display:none;" class="line data-row-id="<?php echo $row["id"] ?>">      
            <div class="user">
                <?php echo $uinfo["username"]; ?>
            </div>

            <?php if ($general->logged_in() === true && $user["rank"] == 5){ ?>
            <div class="delete-message" data-row-id="<?php echo $row["id"] ?>"><i class="fa fa-close"></i></div>
            <?php } ?>

            <div class="message">
                <?php echo $row["content"]; ?>
            </div>
        </div>

        <?php
        } 
    }
}

我用的是PDO,调用的函数是MySQL个查询

一些提高性能的建议。其中一些已经被建议,但我会把它们包括在内,这样你就有了一个完整的目录。它们在这里,排名不分先后:

1) 从 PHP 服务 JSON,并在客户端中为查询呈现 HTML。这应该可以为您节省大量的处理时间和带宽。

2) 尽量减少从 MySQL 查询的字段数,因为每个字段都必须通过 PDO 传输和编组。

3) 考虑使用 Comet 通过持久连接将消息推送到 Ajax 客户端。您可以在 http://www.webreference.com/programming/javascript/rg28/index.html and http://www.zeitoun.net/articles/comet_and_php/start

阅读更多关于彗星的信息

4) 考虑在 Memcached or Redis 中缓存您的 MySQL 结果。这将消耗一些额外的内存,但会显着降低总体开销,并减轻 MySQL 的巨大负载。世界上最大的流量站点使用这些技术来减少开销并显着增加并发用户数。

5) 找到使用 HTML5 websockets 的方法。 Webchat 是 HTML5 websocket 的驱动应用程序之一,因此这个问题非常适合该技术。

6) 考虑将刷新时间从 1 秒减少到 2 到 5 秒之间。用户无法分辨 1 秒和 2 秒之间的区别,而对于聊天应用程序,键入大多数响应所花费的时间远远超过 5 秒。在 5 秒时,一半消息将在不到 2.5 秒内送达,另一半消息平均在 2.5 到 5 秒之间送达。值得研究,因为对 5 秒轮询间隔的简单更改会将您的服务器开销减少 5 倍,这可能足以支持您当前的用户集而无需更改代码。