systemtap 探秘(二)- 由 probe 生成的 C 代码

2019-06-27
阅读 5 分钟
4.5k
上一篇文章,我简单地介绍了 systemtap 的工作流程,以及第一、第二个阶段的内容。从这篇文章开始,我们将步入本系列的重头戏 - 负责生成 C 代码的第三阶段。

systemtap 探秘(一)- 基本介绍

2019-06-24
阅读 3 分钟
6.9k
Linux 内核(以下简称内核)提供了 kprobe 和 uprobe 的机制,允许用户通过编写自己的内核模块,挂载特定的事件来执行自己的函数。比如我们可以在 accept 系统调用结束时记录下新创建的 fd;或者在 VFS 读写操作前后记录时间戳,统计它们的耗时。

如何在 Python 中实现 goto 语句

2019-05-17
阅读 5 分钟
19.7k
Python 默认是没有 goto 语句的,但是有一个第三方库支持在 Python 里面实现类似于goto 的功能:[链接]。 比如在下面这个例子里, {代码...} func() 在执行第一遍循环时,就会从最内层的 for j in range(2) 跳到函数的return 语句前面。 按理说本文到此就该完了,但是这个库有一个限制,如果嵌套的循环层次太深,就无法...

如何应对 OpenResty 为支持 ARM64 引入的 break change

2019-05-03
阅读 3 分钟
6.3k
另外,如果你没用 OpenResty 自己的 LuaJIT 分支,那么可以直接关掉这个页面了,因为这些 break change 只有在使用了 OpenResty 自己的 LuaJIT 分支才会出现。

如何实现一个 circuit breaker

2019-04-20
阅读 4 分钟
3.7k
Circuit breaker 是微服务架构里常见的一种设计模式,用来避免某个出问题的服务拖垮整条链路的情况。它的职责在于,当一个服务不能正常响应的时候,与其继续执行该服务的逻辑,不如断开该部分链路,直接返回错误或者某个降级的内容(比如只显示个静态页面)。

在 OpenSSL 1.1.1 下支持 OpenResty 的非阻塞 SSL session fetch

2019-04-13
阅读 4 分钟
6.7k
如果你用 OpenResty 做过 SSL session reuse,你可能会用到其中的异步获取 SSL session 的特性,比如在 ssl_session_fetch_by_lua* 里面发起非阻塞的网络请求,从 memcache 或别的什么存储服务器上读取 SSL session。ssl_session_fetch_by_lua* 的实现原理,就是在 OpenSSL 的 session get callback 里执行 Lua 代码。然...

分享一种最小 Perfect Hash 生成算法

2019-02-02
阅读 4 分钟
4.1k
先解释下什么是 Perfect Hash:Perfect Hash 是这样一种算法,可以映射给定 N 个 keys 到 N 个不同的的数字里。由于没有 hash collision,这种 Hash 在查找时时间复杂度是真正的 O(1)。外加一个“最小”前缀,则是要求生成的 Perfect Hash 映射结果的上界尽可能小。举个例子,假设我有 100 个字符串,如果存在这样的最小Pe...

用关系型数据库处理树状结构的数据的一些想法

2019-01-17
阅读 3 分钟
2.4k
树状结构的数据,就是符合“每个上级节点可以有多个子节点,而每个子节点都只有一个上级节点”这一模型的数据。比如一个 region 可以有多个 zones,而每个 zone 又能有多个 servers;但是每个 server 只位于某个 zone,每个 zone 又只位于某个 region。

如何编写正确且高效的 OpenResty 应用

2018-12-29
阅读 8 分钟
12.8k
编写正确且高效的应用,最为关键是一系列软件工程上的实践,像测试、code review、灰度、监控、压测等等。不过由于这是 OpenResty 大会上的演讲,我会专注于讲讲 OpenResty 和 LuaJIT 的一些小细节,帮助各位听众避免线上踩坑。

Nginx 是如何让你的缓存延期的

2018-12-18
阅读 2 分钟
4.3k
当 Nginx 使用 proxy cache 的文件作为响应时,它会更新其中的一些内容,比如 Date 响应头;但大部分响应头都不会得到更新,比如 Expires 和 Cache-Control。众所周知,Cache-Control 可以通过 max-age=xxx 或者 s-maxage=xxx 指令设置缓存的有效时间。跟 Expires 响应头不同,这一时间是相对的。假设上游服务器返回 Cac...

LuaJIT FFI 介绍,及其在 OpenResty 中的应用(下)

