---
title: Tailchat 压测报告新鲜出炉，万人消息广播完全接受只需1.2秒
authors: moonrailgun
image: /img/logo.svg
slug: benchmark-report
keywords:
  - tailchat
  - benchmark
tags: [Report]
---

作为一个即时通讯应用，Tailchat 天然就需要具备能够处理高并发多人在线能力的需求。

为了衡量`Tailchat`在处理大批量用户上的处理能力，给予我们的客户有足够的信心，我们决定花时间来测试在实际生产环境中实际表现。

因为为了面对来自不同程度与需求的用户的规模要求，`Tailchat` 的底层设计是基于分布式架构，这意味着我们可以通过水平扩容来承载不同的规模的业务需求。

但是分布式的缺点也在于花费了更多的资源在数据的通讯与转发上，在小规模的运行中比不上传统的集中式架构来的快。

这看上去是一个鱼和熊掌不可兼得的矛盾，但是为了同时获得两者的优势，`Tailchat` 在单实例部署上做了一些特殊的优化，即最短路径原则。这意味着在微服务之间相互调用中如果有且只有自身可以消费则跳过转发阶段直接把请求发送给自身。

这使得如果性能足够的情况下，单机的能力会优于集群。而当单机无法支撑足够的业务需求时，切换为集群部署用多个实例一起来承载高需求的业务规模。

![](/img/architecture/transport.excalidraw.png)

## 压测方式

为了衡量 Tailchat 在多人在线情况下表现，我们选择了消息发送与接收能力作为衡量标准。

即: **当一个群组中有若干人同时在线时，一条消息从发送开始到所有在线用户都接收到消息的转发这条完整链路所需要耗费的时间**

> 因为对于IM项目来说，传统的90分位/99分位数据是无意义的，只有所有用户都能接收到广播的消息、不丢失才是最基本的能力表现。因此对于Tailchat的要求也是只看消息传播耗时的100分位数据

同时，测试在多人在线时，**常驻**cpu与内存的**增长表现**

> 本次测试由 [sealos](https://sealos.io/) 提供集群服务支持。sealos 真的很方便！

压测方式主要分为三个步骤:

1. 批量注册用户，并把注册后系统返回的凭着(Token)记录到本地文件
1. 加载上一步存储的token，并按照token进行登录并建立长连接。当所有用户登录完毕后，记录常驻资源增长。
1. 当所有用户登录完毕后，选定一用户连接并发送消息到指定群组的指定频道，同时记录开始时间。当所有的连接都接收到这条消息后，记录结束时间。此时记录结束时间，计算中间耗时。该方法统计数次得到多组数据以消除误差。


## 压测概述

本次压测分别测试了 100用户、500用户、1000用户、2000用户、5000用户、10000用户同时在线且在同一个群组的性能表现。

为了尽可能压榨 `Tailchat` 的性能，我把选择使用最低限度的配置上限，来测试尽可能多的服务。在3实例的case中最高支撑到800人就出现问题了，拓展到5实例后成功支撑起1000用户，但是当用户同时在线人数上升到1300左右的时候又出现了瓶颈。此时我猜测可能是因为linux系统自带的ulimit导致的，毕竟在此之前没有做好相关的定向优化。此时我觉得集群测试可能要暂时告一段落了，我转移到window平台。

果然不负我的期待，在windows平台没有相关的限制，成功让 `Tailchat` 的在线人数突破到 2k、5k，乃至10k的限制。此时我认为我们本次的压测工作已经符合一开始的期待了。毕竟万人同群已经达到的同等行业的上限。当然我认为其上限远不止于此，因为还有很多的优化空间。

在最高的 10000 用户用例中，我们测试了5次从消息发送到所有用户接受到消息的耗时。最终我们发现 `Tailchat` 给出的答卷是1.2秒, 即1.2秒内一条消息会发送到所有的用户。这个数据我认为还是比较理想的，毕竟有1万人同时在线的群往往实际人数会达到10万人以上。当然在后续对大量用户的情况会进行进一步优化，这个数据只会是一个起点而不是一个终点。

## 完整报告

具体的压测报告可见: [压测报告](/docs/benchmark/report)
