C++ 套接字服务器 - 无法使 CPU 饱和

标签 c++ linux multithreading scalability boost-asio

我已经使用 boost::asio 在 C++ 中开发了一个迷你 HTTP 服务器,现在我正在使用多个客户端对其进行负载测试,但我一直无法接近 CPU 饱和。我在 Amazon EC2 实例上进行测试,一个 cpu 的使用率约为 50%,另一个 cpu 的使用率为 20%,其余两个处于空闲状态(根据 htop)。

详情:

  • 服务器每个内核启动一个线程
  • 接收、解析、处理请求并写出响应
  • 请求是从内存中读取的数据(本测试只读)
  • 我正在使用两台机器“加载”服务器,每台机器运行一个 java 应用程序,运行 25 个线程,发送请求
  • 我看到大约 230 个请求/秒的吞吐量(这是 应用程序 请求,由许多 HTTP 请求组成)

那么,我应该看什么来改善这个结果?鉴于 CPU 大部分时间处于空闲状态,我想利用额外的容量来获得更高的吞吐量,比如 800 个请求/秒或其他什么。

我的想法:

  • 请求非常小,通常在几毫秒内完成,我可以修改客户端以发送/组合更大的请求(可能使用批处理)
  • 我可以修改 HTTP 服务器以使用 Select 设计模式,这里合适吗?
  • 我可以做一些分析来尝试了解瓶颈是什么

最佳答案

boost::asio 并不像你希望的那样对线程友好——在 boost/asio/detail/epoll_reactor.hpp 中的 epoll 代码周围有一个大锁,这意味着只有一个线程可以调用内核的 epoll 系统调用一次。对于非常小的请求,这会产生很大的不同(这意味着您只会看到大致的单线程性能)。

请注意,这是 boost::asio 如何使用 Linux 内核工具的限制,不一定是 Linux 内核本身。在使用边缘触发事件时,epoll 系统调用确实支持多线程,但是正确处理(没有过度锁定)可能非常棘手。

顺便说一句,我在这方面做了一些工作(将完全多线程的边缘触发 epoll 事件循环与用户调度的线程/光纤相结合)并在 nginetd 下提供了一些代码项目。

关于C++ 套接字服务器 - 无法使 CPU 饱和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1234750/

相关文章:

linux - 我可以以非规范的方式从 stdin 读取吗?

java - 在Java中,您必须有一个具有线程将访问的共享变量的类吗?

c++ - boost python,使用 main global 以外的命名空间

c++ - 跟踪断言失败时如何知道调用者函数

linux - 如何解决 panic : no reachable servers

linux - 获取执行 bash 脚本的负载、cpu 使用率和时间

java - 多线程状态相关问题

python - 什么是 Python 线程 + Unix 信号语义?

c# - 如何通过进程访问内核操作

c++ - 无法理解带有特殊字符的 C++ 字符串的输出