之前我们在编写Reactor网络编程框架时,已经简单介绍了几种典型的Linux I/O模型,在本文中,我们将对这些模型进行简单梳理总结,介绍它们的用法和优缺点。 本文结构 基本概念 阻塞与非阻塞、同步与异步往往被混为一谈。这在一些语境下是可以不作严格区分的,例如多线程编程时,一个线程向另一个线程下达了任务,自己转而执行别的工作。之后,它将以轮询或事件通知的形式得知自己提交的任务是否被...
「Let's Go eBPF」来,一起“偷窥”下进程在干什么?
我们已经对eBPF和常见的Linux内核跟踪机制有了一定了解,接下来我们可以整合已有的知识,实现一个简易的进程“监控”程序。在这篇文章中,我们将借助eBPF记录进程的execve和execveat事件,看看系统中的进程在私底下执行了哪些程序。我们首先编写eBPF程序,实现exec事件的探针函数。然后基于libbpfgo编写用户态程序,接受并处理eBPF程序的输出。 这个程序的最终效果如...
「Let's Go eBPF」认识数据源:kprobe
上一篇文章中,我们介绍了Linux的静态插桩方式Tracepoint。本文我们将介绍Linux的动态插桩方式,包含两种实现机制:陷阱和蹦床。 陷阱机制 基于陷阱(trap)机制,我们可以在程序运行时动态打桩。Linux内核提供了kprobe,作为陷阱机制的实现。kprobe的好处是无须修改代码和重新编译内核,即可向内核中的大多数函数中插桩,且位置可由用户指定。kprobe很适合用于内...
「Let's Go eBPF」认识数据源:Tracepoint
系统的可观测性 软件应用和操作系统变得复杂以后,程序的行为跟踪、调试和性能分析成为难题。我们需要知道系统中此时此刻在进行哪些行为,程序中哪些流程是系统的潜在性能瓶颈,程序是否按照预期正确执行,这对系统的可见性(visibility)或可观测性(observability)提出了要求。为提升复杂系统的可观测性,Linux内核提供了多种内核跟踪(tracing)技术。 我们可以很容易想到...
「Let's Go eBPF」来看看Linux社区的新宠!
eBPF是近年来新兴的Linux内核技术,用于提供一种安全、友好的Linux内核态程序执行环境。在以前,当我们想扩展内核的功能,或者借助内核提供的能力进一步开发时,通常需要自己编写Linux内核模块(当然,你也可以选择直接修改Linux源码,然后重新编译内核😅)。内核模块的编写门槛较高,不容易调试,且编写出错很容易导致整个内核崩溃。 eBPF的出现从根本上解决了这些问题,赋予了Linu...
「Yogin」更多功能:模板渲染、限流和Session管理
欢迎来到「Yogin」系列的完结篇!在这篇文章中,我们会完成框架的静态资源托管、HTML模板服务端渲染等基本功能,然后在gin的基础上,扩展简单的限流和Session管理中间件,作为功能完善和中间件编写练习。 静态资源托管 在一张网页中,除了文本以外,还会引入很多其它静态资源,例如JavaScript和CSS文件、图片文件等等,在HTML标签中通常以href属性引入。浏览器读到这些属性时...
「Yogin」实现错误恢复和基本鉴权
从错误中恢复 要实现一个可用的服务器框架,错误恢复是必不可少的。由于代码编写有误或是生产环境中发生了没有预料到的情况,服务器在运行时很可能会发生panic。这个panic往往是服务器处理某个用户发来的请求产生的,我们不希望服务器因为处理一个用户请求出错进而连其它用户都无法响应的局面。因此,我们希望服务器具有从错误中恢复的能力。 panic和recover Go语言提供了panic和re...
「Yogin」实现分组路由和日志中间件
在上一篇文章中,我们完成了简单的路由逻辑,实现从请求的方法和URL到相应业务处理逻辑的映射。随着网站接口规模越来越庞大,我们期望对路由进行分组归类,对不同组别的路由区分管理。例如,/pubilc开头的API可公开调用,而/admin开头的API需要进行鉴权,调用前要先登录。 分组路由使得多个API按照语义归类到不同的API组下,根据业务场景,同一组中的API中,公共的处理逻辑可以被单独抽取...
「Yogin」从零实现一个gin-like框架
Yogin is Your Own Gin Go语言已经为我们提供了强大的net/http库,对于初学者而言,可以用几行代码搭建起一个简单的HTTP服务,和浏览器谈笑风生。 Go语言的网络标准库1 但是,当HTTP服务变得复杂起来后,Go语言自带的库就显得力不从心了,为了实现不同功能,我们会编写大量重复的代码,变得难以维护。因此,基于一个Web框架开发是更好的选择。 Gin是Go语...
「网络编程101」拼好最后一块积木,多线程Reactor框架!
在实现完简单的Reactor编程框架后,我们可以进一步扩展,使其效率更高、更加强劲。 扩展Reactor框架 引入Buffer 在之前实现的TcpConnection中,receive和send相关方法都是直接与文件描述符直接交互的。虽然事件通知时,文件描述符对应的读写资源都是准备就绪的,此时对其读写不会因为等待I/O资源长时间阻塞。但我们也有主动在连接上发起读写请求的时候,此时我们的...