Libevent 时间线记录:版本、作者、架构演变解析

发布于:2025-08-07 ⋅ 阅读:(15) ⋅ 点赞:(0)

我对开源项目 Libevent 比较感兴趣,我的项目中也使用到了 Libevent。一直以来,我都想多了解了解它。最近抽出来一些时间,在网上查找了大量的资料,做了梳理,肯定有不完善的地方,权当一个开始吧。

1. Libevent 的核心开发者

Libevent 项目涉及到 3 位核心开发者:Niels Provos(尼尔斯)、Nick Mathewson(尼克)、Azat Khuzhin(阿扎特)。

尼尔斯是 Libevent 项目的创始人、初代作者,在2000年11月发布了 Libevent 的第一个版本。从 2003 年到 2018 年,他在谷歌工作,担任谷歌安全杰出工程师。

尼克是 Tor 项目核心成员、联合创始人之一,负责 Tor 协议设计、安全性维护,以及核心程序的开发与漏洞修复。在 2003 年开发 Tor 项目时发现了一些问题(比如 select 和 poll 在 Windows 上表现不佳,扩展性不佳等),于是在 2005 年开始将 Libevent 引入到 Tor 项目之中,用于解决快速非阻塞 I/O 和扩展性方面的问题,并在不久之后参与维护 libevent,推动了 Libevent 重构与发展。

阿扎特是 Libevent 后期的核心维护者,专注于线程安全支持、bug 修复和现代化改造,使 Libevent 保持长期可维护。据 ClickHouse 团队在 2024 年的介绍,阿扎特目前供职于 Semrush 公司,担任该公司的高级工程师(Lead Engineer)。他在 Semrush 工作已超过 13 年,主要专注于 ClickHouse 和大型分布式系统等方面。

2. Libevent 的 3 个重要版本

Libevent 目前一共有 3 个 Stable Release:1.4.x-stable、2.0.x-stable、2.1.x-stable。

关于 Stable Release,稳定版,也称 GA - General Availability,是软件开发的最终阶段,代表经过完整测试、修复关键问题后,正式面向所有用户发布的版本。它是最可靠、最适合生产环境使用的版本。当然了,即使是 GA 版本,也会有未发现的隐藏较深的 BUG,或者安全漏洞,所以第一个 GA 发布之后,后续可能会持续推送补丁。

1.4.x 版本

  • 开始时间:1.4.0-beta(2007-11-11)
  • 第一个稳定版本:1.4.3-stable(2008-04-07)
  • 最后一个稳定版本:1.4.15-stable(2015-01-05)
  • 主要特性:
    • 引入了 bufferevent 抽象接口,简化了基于事件的 socket 读写逻辑。
    • 提供了对 evbuffer(事件缓冲区)API 的改进,提升了处理网络数据的便利性。
    • 改进的 signal 支持(event_base 级别的信号处理)。
    • 更好地支持 epoll、kqueue、poll、select 后端的封装与抽象。
    • 逐步改进了 线程安全性,增加 evthread_* 系列 API(非默认启用)。
    • 基础事件机制稳定,是很多应用(如 memcached)长期使用的版本。

2.0.x 版本

  • 开始时间:2.0.1-alpha(2009-04-17)
  • 第一个稳定版本:2.0.10-stable(2010-12-16)
  • 最后一个稳定版本:2.0.22-stable(2014-01-05)
  • 主要特性:
    • 线程安全的设计(开启 EVTHREAD_USE_* 后),支持多线程环境中注册和处理事件。
    • 引入了 新的 DNS 查询接口:evdns_base_,支持异步 DNS(UDP方式)。
    • 新一代 bufferevent API:包括基于 socket、filter、SSL 的 bufferevent 支持。
    • 加入高级的定时器(timerfd、clock_gettime)支持。
    • 支持优先级调度机制:不同事件可以设置处理优先级。
    • 更灵活的 event_base 配置机制(event_base_new_with_config)。
    • 大量重构和单元测试,改善了可维护性和跨平台兼容性。

2.1.x 版本

  • 开始时间:2.1.1-alpha(2012-04-03)
  • 第一个稳定版本:2.1.8-stable(2017-01-22)
  • 最后一个稳定版本:2.1.12-stable(2020-07-05)
  • 主要特性:
    • 引入了更现代化的 API和更严谨的类型定义,C++ 兼容性更好。
    • 支持 event_enable_debug_mode():帮助调试事件生命周期和内存泄露。
    • 全面增强 bufferevent_filter 支持:用于构建如加密/解密等流处理链。
    • 提升了性能,特别是 epoll 后端的延迟和唤醒处理优化。
    • 添加了 changelist 优化机制,减少 epoll_ctl 调用次数。
    • 提供了更完整的 OpenSSL 支持,兼容性更强。
    • 更完善的测试用例、更完善的代码分支覆盖率,提升了稳定性和可靠性。

