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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

使用 Ruby 拓展 Vim

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

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

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

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

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

OpenResty Con 2017 见闻杂记

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

探究 Redis 4 的 stream 类型

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

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

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

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

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

玩转 OpenResty 协程 API

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

beanstalkd binlog 格式解析

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

lua unpack 陷阱

2017-05-13
阅读 2 分钟
8.3k
先看一则示例: {代码...} 拜 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.4k
过去我们项目组的应用都是用 supervisord 托管的。最近因为某些因素,无法使用 supervisord,因此考虑改用 systemd。作为主流 Linux 发行版的默认选项,之前多多少少用过一点 systemd。不过这次需要上生产环境,所以抽空深入研究一番。

logstash接入新业务四步走

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

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

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

在 LuaJIT 中调用 Go 函数

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

评估 Redis 最近的 Cross Protocol Scripting 漏洞

2017-02-02
阅读 3 分钟
3.2k
这意味着,如果我们用 HTTP 协议请求 Redis,那么 Redis 会跳过不认识的各种报头,执行请求体中的命令。举个例子,下面的 HTTP 请求中,只有最后的 EVAL 会被解析成合法的命令并执行。

如何用 Valgrind 检测使用 LuaJIT FFI 过程中的内存泄漏

2017-01-29
阅读 3 分钟
6.2k
给带 GC 的语言写 C binding 一向是件让人迷糊的事。到底应该在 C 手工释放资源呢,还是依靠 GC 来回收?还好 LuaJIT FFI 提供了很好用的 ffi.gc 方法。该方法允许给 cdata 对象注册在 gc 时调用的回调,它能让你在 Lua 领域里完成 C 手工释放资源的事。

redmine 插件开发非官方指南

2017-01-22
阅读 6 分钟
9.1k
redmine 官网上的开发者文档并不多,即使看完后,许多时候你也不知道接下来需要怎么做。好在 redmine 是用“约定高于配置”的 Rails 开发的,其命名相对规范。有必要时,可以猜测下对应的接口叫什么名字。实在摸不到门,阅读 redmine 和网上开源出来的 redmine 插件代码也是条路。

OpenResty 中的真值与假值与坑

2016-12-27
阅读 3 分钟
6.6k
先重温下 Lua 里的真值与假值:除了 nil 和 false 为假,其他值都是真。“其他值”这个概念包括0、空字符串、空表,等等。在 Lua 里,通常使用 and 和 or 作为逻辑操作符。比如 true and false 返回 false,而 false or true 返回 true。

OpenResty Con 2016 见闻杂记

2016-12-12
阅读 4 分钟
5.8k
我昨天参加了在深圳举办的 OpenResty Con 2016,趁着周末有空记录下与会过程,作为路边社的一篇报道。由于内容基于会上的笔记和事后的回忆,读起来会显得琐碎,具体细节可能会有些出入。

mock go 程序的新方法

2016-12-08
阅读 3 分钟
9.8k
一直以来,我都认为在 go 里面 mock 是非常困难的。不像动态语言或者跑在 VM 上的语言,go 要求在开发的时候就给 mock 介入预留空间,不然测试的时候会不得其门而入。开发的时候需要头疼的事情可多了,还要求再考虑下可测试性,真有点强人所难。另外第三方库并不一定给 mock 预留空间,遇到这种情况只能干瞪眼绕路走。很...