我想做一个app,里面有个用户与用户之间交流的模块,我首先想到具有即时交流的功能就用websocket,但因为websocket建立的是长连接,那性能方面肯定大不如http吧?那一般建立多少个websocket链接合适呢?因为用户与用户之间交流最多就可能要建立n²的websocket链接,这样子可行吗?或者说不用websocket进行即时通讯,那我用kafkaMQ来做可以吗?
WebSocket它的性能并不比HTTP差。相反,WebSocket在性能方面比HTTP更优秀,因为它可以实现双向通信,而HTTP只能实现单向通信。
并且WebSocket的数据传输也比HTTP更高效,因为它不需要在每次通信时都建立连接。
对于你的问题,我有几个方案和观点提供:
WebSocket连接数: WebSocket在建立一次握手后就会保持长连接,避免了频繁建立和断开HTTP请求带来的性能损耗。然而如果一个服务端程序要管理大量WebSocket客户端,则必然需要较高配置(CPU, 内存等)的服务器。实际上支持多少个Websocket并发链接因硬件资源与具体业务逻辑不同而变化很大。单机维护几千甚至上万个是可能的。但一般情况下,基于可扩展性以及系统稳定性考虑都会使用集群方式分摊这些长链接。
N²问题: 对于用户之间所有人相互通讯即使是websocket也并不推荐进行全网广播形式组网(N*N),其带来巨大负担且显着增加复杂度,并引入安全风险。更常见有效做法为每位用户和服务器建立一个长连接,消息通过服务器转发给接收者。
Kafka使用: Kafka 更多用于创建可靠消息队列或日志处理系统,在某些场景比如离线聊天、历史信息储存它将非常有用,然而_kafka本身无法提供实时交付_功能(确切说没有设计为延迟低微秒级别),所以它不能代替WebSocket完成客户端到客户端之间的实时传输任务;
选择技术时请根据项目需求以及预期规模进行考虑。
总结一切皆有利弊,请依情况取舍!
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!主要使用场景有以下2种:
对于建立的WebSocket连接数量是否有限制,一般来说,WebSocket连接的数量是有限制的,具体的数量限制取决于服务器的硬件配置、网络带宽、以及应用程序的负载情况。一般来说,如果使用WebSocket建立连接,连接的数量应该小于5万个,否则可能会导致服务器崩溃或性能下降。
在考虑到大量用户在线时,建立的WebSocket连接数量可能过多的情况下,可以考虑使用MQ(消息队列)来实现即时通讯。KafkaMQ是一种分布式消息队列,提供高吞吐量的消息传输,并支持多个消费者进行并行处理。可以考虑使用KafkaMQ作为WebSocket连接的替代方案,将即时通讯的消息统一进行分发,从而避免了n²级别的连接数量导致的性能问题。
具体实现方案可以先将用户通过Websocket连接发送到KafkaMQ的指定Topic中,然后利用KafkaMQ的消费者进行消息的订阅和回调,从而实现即时通讯的功能。另外需要注意的是,使用KafkaMQ也需要避免过多的连接数量导致服务器崩溃或性能下降的问题,因此仍需要进行适当的服务器硬件和网络配置优化。
代码实现方案可参考如下(以Node.js为例):
具体的代码实现可以分为以下几个步骤:
npm install kafka-node
npm install ws
const kafka = require('kafka-node');
const client = new kafka.KafkaClient({kafkaHost: 'localhost:9092'});
const producer = new kafka.Producer(client, { requireAcks: 1 });
producer.on('ready', () => console.log('Kafka producer is ready'));
producer.on('error', (err) => console.log('Error', err));
const WebSocket = require('ws');
const wsServer = new WebSocket.Server({ port: 8080 });
wsServer.on('connection', function connection(ws, req) {
const ip = req.connection.remoteAddress;
const id = Math.random().toString(36).substring(2, 15);
const data = JSON.stringify({type: 'connect', id, ip, time: Date.now()});
producer.send([
{topic: 'websocket-connections', messages: [data]},
], (err, data) => {
if (err) console.log('Error publishing', err);
});
console.log('User connected', id);
});
const consumer = new kafka.Consumer(
client,
[{ topic: 'websocket-connections', partition: 0 }],
{ autoCommit: true }
);
consumer.on('message', (message) => {
const { type, id, ip, time } = JSON.parse(message.value);
if (type === 'connect') {
console.log(`Received new connection: [${time}] ${ip} ${id}`);
}
// Handle other message types (disconnects, user messages, etc.)
});
consumer.on('error', (err) => {
console.log('KafkaMQ Error:', err);
});
注意事项: 1. 在使用KafkaMQ进行即时通讯时,需要考虑到网络延迟和消息处理的速度等因素,可能会导致实时性不高或者存在一定的消息丢失问题。 2. 在发送WebSocket连接信息到KafkaMQ的Topic中时,需要保证消息的顺序性和一致性,建议采用分区的方式进行消息发送和订阅。 3. 在处理WebSocket连接信息时,需要注意避免用户注销或断开连接时产生的垃圾连接和消息不一致问题。可以考虑使用心跳机制或定时清理无效连接等方式进行优化。