2018-08-25
阅读 6 分钟
10.4k
还有一笔账值得一算:调用 Lua CFunction 会迫使 LuaJIT 退回到解释模式,而通过 FFI 调用 C 函数则不会。所以不能光计算 FFI 的开销,还要看因为不用 FFI,导致 Lua 代码无法被编译掉的损耗。在代码中大量调用 Lua CFunction,会使得 LuaJIT 的 JIT tracing 变得支离破碎。即使因为 stitch 的缘故,让剩余的部分能够被...

LuaJIT FFI 介绍,及其在 OpenResty 中的应用(上)

2018-07-28
阅读 6 分钟
16.4k
对 C 语言良好的亲和力,一直是 Lua 的优势之一。LuaJIT 在传统的 Lua C API 之外,额外提供 FFI 的方式来调用 C 函数,更是大大提升了跟 C 交互的便利度。甚至有这么一种说法,虽然 LuaJIT 命名是 Lua + JIT,但是好多人是冲着 FFI 去用 LuaJIT 的。[1]

OpenSSL API 调用错误处理上的细节问题

2018-06-19
阅读 4 分钟
4.9k
最近遇到一个 bug,调用 OpenSSL API 出错时,返回的错误信息牛头不对马嘴,不知道为什么会有这种情况。仔细分析后发现,发生这种情况时之前都会有一次 OpenSSL API 出错,而且后一次调用出错返回的错误信息跟前一次很相似。呃,难道 OpenSSL API 出错时,会返回多条错误信息?

如何在 Linux 上通过 C API 判断给定的 fd 的类型?

2018-06-05
阅读 3 分钟
5.2k
最近接到一个任务,需要判断传过来的 fd 是不是属于 eventfd/signalfd 这一类特定的 fd。因为这一类 fd 不支持某些操作,如果调用时不加判断,会报 Invalid Argument 错误。按理说,如果能把 fd 类型作为一个额外的参数传进来,就能轻松解决问题了。不过因为一些限制,拿到手时只有 fd 这一个整数。好在需要过滤的地方不...

基于 patch 的版本控制系统是如何处理合并的 -- 一种新思路

2018-03-10
阅读 3 分钟
4.4k
patch 是版本控制系统中最为渊远流长的概念之一,日常的各种操作中都需要跟它打个照面。比如 git diff 输出格式就是个 patch 文件,git cherry-pick 会把摘取的修改以 patch 的形式应用到目标分支上。此种例子比比皆是。不过需要指出的是,当前广泛使用的版本控制系统,比如 svn/git/hg,都是基于 snapshot 而不是 patch...

使用 Ruby 拓展 Vim

2018-02-18
阅读 2 分钟
4.2k
作为一款历史悠久的编辑器,Vim 不仅支持用别具一格的 Vimscript 编写插件,还提供了 Python、Ruby、Lua 和 Perl 等语言对应的接口,甚至包括了对 Tcl 的支持,注意我说的是名为 Tcl 的编程语言,不是某家电品牌。通过这些语言,开发者可以摆脱 Vimscript 的限制,挑选自己最擅长的工具来拓展自己的编辑器。几年前,我曾...

排查一个潜在的内存访问问题 -- 用 C 写代码的日常

2018-01-30
阅读 3 分钟
4.6k
最近几个月,我开始涉足 C 开发的领域,遇到的最大的挑战在于如何管理好内存。从异常情况下避免内存泄漏,到排查代码逻辑里面的 invalid read,还有复用过程中没能清理好数据的问题,几乎各种坑都体验过一次。

nmap服务识别和操作系统探测

2017-11-06
阅读 5 分钟
14.4k
扫描对外公开的服务器信息,是 nmap 的主要用途之一。为了识别服务器上运行的是哪种服务,nmap 把主流服务的特征信息存储在 nmap-services-probes 和 nmap-os-db 这两个文件中。其中前者包含应用程序的特征信息,后者放置操作系统的特征信息。不同操作系统上,这两个文件的位置不一样,可以通过 locate 或其他相似的全盘...

OpenResty Con 2017 见闻杂记

2017-10-23
阅读 3 分钟
5k
今年的 OpenResty Con 在北京举行,考虑到路途过于遥远,我决定看直播。虽然参与的方式变了,但我依旧跟去年一样,趁着记忆还算清晰写了篇文章,算是“路边社”的新闻稿吧。

探究 Redis 4 的 stream 类型

2017-10-15
阅读 5 分钟
7.7k
10 月初,Redis 搞了个大新闻。别紧张,是个好消息:Redis 引入了名为 stream 的新数据类型和对应的命令,大概会在年底正式发布到 4.x 版本中。像引入新数据类型这样的变化在 Redis 的发展历史上非常罕见,所以称之为大新闻一点也不为过。至少很多介绍 Redis 的资料要跟着修订了。