3. Libevent 的版本历史

2000年

2000-11-14 发布第一个版本

Libevent 0.1 版本在 2000 年 11 月 4 日发布。当时 Niels Provos 就职于密歇根大学,出于对跨平台异步事件机制的需求(一种“能替代自己写的事件循环”的通用工具)而创建 Libevent。

Libevent 0.1 版本的代码很简单,包含一个头文件 event.h(83行)、一个实现文件 event.c(385行)、一个测试程序(95行)。queue.h 是高效且无类型限制的链表实现,从 BSD 系统移植而来的。

libevent-0.1 这个版本,只支持 select() 调用,并且是在 event_dispatch 函数中直接调用了 select,还没有开始对底层接口做抽象。而在 2022 年发布的 2.1.12-stable 版本中,在 event_base_loop 的 while 循环中(event_dispatch->event_loop->event_base_loop),调用的是抽象接口:res = evsel->dispatch(base, tv_p)。dispatch 便是事件循环的核心实现函数,其底层可能基于 select、poll、epoll、kqueue、windows select 等机制,具体使用哪一种取决于操作系统平台和运行时的可用性:

  • select:几乎所有平台都支持(POSIX、Windows 早期)
  • poll:大多数类 Unix 系统(如 Linux、Solaris、*BSD)
  • epoll:Linux 专用(高性能)
  • kqueue:FreeBSD、OpenBSD、macOS(XNU 内核)

而在 libevent-0.2b 这个版本中,已经有了 select.c 和 kqueue.c 了,event_dispatch 也做了抽象适配,说明尼尔斯最开始就已经想到要做一个跨平台的事件通知机制。在此后的 20 多年时间里,这个核心机制一直没有变过。

2000 年的版本发布:

  • Released 2000-11-14 - libevent-0.1.tar.gz
  • Released 2000-11-22 - libevent-0.2b.tar.gz

2001 年

  • Released 2001-04-05 - libevent-0.3c.tar.gz
  • Released 2001-06-04 - libevent-0.3d.tar.gz

2002 年

  • Released 2002-04-09 - libevent-0.4.tar.gz
  • Released 2002-06-12 - libevent-0.5.tar.gz
  • Released 2002-09-15 - libevent-0.6.tar.gz

2003 年

Nick Mathewson:早在 2003 年,我当时正在开发一个用 C 语言编写的项目(Tor 项目),该项目其中之一的功能是需要同时在大量套接字上执行快速非阻塞 IO。我们基于可广泛移植的 select() 和 poll() 系统调用的占位符异步 IO 实现在 Windows 上运行不佳,并且完全无法扩展(这里指的是扩展到其他操作系统)。

在 2023 年,Libevent 发布的版本如下:

  • Released 2003-05-04 - libevent-0.7a.tar.gz
  • Released 2003-10-05 - libevent-0.7b.tar.gz
  • Released 2003-10-25 - libevent-0.7c.tar.gz

2004 年

  • Released 2004-04-03 - libevent-0.8.tar.gz
  • Released 2004-06-12 - libevent-0.8a.tar.gz
  • Released 2004-07-30 - libevent-0.9.tar.gz

2005 年(尼克加入 Libevent)

Nick Mathewson:所以,我们大约在 2005 年开始使用 Niels Provos 的 Libevent 库。当时它大约是 1.0 版本,而且……有一些 bug。为了让我们的应用程序正常运行,我开始提交补丁,不久之后,Niels 就问我是否愿意参与维护。

2005 年 Libevent 发布了哪些版本如下:

  • Released 2005-01-03 - libevent-1.0a.tar.gz
  • Released 2005-01-13 - libevent-1.0b.tar.gz
  • Released 2005-04-03 - libevent-1.0c.tar.gz
  • Released 2005-04-22 - libevent-1.0d.tar.gz
  • Released 2005-04-26 - libevent-1.0e.tar.gz
  • Released 2005-05-14 - libevent-1.1.tar.gz
  • Released 2005-06-12 - libevent-1.1a.tar.gz

2006 年

  • Released 2006-08-09 - libevent-1.1b.tar.gz
  • Released 2006-10-15 - libevent-1.2.tar.gz
  • Released 2006-12-02 - libevent-1.2a.tar.gz

