狸猫换太子:聊聊那些藏在 Go interface 方法调用里的坑

4 月 14 日
阅读 5 分钟
428
对 interface 的使用想必是一件简单到自然的事。定义一组方法描述特定的行为,然后在某个类上实现这组方法。如此一来,这个类就能作为某些函数的输入或输出参数,而外界无从知晓用作参数的实际的类到底是怎么实现的。interface 带来的“隐藏性”,可以让它的使用者和实现者之间解耦,无需暴露不必要的细节。但是在某些特殊...

为什么 Tetrate 逐渐成为 Envoy Gateway 的主心骨?

2 月 6 日
阅读 4 分钟
410
Envoy Gateway 的发起 是 2022 年网络领域的一件大事。扛着 Envoy 这面大旗,Envoy Gateway 奉天子以令不臣,任何基于 Envoy 的网关都不得不回答一个问题:“你和 Envoy Gateway 是什么关系”。比如:

你的Go应用真的用了正确的 CPU 核数吗?

2023-06-24
阅读 2 分钟
3.4k
Go 的调度模型是 GMP,其中 G 是 goroutine,M 是线程,P 是可用的 CPU 核数。多个 G 会共用一个 M。M 作为操作系统层面上的调度单位,在执行时需要绑定到 P。如果操作系统认为的某个 Go 进程可用的 CPU 数,和该进程认为的可用的 CPU 数不一致,那么即使把 M 绑定到某个 P 上,操作系统也不一定会执行这个线程。所以能...

ebpf 月报 - 2023 年 2 月

2023-02-27
阅读 6 分钟
2.1k
本刊物旨在为中文用户提供及时、深入、有态度的 ebpf 资讯。如果你吃了鸡蛋觉得好吃,还想认识下蛋的母鸡,欢迎关注:笔者的 twitter:[链接]bpftrace 发布 0.17.0 版本[链接]时隔数月,bpftrace 发布了新版本 0.17.0。这个版本,允许直接比较整数数组,还新增了对以下几个架构的支持:龙芯:[链接]ARM32:[链接]此外,...

漫谈负载均衡算法

2023-02-12
阅读 5 分钟
2.2k
负载均衡是个大话题,我们可以谈谈:slow start 给新加入的节点分配较低权重,避免过载priority 不同的可用区(AZ)有不同的优先级,非当前可用区的节点只有在当前可用区节点不可用时才作为备份加入subset 分组负载均衡,会先通过负载均衡算法选择一个组,再通过负载均衡算法在组里选择具体的节点retry 当负载均衡碰上重...

化虹为桥 - Nginx 如何代理 UDP “连接”

2023-01-29
阅读 7 分钟
4.5k
众所周知,UDP 并不像 TCP 那样是基于连接的。但有些时候,我们需要往一个固定的地址发送多个 UDP 来完成一个 UDP 请求。为了保证服务端能够知道这几个 UDP 包构成同一个会话,我们需要在发送 UDP 包时绑定某个端口,这样当网络栈通过五元组(协议、客户端IP、客户端端口、服务端IP、服务端端口)进行区分时,那几个 UDP...

ebpf 月报 - 2023 年 1 月

2023-01-26
阅读 3 分钟
4.3k
Merbridge 是一个旨在通过 ebpf 代替 iptables,给 service mesh 加速的项目。作为成立刚满一周年的新项目,Merbridge 已经应用到 kuma 的官方版本当中。最近 Merbridge 又达到了另外一个里程碑 —— Merbridge 正式成为 CNCF sandbox 项目。

如何开发一个开源网关?

2022-12-10
阅读 3 分钟
3.6k
编写本文并非打算总结开发开源网关的最佳实践,仅仅是谈谈自己的一些观点。基石如果有人问我,开发开源网关最重要的是什么,我会毫不犹豫地提到两点:要有一套一致的设计语言。要有持续的人力投入设计语言由于现在开源项目内卷化,要想推出一个新的开源网关,已经必须要有整套的控制面(CP) + Dashboard + 数据面(DP)...

把 Go 放到 Nginx C module 之中

2022-11-27
阅读 3 分钟
4.2k
最近一段时间,我在做一件有趣的事情,让一个 Nginx C module 通过 Go 代码来访问 gRPC 服务。不得不感慨 Go 真的很流行,让人无法拒绝。之前我做 wasm-nginx-module 时就试图把 tinygo 跑在 Nginx 里面,这次则是把正宗的 Go 跑在 Nginx 里面。这就是无法回避的命运吗?!

CVE-2020-11724:OpenResty HTTP request smuggling 漏洞

2020-07-25
阅读 4 分钟
16.3k
OpenResty 最近发布的正式版本 1.17.8.2 修复了安全漏洞 CVE-2020-11724。这个漏洞是一个 HTTP request smuggling 漏洞,可以实现某种程度上的安全防护绕过。