为什么你应该在 OpenResty 项目中使用 lua-resty-core

2017-09-09
阅读 3 分钟
9.9k
lua-resty-core 是 OpenResty 组件的一部分。它由两部分组成,一部分是 resty.core.*,提供了对 lua-nginx-module Lua 接口的替换实现;另一部分是 ngx.*,OpenResty 新的接口一般都会放到这里。跟其他 lua-resty 开头的库一样,lua-resty-core 也是用 Lua 实现的。说到这有人可能会问,既然 lua-nginx-module 已经有了...

漫谈非加密哈希算法

2017-09-03
阅读 3 分钟
30.3k
哈希算法是一个大杂烩,除了 MD5、SHA1 这一类加密哈希算法(cryptographic hash),还有很多或家喻户晓或寂寂无闻的算法。哈希算法只需满足把一个元素映射到另一个区间的要求。鉴于该要求是如此之低,像 Java 的 hashCode 其实也算一种哈希算法。不过今天当然不会讲 Java 的 hashCode,我们来聊聊一些更具实用性的算法...

为 OpenResty 项目编写自定义 Nginx C 模块

2017-08-13
阅读 3 分钟
6.2k
有些时候,我们需要通过 Lua 代码操作 Nginx 里面的某些状态,但是想要的 API 并不存在于 OpenResty 之内。这时候,可以选择编写一个 Nginx C 模块,然后暴露出可供 Lua 调用的接口。本文中,我们会分别探讨,如何通过 Nginx 变量或 FFI 的方式去提供 Lua 调用得到的接口。

玩转 OpenResty 协程 API

2017-06-29
阅读 6 分钟
8.3k
注意:本文中列出的所有代码只是 Proof Of Concept,基本上都没有进行错误处理。另外对于一些边际情况,也可能没有考虑清楚。所以对于直接复制文中代码到项目中所造成的一切后果,请自负责任。

beanstalkd binlog 格式解析

2017-05-31
阅读 3 分钟
4.7k
最近工作上需要写一个小工具,用于解析 beanstalkd 的 binlog。一如既往,我先在网上搜索相关的资料。令我惊讶的是,beanstalkd 官方文档中连关于 binlog 格式的只言片语都没有。网络上跟 beanstalkd binlog 格式相关的资料也几乎是个空白。所以在阅读了 beanstalkd 相关源码,并编写了对应工具之后,我试着在本文记下 b...

lua unpack 陷阱

2017-05-13
阅读 2 分钟
8.5k
先看一则示例: {代码...} 拜 Lua 内部实现上的细节所赐,如果传递的数组中带有 nil 值空洞,# 操作符返回的数值并不能反映真实的大小。 直接引用 Lua 5.1 manual 上的说法(Lua 5.2 和 LuaJIT 也是一样的定义): [链接] The Length Operator The length of a table t is defined to be any integer index n such that ...

systemd vs supervisord

2017-05-08
阅读 4 分钟
15.6k
过去我们项目组的应用都是用 supervisord 托管的。最近因为某些因素,无法使用 supervisord,因此考虑改用 systemd。作为主流 Linux 发行版的默认选项,之前多多少少用过一点 systemd。不过这次需要上生产环境,所以抽空深入研究一番。

logstash接入新业务四步走

2017-04-26
阅读 2 分钟
4.4k
第一步:定下好名字 第一步当然是给新的业务起一个响当当的名字啦。后面的各处变更,都要用到这个名字。所以起名时请三思,想出一个别具一格且能顾名思义的好名字。 第二步:添加对应的映射模板 确定名字之后,先给 elasticsearch 准备对应的映射模板。这样一来,新创建的索引就能立即拥有自己的映射规则: type_name_te...

盘点那些不知名却常用的 Git 操作

2017-03-30
阅读 4 分钟
6.6k
Git 非常复杂。我即使几乎每天都在用,也不敢保证对 Git 的每一个角落都了如指掌。本文试图盘点一些不知名,但在我看来较常用的操作。如果没有你预期的操作,说明要么在我看来它很知名,要么在我看来它不太常用。

在 LuaJIT 中调用 Go 函数

2017-03-09
阅读 3 分钟
8.1k
今天同事在公司群里转发了一篇文章:Calling Go Functions from Other Languages 其原理是 通过编译时指定 -buildmode=c-shared 选项,把 Go 程序编译成 C 的动态链接库。 由其他语言通过 FFI 的形式,去调用动态链接库的函数。 于是,只要能支持 FFI 的语言,就能调用事先编译到动态链接库里 Go 的函数。 想到 LuaJIT ...