简体   繁体   中英

High traffic php ajax chat design options

I have an High Traffic website, and I have implemented a webchat feature. The problem is, I need to have 10k to 20k users online at the same time on the same page. I have a 16gb Ram / 8 cores / ssd server, but when I reach about 7k concurrent users, the server goes down.

Now i'm using php/ajax/mysql chat, asking the server for new messages every 1 second - I know I shouldn't do this, so, what can I do?

It has been suggested to use the timestamp on a file and check the file instead of MySQL? I'm not sure if that's a good solution.

Here is my Ajax code:

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);
}

This is the PHP code:

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
        } 
    }
}

I am using PDO, and the called functions are MySQL queries.

A few suggestions to improve performance. Some of these have already been suggested, but I'll include them, so that you have a complete catalog. Here they are, in no particular order:

1) Serve JSON from PHP, and render the HTML for the query in the client. This should save you a considerable amount of processing time and bandwidth.

2) Minimize the number of fields that you query from MySQL, as each field has to be transferred and marshaled through PDO.

3) Consider using Comet to push messages to the Ajax clients over persistent connections. You can read more about Comet at http://www.webreference.com/programming/javascript/rg28/index.html and http://www.zeitoun.net/articles/comet_and_php/start

4) Consider caching your MySQL results in a Memcached or Redis . This will consume some additional memory, but will dramatically decrease the overall overhead, and take an enormous load off of MySQL. The biggest traffic sites in the world use these techniques to reduce overhead and significantly increase the number of concurrent users.

5) Find a way to use HTML5 websockets. Webchat is one of the driving applications of HTML5 websocket, so this problem is ideally suited to the technology.

6) Consider reducing the refresh time from 1 second to between 2 and 5 seconds. Users can't tell the difference between 1 and 2 seconds, and with a chat application, it takes considerably longer than 5 seconds to type most responses. At 5 seconds, half of the messages will be delivered in less than 2.5 seconds, and the other half between 2.5 and 5 seconds, on average. It's worth investigating, as a simple change to a 5 second polling interval would reduce your server overhead by 5X, which may be enough to support your current set of users with no code changes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM