高流量php ajax聊天设计选项

时间:2016-06-05 03:28:15

标签: php jquery mysql ajax chat

我有一个High Traffic网站,我已经实现了网络聊天功能。 问题是,我需要在同一页面上同时在线拥有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 个答案:

答案 0 :(得分:0)

提高性能的一些建议。其中一些已被建议,但我会包括它们,以便您有一个完整的目录。在这里,他们没有特别的顺序:

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

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

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

了解更多有关Comet的信息

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

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

6)考虑将刷新时间从1秒减少到2到5秒之间。用户无法区分1到2秒之间的差异,而使用聊天应用程序,输入大多数响应需要大约5秒钟。在5秒时,一半的消息将在不到2.5秒的时间内传送,另一半的消息将在2.5到5秒之间传送。值得研究的是,对5秒轮询间隔的简单更改会将服务器开销降低5倍,这可能足以支持您当前的用户组而无需更改代码。