【问题标题】:PHP Real-time chat back up server production issuesPHP实时聊天备份服务器生产问题
【发布时间】:2016-02-17 15:06:03
【问题描述】:

我已经构建了一个由 PubNub 提供支持的实时聊天应用程序。目前,我允许仅通过 PubNub 直接向用户发送和接收消息。但是,我希望通过首先将这些消息推送到我的服务器/db(内置 PHP 和 MySQL)来“保存”这些消息,然后在成功进入后通过 PubNub 发送给用户。

我目前的 PHP 服务器的设置接受请求并将其定向到正确的 case 语句,因为定义的 action 传递到请求中:

<?php

switch($action) 
{

    case "userLogin": 
        ...
    break;  


    case "signUpUser":
        ...
    break;  

        ...

    case "syncWithServer":
        ...
    break;  

?>

每个 case 语句允许数据库插入和更新,并在给定数据传递的情况下在操作成功后返回。

对于一个详细的例子,我们有下面的sendMessage 案例。必须插入数据,然后返回最新的sync_id,对于刚刚插入的消息,然后发送回用户,以保持一切同步:

case "sendMessage":

    // Output is: {"message_sync_id":"4"}
    if ($userId = authenticateUser($db, $username, $password, $gcmregid)) 
    {   
        //echo "passed1";
        if (isset($_REQUEST['to_user_sync_id']))
        {
            //echo "passed2";a
             $touserid = $_REQUEST['to_user_sync_id'];               
             $unescapedMessage = $_REQUEST['message_text'];
             $message = mysql_real_escape_string($unescapedMessage);             
             $campaign = $_REQUEST['shared_campaign_id'];
             $location = $_REQUEST['shared_campaign_location_id'];

             if($stmt1 = $db->prepare("INSERT INTO `messages` (`message_sync_id`,`from_user_sync_id`, `to_user_sync_id`, sent_dt, `message_text`,`shared_campaign_id`,`shared_campaign_location_id`) 
                                      SELECT 
                                      CASE 
                                      WHEN max(message_sync_id) is null
                                      THEN 0
                                      ELSE max(message_sync_id)
                                      END + 1
                                      , ?
                                      , ?
                                      , NOW()
                                      , ?
                                      , ?
                                      , ?
                                      from messages;"))
             {
                $stmt1->bind_param("sssss", $userId,$touserid,$message,$campaign,$location);
                $stmt1->execute();
                $stmt1->close();

                $sqlMaxSyncId = "select max(message_sync_id) as message_sync_id from messages;";

                if($resultMaxID = $db->query($sqlMaxSyncId))
                {

                    $row = $resultMaxID->fetch_assoc();

                    $out = json_encode(array('message_sync_id' => $row['message_sync_id']));

                    error_log("sendMessage", 3 , $row['message_sync_id']);

                }
                else
                {
                    $out = FAILED;
                }           

             }
             else
             {
                $out = FAILED;
             }

        }
        else
        {
            $out = FAILED;
        }   
    }
    else
    {
        $out = FAILED;
    }   
break;

鉴于聊天应用程序需要非常低的延迟,这个公式可能会遇到哪些生产问题,而我在非常低使用率测试期间可能看不到?

如何缓解这些问题?

Heroku 是否适合部署这样的服务器?

【问题讨论】:

    标签: php mysql apache heroku


    【解决方案1】:

    如果许多用户同时聊天,那么保存到数据库(我猜是“syncWithSErver”)可能会成为瓶颈,该 case 语句会执行数据库查询,数据库会过载,因此,减慢消息发送速度。

    不要直接保存它们,而是使用任何内存缓存,例如 memcache 或 redis 来临时存储它们,并使用后台作业(例如,附加到 cron 的 php 脚本)来继续保存它们。

    【讨论】:

    • 主要问题是必须插入消息,然后检索该消息的最新sync_id,然后返回给用户,然后通过PubNub发送。如果我按照您概述的方式完成,则消息将不同步。查看更新
    • 如果您通过其他方法(例如随机散列)生成同步ID,那么您不需要在将结果发送回客户端之前执行插入查询
    • 我已经审查了几个选项,我认为我将迁移到 Firebase。你有经验吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 2015-03-11
    • 2014-03-02
    • 1970-01-01
    • 2016-02-25
    • 2014-06-08
    • 2021-04-18
    相关资源
    最近更新 更多