2007 年(开始 1.4 版本)

  • Released 2007-02-15 - libevent-1.3.tar.gz
  • Released 2007-02-17 - libevent-1.3a.tar.gz
  • Released 2007-03-03 - libevent-1.3b.tar.gz
  • Released 2007-07-30 - libevent-1.3c.tar.gz
  • Released 2007-08-16 - libevent-1.3d.tar.gz
  • Released 2007-09-24 - libevent-1.3e.tar.gz
  • Released 2007-11-11 - libevent-1.4.0-beta.tar.gz
  • Released 2007-12-21 - libevent-1.4.1-beta.tar.gz

2008 年(1.4 稳定版发布)

  • Released 2008-02-25 - libevent-1.4.2-rc.tar.gz
  • Released 2008-04-07 - libevent-1.4.3-stable.tar.gz
  • Released 2008-05-13 - libevent-1.4.4-stable.tar.gz
  • Released 2008-06-25 - libevent-1.4.5-stable.tar.gz
  • Released 2008-07-24 - libevent-1.4.6-stable.tar.gz
  • Released 2008-08-25 - libevent-1.4.7-stable.tar.gz
  • Released 2008-09-13 - libevent-1.4.8-stable.tar.gz
  • Released 2008-12-12 - libevent-1.4.9-stable.tar.gz

在 2008-04-07 发布的 libevent-1.4.3-stable.tar.gz 版本是第一个 GA 版本,后续的 1.4.x 版本都是推送安全补丁和重要修复。从官网我们可以看到,2015-01-05 还在发布 libevent-1.4.15-stable.tar.gz,说明 1.4 版本得到了长期的支持。

2009 年(开始 2.0 版本)

2009 年 3 月 1 日 Nick Mathewson 关于 IOCP 的一些进展报告

Nick Mathewson:Libevent 的现有版本在除 Windows 之外的所有平台上都表现出色。因为 Windows 的 IOCP 网络调用仅适用于构建与 Libevent 高级接口兼容的版本。 Libevent 的现有实现,存在某些缺陷(例如,所有子模块均未完全兼容 Windows、缺乏线程安全的数据结构以及效率低下的数据结构)。对于 Windows 来说,使用 IOCP 不仅仅是为了性能,也是为了稳定性。

因此,为了使 Libevent 在 Windows 上快速且稳定,需要完成以下任务:

  1. 使 Libevent 的整体设计足够灵活,以支持基于 IOCP 的高级接口后端。(基本完成)
  2. 为 Windows 编写基于 IOCP 的后端。(已开始并正在进行中,预计将于 3 月底完成第一个版本)
  3. 修改 Libevent 的高级接口以支持 Tor 所需的功能。(基本完成)
  4. 修改 Tor 自己的网络层以使用 Libevent 的高级接口。(等 Libevent 接口经过充分测试便启动)
  5. 最后,Windows 的 IOCP 在多线程环境下运行性能最佳,此时工作线程池中的任意一个线程都可能收到任意套接字上任意操作完成的通知。迁移到这种模型超出了本报告的讨论范围,不过 Libevent 和 Tor 都计划在长期内朝这个方向发展。

2009 年 4 月 Nick Mathewson 开发 Libevent 2.0 版本,重构大量代码

Nick Mathewson:2009 年 4 月左右的初步结果表明,重写的代码库将我们的大负载 HTTP 基准性能提升了 35%到 174%。我们希望,随着我们更积极地分析和基准测试这段代码,能够发现更多改进的机会。

libevent 2.0版本有哪些重大解决事项?

  • 在 Windows 上支持 IOCP 一直是 Libevent 2.0 面临的最大挑战,这也促使了其余(非 Windows 专用)代码库的改进。
  • 在 Libevent 2.0 中,我们彻底重写了 bufferevent。早期版本的 Libevent 有一个“bufferevent”抽象,用于处理常见的情况:您希望将通过 TCP 连接接收的数据和待发送的数据排队,并在更多数据到达或发送时收到通知。这个接口与 IOCP 非常匹配,但现有的实现过于缺乏灵活性和效率,不适合正式使用。此外,它的存储格式依赖于大型循环缓冲区,接口只允许单一实现,在 Windows 上性能不佳,而且速度通常很慢。在 Libevent 2.0 中,我们彻底重写了 bufferevent。数据存储格式从循环缓冲区更改为缓冲区链表,令人联想到经典的 mbuf 接口。我们添加了使用 sendfile() 及其相关函数发送文件的支持,并修复了 Windows 支持。该接口现在支持多个面向对象风格的后端,从而允许“缓冲 IO” API 的多种实现。到目前为止,我们有五个这样的后端:基本套接字实现、过滤包装器实现、基于 SSL 的实现(见下文)、套接字对风格的实现以及基于 IOCP 的实现。

