我应该在社交网络应用程序中使用WebSockets,还是PHP / AJAX就足够了?

时间:2015-07-07 09:07:52

标签: php websocket

我希望您对项目有所了解。我开始自己的方式,现在或将来慢慢地提出许多差距和问题,他们将会产生很大的问题。

系统将具有通知系统,朋友系统,消息系统(私人),并且通常具有这样的系统。我设置的所有这些: jQuery,PHP,mysqli往返避免冗长。我正在谈论标题所说的内容。

如果所有这些都做了简单的PHP代码并且发布并获得3-4个在线用户的方法将是惊人的!问题是,当我有几个用户时,我该怎么做才能更好地利用服务器的资源?所以我开始寻找更多,并发现像这样的socket.io

我只是希望有人告诉我谁更了解什么是最好的。想想更新通知系统现在如何工作。 jQuery有帖子并且每3-5秒重复一次,但这绝不是正确的。

1 个答案:

答案 0 :(得分:0)

如果您的目标是设置高度可扩展的通知服务,那么可能不会。

这不是严格的否,因为除了速度之外还有其他因素需要考虑,但是当谈到速度时,请继续阅读。

WebSockets确实为用户提供了一致的开放式双向连接,就其本质而言,非常快。此外,客户不需要请求新信息;当任何一方认为适合发送时发送。

但是,就生成内容的成本而言,连接本身所节省的时间可以忽略不计。您为检查新通知而进行了多少次数据库调用?您生成多少结构化数据以让客户知道更改通知图标?您从磁盘或网络中读取数据的次数是多少次?

使用任何WebSocket服务器时,这些相同的成本不会消失;它只是使一种缓解技术更加明显:将用户的通知状态保存在内存中,并在通知发生变化时对其进行更新,以防止昂贵的访问磁盘,数据库以及整个服务器的本地网络。

已知的经过验证的技术可以减少快速更改网络内容的时间成本:

反向代理(Varnish-Cache)

坐在端口80上,充当非常瘦的Web服务器。如果请求是针对代理的RAM内缓存中的某些内容,则会将请求发送到" real"网络服务器。这对于提供很少更改的内容(例如图像和脚本)尤其有用,并且对于内容大多数保持相同但具有一些无法缓存的小元素具有边缘包含...例如,在电子商务网站上,产品的描述,图像等都可以被缓存,但是显示用户购物车内容的HTML不能,所以理想的边缘选择包括。

这将有助于大大减少系统负载,因为使用磁盘IO的请求要少得多,这是一种比内存IO更有限的资源。 (硬盘驱动器在寻找cat jpeg的同时无法寻找数据库资源。)

内存键值存储(Memcached)

在创建可扩展的通知系统方面,这可能会给你带来最大的好处。

还有其他内存中的键值存储系统,但是这个存储系统内置于PHP中,而不仅仅是一次,而是两次! (在PHP核心开发的传统中,他们决定考虑破坏的版本而不是实际标记该系统已弃用并抛出适当的警告等,而不是修复破坏的实现,这会让人们停止使用破坏system.mysql_ v.mysqli_,我看着你......)(使用memcache d 版本,而不是memcache。)

无论如何,它很简单:当你经常进行数据库,文件系统或网络调用时,将结果存储在Memcached中。当您通过网络更新记录,文件或推送数据,并且该数据用于存储在Memcached中的结果时,请更新Memcached。

然后,当您需要数据时,首先检查Memcached。如果它不存在,则然后进行长时间,昂贵的磁盘访问,数据库访问或网络访问。

请记住,Memcached不是持久性数据存储区...也就是说,如果重新启动服务器,Memcached将完全恢复为空。您仍然需要持久数据存储,因此仍然使用您的数据库,文件和网络。此外,Memcached专门设计为易失性存储,仅快速提供访问最多和最新的数据。如果数据变旧,则可以将其删除以为更新的数据腾出空间。毕竟,RAM很快,但它并不像磁盘空间那么便宜,所以这是一个很好的权衡。

此外,没有键值存储系统是关系数据库。关系数据库有原因。您不希望在键值存储区周围编写自己的ACID保证包装器。您不希望在键值存储上强制实施参照完整性。键值存储的奇特名称是No-SQL数据库。记住这一点:你可能从Cassandra那里得到横向可扩展性,你可能会从Memcached这样的速度获得超快的速度,但是你不会得到SQL以及RDBMSs的所有许多,数十年的演变有过。

最后:

不要混合语言

如果在实现反向代理和内存缓存之后,您仍然希望实现WebSocket服务器,那么您将获得更多权力。请记住您选择的服务器的含义。

如果您想将Socket.io与Node.js一起使用,请在Javascript中编写整个应用程序。否则,请选择使用与系统其余部分使用相同语言编写的WebSocket服务器。

1种语言解决方案的示例:

<?php // ~/projects/MySocialNetwork/core/users/myuser.php
class MyUser {
    public function getNotificationCount() {
        // Note: Don't got to the DB first, if we can help it.
        if ($notifications = $memcachedWrapper->getNotificationCount($this->userId) !== null) // 0 is false-ish. Explicitly check for no result.
            return $notifications;
        $userModel = new MyUserModel($this->userId);
        return $userModel->getNotificationCount();
    }
}
... 
<?php // ~/projects/WebSocketServerForMySocialNetwork/eventhandlers.php
function websocketTickCallback() {
    foreach ($connectedUsers as $user) {
        if ($user->getHasChangedNotifications()) {
            $notificationCount = $user->getNotificationCount();
            $contents = json_encode(array('Notification Count' => $notificationCount));
            $message = new WebsocketResponse($user, $contents);
            $message->send();
            $user->resetHasChangedNotifications();
        }
    }
}

如果我们使用的是socket.io,我们必须编写两次MyUser类,一次是PHP,一次是Javascript。谁想打赌这些类会在两种语言中以相同的方式实现相同的逻辑?如果两个开发人员正在研究类的不同实现怎么办?如果将错误修正应用于PHP代码但没有人记得Javascript会怎样?