liuxiran commented on a change in pull request #512:
URL: https://github.com/apache/apisix-website/pull/512#discussion_r695571388



##########
File path: website/blog/2021-8-25-Why-Apache-APISIX-chose-Nginx-and-Lua.md
##########
@@ -0,0 +1,163 @@
+---
+title: "为什么 Apache APISIX 选择 Nginx + Lua 这个技术栈?"
+author: spacewander
+authorURL: "https://github.com/spacewander";
+authorImageURL: "https://avatars.githubusercontent.com/u/4161644?v=4";
+---
+> [@spacewander](https://github.com/spacewander), Core developer of Apache 
APISIX from [Shenzhen Zhiliu Technology Co.](https://www.apiseven.com/)
+>
+<!--truncate-->
+
+> 本文由 Core developer of OpenResty、Apache APISIX Committer、深圳支流科技工程师罗泽煊撰写,介绍了 
APISIX 选用 Nginx + Lua 这个技术栈的历史背景和这个技术栈为 APISIX 带来的优势。
+
+笔者在今年的 COSCUP 大会做分享时,曾有观众问这样的问题,为什么 APISIX、Kong 和 3scale 这些网关都采用 Lua 来编写逻辑?
+
+是啊,Lua 并不是一门广为人知的语言,离“主流编程语言”的圈子大概还差个十万八千里吧。甚至有一次,我在跟别人交流的时候,对方在说到 Lua 
之前,先停顿了片刻,随后终于打定主意,以"L U A"逐个字母发音的方式表达了对这一罕见之物的称呼。
+
+所以,为什么 APISIX 和其他知名的网关会选择用 Lua 呢?
+
+事实上,APISIX 采用的技术栈并不是纯粹的 Lua,准确来说,应该是 Nginx + Lua。APISIX 以底下的 Nginx 为根基,以上层的 
Lua 代码为枝叶。
+
+## LuaJIT VS Go
+严谨认真的读者必然会指出,APISIX 并非基于 Nginx + Lua 的技术栈,而是 Nginx + LuaJIT (又称 
OpenResty,以下为了避免混乱,会仅仅采用 Nginx + Lua 这样的称呼)。
+
+LuaJIT 是 Lua 的一个 JIT 实现,性能比 Lua 好很多,而且额外添加了 FFI 的功能,能方便高效地调用 C 代码。
+由于现行的主流 API 网关,如果不是基于 OpenResty 实现,就是使用 Go 编写,所以时不时会看到各种 Go 和 Lua 谁的性能更好的比较。  
+
+**就我个人观点看,脱离场景比较语言的性能,是没有意义的。**
+
+首先明确一点,APISIX 是基于 Nginx + Lua 的技术栈,只是外层代码用的是 Lua。所以如果要论证哪种网关性能更好,正确的比较对象是 C + 
LuaJIT 跟 Go 的比较。网关的性能的大头,在于代理 HTTP 请求和响应,这一块的工作主要是 Nginx 在做。
+
+**所以倘若要比试比试性能,不妨比较 Nginx 和 Go 标准库的 HTTP 实现。**
+
+众所周知,Nginx 是一个 bytes matter 的高性能服务器实现,对内存使用非常抠门。举两个例子:
+
+1. Nginx 里面的 request header 在大多数时候都只是指向原始的 HTTP 请求数据的一个指针,只有在修改的时候才会创建副本。
+2. Nginx 代理上游响应时对 buffer 的复用逻辑非常复杂,是我读过的最为烧脑的代码之一。
+
+凭借这种抠门,Nginx 得以屹立在高性能服务器之巅。
+
+相反的,Go 标准库的 HTTP 实现,是一个滥用内存的典型反例。
+
+这可不是我的一面之辞,Fasthttp,一个重新实现 Go 标准库里面的 HTTP 包的项目,就举了两个例子:
+
+1. 标准库的 HTTP Request 结构体没法复用
+2. headers 总是被提前解析好,存储成 
map[string][]string,即使没有用到(原文见:https://github.com/valyala/fasthttp#faq)
+
+Fasthttp 文档里面还提到一些 bytes matter 的优化技巧,建议大家可以阅读下。
+
+事实上,即使不去比较作为网关核心的代理功能,用 LuaJIT 写的代码不一定比 Go 差多少。原因有二。
+
+**其一,拜 Lua 跟 C 良好的亲和力所赐,许多 Lua 的库核心其实是用 C 写的。 **
+
+比如 lua-cjson 的 json 编解码,lua-resty-core 的 base64 编解码,实际上大头是用 C 实现的。
+而 Go 的库,当然是大部分用 Go 实现的。虽然有 CGO 这种东西,但是受限于 Go 的协程调度和工具链的限制,它在 Go 
的生态圈里面只能处于从属的地位。
+
+关于 LuaJIT 和 Go 对于 C 的亲和力的比较,推荐 Hacker News 上的这篇文章:《Comparing the C FFI 
overhead in various programming languages》(链接 
https://news.ycombinator.com/item?id=17161168)
+
+于是我们比较 Lua 的某些功能,其实还是会回到 C 和 Go 的比较中。
+
+**其二,LuaJIT 的 JIT 优化无出其右 **

Review comment:
       ```suggestion
   **其二,LuaJIT 的 JIT 优化无出其右**
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to