为何 filebeat 采集日志不是实时的?

2020-03-20
阅读 4 分钟
7.9k
filebeat 采集的日志的时间戳,和日志管理平台实际收到的日志时的时间戳,通常都会有几秒的延迟,有些情况下甚至能达到十几秒。其中固然有 filebeat 到日志管理平台之间的网络带来的影响,但最大的延迟还是出现在日志的产生到 filebeat 上报这个时间段。为何 filebeat 采集日志不是实时的?

丢失的$remote_port

2020-01-29
阅读 2 分钟
6.2k
最近做日志采集的时候发现,部分 Nginx access log 里面的 $remote_port 字段为空。$remote_port 字段提供的是客户端发起连接时使用的端口地址。理论上,如果请求是通过 unix socket 来的,没有端口自然不足为奇。不过我们的请求都是走 TCP 过来的,没有端口便是一件奇事。

Go: Commit失败后是否需要Rollback

2020-01-27
阅读 3 分钟
9.9k
如果 tx.Commit() 失败了,那么 Rollback 的 mock assertion 不会被触发。但跟踪代码时我看到 tx.Rollback() 路径确实会被执行到的。

用docker拓展压测工具artillery的能力

2020-01-07
阅读 2 分钟
2.7k
最近在用 artillery 做压测时遇到一个问题。我需要压测某一个通过域名访问的服务,而这个域名背后的机器地址需要随着压测用例变化的。通常这就是DNS要做的事情 - 把不变的域名和变化的地址关联起来 - 但我又没权限控制这个域名的解析地址。

谈谈go.sum

2019-12-27
阅读 4 分钟
10.2k
众所周知,Go 在做依赖管理时会创建两个文件,go.mod 和 go.sum。相比于 go.mod,关于 go.sum 的资料明显少得多。自然,go.mod 的重要性不言而喻,这个文件几乎提供了依赖版本的全部信息。而 go.sum 看上去就是 go module 构建出来的天书,而不是什么人类可读的数据。

systemtap 探秘(五)- 编译和运行

2019-10-06
阅读 3 分钟
4.1k
编译阶段没有什么要说的,唯一要说明的是 stap 生成的内核模块编译起来很耗时。一般来说,整个编译阶段会花上十几二十秒。所以在生成火焰图时,我通常会让 stap 空跑一遍,让它把内核模块编译出来,完成编译阶段后 Ctrl+C 中断掉它。等到正式压测时,再跑一遍。第二次跑的时候,由于可以用上第一次编译出来的内核,花在...

systemtap 探秘(四)- 函数调用

2019-09-22
阅读 5 分钟
3.9k
上一篇文章,我们介绍了 stp 的类型、变量等基本构成元素。本文将讲解 stp 如何把某些语句编译成对应的 C 代码。stp 在编译 if / for 这样的控制语句时,基本上就是原样翻译成 C 代码(除了一点:break 和 continue 语句是用 goto 实现的)。因此这里只着重谈谈 stp 函数调用是如何被编译成 C 代码的。

systemtap 探秘(三)- 类型、变量和数组

2019-09-13
阅读 6 分钟
8k
上一篇文章,我们展示了几个常见的 probe 生成的 C 代码是怎么样的。本文则讨论 stp 的几种类型,两种变量,以及关联数组。 基本类型 stp 有三种基本类型: long string stats long 类型虽然叫做 long,但其实是 int64_t 的别名。所以即使在 32 位系统上,它还是 64 位整数。 string 类型的变量会被编译成 string_t。而 ...

在 OpenResty 里实现进程间通讯

2019-08-03
阅读 4 分钟
12k
一种简单粗暴但却被普遍使用的方案,就是每个进程划分属于自己的 list 类型的 shdict key,每隔一段时间查看是否有新消息。这种方式优点在于实现简单,缺点在于难以保证实时性。当然对于绝大多数需要进程间通讯的场景,每 0.1 起一个 timer 来处理新增消息已经足够了。毕竟 0.1 秒的延迟不算长,每秒起 10 个 timer 开销...

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

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

systemtap 探秘(一)- 基本介绍

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

如何在 Python 中实现 goto 语句

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

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

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

如何实现一个 circuit breaker

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

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

2019-04-13
阅读 4 分钟
6.4k
如果你用 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 分钟
3.8k
先解释下什么是 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.3k
编写正确且高效的应用,最为关键是一系列软件工程上的实践,像测试、code review、灰度、监控、压测等等。不过由于这是 OpenResty 大会上的演讲,我会专注于讲讲 OpenResty 和 LuaJIT 的一些小细节,帮助各位听众避免线上踩坑。

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

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

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

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