Linux

ebpf

December 24, 2021
Linux
Ebpf

ebpf: 扩展伯克利包过滤器。 下面的内容主要来源于 译文。 用处 # 目前,主要有两大组触发器。 第一组用于处理网络数据包和管理网络流量。它们是 XDP、流量控制事件及其他几个事件。 以下情况需要用到这些事件: 创建简单但非常有效的防火墙。Cloudflare 和 Facebook 等公司使用 BPF 程序来过滤掉大量的寄生流量,并打击最大规模的 DDoS 攻击。由于处理发生在数据包生命的最早阶段,直接在内核中进行(BPF 程序的处理有时甚至可以直接推送到网卡中进行),因此可以通过这种方式处理巨量的流量。这些事情过去都是在专门的网络硬件上完成的。 创建更智能、更有针对性、但性能更好的防火墙——这些防火墙可以检查通过的流量是否符合公司的规则、是否存在漏洞模式等。例如,Facebook 在内部进行这种审计,而一些项目则对外销售这类产品。 创建智能负载均衡器。最突出的例子就是 Cilium 项目,它最常被用作 K8s 集群中的网格网络。Cilium 对流量进行管理、均衡、重定向和分析。所有这些都是在内核运行的小型 BPF 程序的帮助下完成的,以响应这个或那个与网络数据包或套接字相关的事件。 这是第一组与网络问题相关并能够影响网络通信行为的触发器。第二组则与更普遍的可观察性相关;在大多数情况下,这组的程序无法影响任何事件,而只能“观察”。这才是我更感兴趣的。 这组的触发器有如下几个: perf 事件(perf events)——与性能和 perf Linux 分析器相关的事件:硬件处理器计数器、中断处理、小 / 大内存异常拦截等等。例如,我们可以设置一个处理程序,每当内核需要从 swap 读取内存页时,该处理程序就会运行。例如,想象有这样一个实用程序,它显示了当前所有使用 swap 的程序。 跟踪点(tracepoints)——内核源代码中的静态(由开发人员定义)位置,通过附加到这些位置,你可以从中提取静态信息(开发人员先前准备的信息)。在这种情况下,静态似乎是一件坏事,因为我说过,日志的缺点之一就是它们只包含了程序员最初放在那里的内容。从某种意义上说,这是正确的,但跟踪点有三个重要的优势: 有相当多的跟踪点散落在内核中最有趣的地方 当它们不“开启”时,它们不使用任何资源 它们是 API 的一部分,它们是稳定的,不会改变。这非常重要,因为我们将提到的其他触发器缺少稳定的 API。 例如,假设有一个关于显示的实用程序,内核出于某种原因没有给它时间执行。你坐着纳闷为什么它这么慢,而 pprof 却没有显示任何什么有趣的东西。 USDT——与跟踪点相同,但是它适用于用户空间的程序。也就是说,作为程序员,你可以将这些位置添加到你的程序中。并且许多大型且知名的程序和编程语言都已经采用了这些跟踪方法:例如 MySQL、或者 PHP 和 Python 语言。通常,它们的默认设置为“关闭”,如果要打开它们,需要使用 enable-dtrace 参数或类似的参数来重新构建解释器。是的,我们还可以在 Go 中注册这种类跟踪。你可能已经识别出参数名称中的单词 DTrace。关键在于,这些类型的静态跟踪是由 Solaris) 操作系统中诞生的同名系统所推广的。例如,想象一下,何时创建新线程、何时启动 GC 或与特定语言或系统相关的其他内容,我们都能够知道是怎样的一种场景。 这是另一种魔法开始的地方: ...

linux epoll

July 17, 2021
Linux
Epoll

linux epoll # wiki 手册 why # what # Linux内核的可扩展I/O事件通知机制。 于Linux 2.5.44首度登场,它设计目的旨在取代既有POSIX select(2)与poll(2)系统函数,让需要大量操作文件描述符的程序得以发挥更优异的性能(举例来说:旧有的系统函数所花费的时间复杂度为O(n),epoll的时间复杂度O(log n))。epoll 实现的功能与 poll 类似,都是监听多个文件描述符上的事件。 how # epoll 通过使用红黑树(RB-tree)搜索被监控的文件描述符(file descriptor)。 在 epoll 实例上注册事件时,epoll 会将该事件添加到 epoll 实例的红黑树上并注册一个回调函数,当事件发生时会将事件添加到就绪链表中。 int epoll_create(int size); 在内核中创建epoll实例并返回一个epoll文件描述符。 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 向 epfd 对应的内核epoll 实例添加、修改或删除对 fd 上事件 event 的监听。op 可以为 EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL 分别对应的是添加新的事件,修改文件描述符上监听的事件类型,从实例上删除一个事件。如果 event 的 events 属性设置了 EPOLLET flag,那么监听该事件的方式是边缘触发。 int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); 当 timeout 为 0 时,epoll_wait 永远会立即返回。而 timeout 为 -1 时,epoll_wait 会一直阻塞直到任一已注册的事件变为就绪。当 timeout 为一正整数时,epoll 会阻塞直到计时 timeout 毫秒终了或已注册的事件变为就绪。因为内核调度延迟,阻塞的时间可能会略微超过 timeout 毫秒。 ...