2009 年 9 月 11 日 chrisd 的一些记录

chrisd:在 2009 年,我参与了 Polipo 的开发工作。Polipo 是 Tor 最青睐的 Web 代理,用于连接 HTTP 和 SOCKS 协议。我有机会了解 Polipo 和 Libevent,并与一些 Tor 的开发者见面。Libevent 的开发者是 Nick Mathewson 和 Niels Provos。Nick Mathewson 恰好也在 Tor 项目工作,并且在那个夏天担任了我的 GSoC 导师。我的工作包括集成对 Libevent 的支持,当 Polipo 编译为使用 Libevent 时,在处理大量打开的连接时应该会更快。Libevent 的现代版本还包含一个异步 DNS 解析器,我也将其与 Polipo 绑定。

2009 年发布的版本如下:

  • Released 2009-04-17 - libevent-1.4.10-stable.tar.gz
  • Released 2009-04-17 - libevent-2.0.1-alpha.tar.gz (2009年开始2.0版本)
  • Released 2009-05-14 - libevent-1.4.11-stable.tar.gz
  • Released 2009-07-24 - libevent-1.4.12-stable.tar.gz
  • Released 2009-07-24 - libevent-2.0.2-alpha.tar.gz
  • Released 2009-11-17 - libevent-1.4.13-stable.tar.gz
  • Released 2009-11-19 - libevent-2.0.3-alpha.tar.gz

2010年(2.0 稳定版发布)

2010年1月26日 Nick Mathewson 报告最近的一些进展

Nick Mathewson:时间飞快地来到今天。Libevent 已经开发出一个“附加”库来支持 HTTP 和 DNS 等常用协议。Libevent 也积累了真正的用户,包括 Tor、Memcached 和 Chromium。随着 1.4 版本的发布,Libevent 的核心已经日趋成熟,在大多数 Unix 平台上运行良好,在 Windows 上的表现也还不错。但仍然存在一些问题,这促使我们决定在 2.0 版本中投入更多精力进行开发。我将在这里简要介绍一些主要问题,解释我们取得的进展,以及在 Libevent 2.0 正式完成之前我们还需要完成哪些工作。

旧版本的 Libevent 允许每个线程使用一个事件循环结构;不支持从另一个线程添加或删除事件。这不仅给多线程应用程序的编写者带来了麻烦,也使得 IOCP 支持几乎不可能,因为我们需要让 IOCP 循环在与主事件线程不同的线程中运行。

基础工作终于完成了。截至上周,Libevent 中主要的非锁定部分已经基本完成。我们可能还需要进行一些性能调优:不同的操作系统提供的互斥锁实现特性差异很大。您可能已经想到,在 Libevent 1.4 和 Libevent 2.0 之间,我们添加并重写了大量的代码。如果没有良好的单元测试,我们很可能会引入相当多的 bug。

我们本可以修改所有 API,使其更不容易出错,但这会破坏所有使用它们的旧程序。此外,默认暴露旧 API 会让开发者难以确保自己避免使用它们。作为妥协,我们决定将首选 API 放在新的头文件(例如 event2/event.h)中,将弃用的 API 放在兼容头文件(例如 event2/event_compat.h)中,同时保留旧头文件(例如旧版 event.h)作为包装器,以同时包含新旧 API(如果不明白为什么 libevent 的头文件中有 event2 文件夹,这里尼克给出了解答)。

2010 年发布的版本如下:

  • Released 2010-03-01 - libevent-2.0.4-alpha.tar.gz
  • Released 2010-05-11 - libevent-2.0.5-beta.tar.gz
  • Released 2010-06-07 - libevent-1.4.14b-stable.tar.gz
  • Released 2010-08-07 - libevent-2.0.6-rc.tar.gz
  • Released 2010-09-09 - libevent-2.0.7-rc.tar.gz
  • Released 2010-10-14 - libevent-2.0.8-rc.tar.gz
  • Released 2010-11-30 - libevent-2.0.9-rc.tar.gz
  • Released 2010-12-16 - libevent-2.0.10-stable.tar.gz

2011 年

  • Released 2011-04-28 - libevent-2.0.11-stable.tar.gz
  • Released 2011-06-04 - libevent-2.0.12-stable.tar.gz
  • Released 2011-07-18 - libevent-2.0.13-stable.tar.gz
  • Released 2011-08-31 - libevent-2.0.14-stable.tar.gz
  • Released 2011-10-12 - libevent-2.0.15-stable.tar.gz
  • Released 2011-11-18 - libevent-2.0.16-stable.tar.gz

2012 年(开始 2.1 版本)

  • Released 2012-02-10 - libevent-2.0.17-stable.tar.gz
  • Released 2012-03-22 - libevent-2.0.18-stable.tar.gz
  • Released 2012-04-03 - libevent-2.1.1-alpha.tar.gz
  • Released 2012-05-03 - libevent-2.0.19-stable.tar.gz
  • Released 2012-08-23 - libevent-2.0.20-stable.tar.gz
  • Released 2012-11-18 - libevent-2.0.21-stable.tar.gz
  • Released 2012-11-18 - libevent-2.1.2-alpha.tar.gz

我想找一下,阿扎特是什么时候加入 Libevent 的,但没有查到相关信息。只在 Libevent 用户的邮件列表中查到,阿扎特早在 2012 年 12 月 04 日 evthread_use_windows_threads() cause memory leak? 就参与了该项目的一些讨论,并开始回答一些问题。

2013 年

  • Released 2013-05-01 - libevent-2.1.3-alpha.tar.gz

2014 年

  • Released 2014-01-05 - libevent-2.0.22-stable.tar.gz
  • Released 2014-03-21 - libevent-2.1.4-alpha.tar.gz

2015 年

  • Released 2015-01-05 - libevent-1.4.15-stable.tar.gz
  • Released 2015-01-05 - libevent-2.1.5-beta.tar.gz

2016 年

  • Released 2016-08-27 - libevent-2.1.6-beta.tar.gz
  • Released 2016-11-05 - libevent-2.1.7-rc.tar.gz

2017 年(2.1 稳定版发布)

  • Released 2017-01-22 - libevent-2.1.8-stable.tar.gz

2018 年

2019 年

  • Released 2019-01-20 - libevent-2.0.23-beta.tar.gz
  • Released 2019-02-10 - libevent-2.1.9-beta.tar.gz
  • Released 2019-05-26 - libevent-2.1.10-stable.tar.gz
  • Released 2019-08-01 - libevent-2.1.11-stable.tar.gz

2020 年

  • Released 2020-07-05 - libevent-2.1.12-stable.tar.gz

2021 年

2022 年

2023 年(开始 2.2 版本)

从 2023 年开始的 Libevent 2.2 版本将会包含许多新功能和性能改进:

  • wepoll 后端;
  • signalfd 后端;
  • 支持使用 TCP 协议查询 DNS;
  • websockets 层;
  • MbedTLS 支持;
  • HTTP 的 unix 域套接字;
  • cmake 优于 autotools/automake;

Libevent 2.2 引入对 wepoll 的支持,是为了增强 在 Windows 平台上的 I/O 多路复用性能。wepoll 是一个专门为 Windows 平台开发的开源库,模拟了 Linux 下 epoll 的行为,通过 Windows 的 IOCP 等底层 API 实现高性能事件通知机制。项目地址: https://github.com/piscisaureus/wepoll,作者 Bert Belder 曾参与 libuv、Node.js 等项目。在 2020 年 4 月,由 Nick Grifka 提出,那时阿扎特还不了解 wepoll 是什么,在 GitHub 上可以找到相关的wepoll 讨论笔记

2023 年的发布情况:

  • Released 2023-05-21 - libevent-2.2.1-alpha-dev.tar.gz

2024 年

2025 年

4. 后记

通过对 Libevent 的发展历史进行梳理,查阅大量的资料,我对这个项目有了更深的认识,这期间也学习和了解到很多新的知识和有趣的事情。后续如有新发现,我会继续补充到这个文章中。

5. References

  1. Libevent 官网
  2. Libevent GitHub
  3. Google 开源博客:Libevent 2.0.x: Like Libevent 1.4.x, Only More So.
  4. Tor 博客:Polipo 可移植性增强功能摘要
  5. Tor 博客:关于 IOCP 和 Libevent 进展的一些说明
  6. 维基百科:Libevent
  7. 维基百科:Niels Provos 尼尔斯·普罗沃斯
  8. 维基百科:Nick Mathewson 尼克·马修森
  9. Sourceforge:Libevent
  10. ClickHouse 团队 2024年12月简讯

网站公告

今日签到

点亮在社区的每一天
去签到