Hello!
我并不是 Go 方面的专家,只是大略列表一下 OpenResty 相对于 Go 的优势:
1. Lua 是全动态语言,支持动态加载和卸载代码,可以在请求级别完成。Go 世界的一些哥们尝试过把动态语言 VM 嵌入进 Go 或用 Go
来实现上层语言的解释器,性能都极差。因为 Go 是很封闭的运行时环境,并不能方便而高效地进行嵌入或扩展。
2. 享受 NGINX 完整的基础设施和生态圈。像二进制热升级和 0 下线时间的整体配置 reload 这样的功能都是由 NGINX 直接提供。
3. 单线程编程方式,方便用 C 扩展,同时通常不用考虑线程安全的问题,开发成本大大下降。而 Go 是多线程模型,对于 C
扩展而言,要么得确保线程安全,要么就要加一把大锁。当然 cgo 还有更多的限制了。
4. 根据我们之前线上观察的规则,Go 运行时的线程调度器的 CPU 损耗非常大,而且很难优化。
5. Go 在底层实现上继承了 Plan9 系统的很多古老的设计,我之前看连 ABI 都是 plan9
的。这使得很多现有的调试和动态追踪工具链和 Go 系统存在较大的兼容性问题。我记得我在上一家东家分析那些运行缓慢的 Go
进程时,都只能在系统调用及其以下层面进行分析,用户态是一团乱麻,非常郁闷。
总而言之,Go 在我看来是一个很尴尬的抽象层面,一方面它不及 C/C++ 那么底层那么有控制力,另一方面它又不及 Lua
这样的动态语言那么灵活,那么动态。更要命的是它的设计是相当封闭的(不封闭也没有做它的那些抽象了),不像 nginx 或 luajit
那样方便深度定制和扩展。
当然了,Go 用作简单的服务还是比较方便的,但如果一旦业务复杂度上去了,就会越写越纠结,至少这是我看到的前东家的一些 Go 粉工程师用 Go
做公司项目之后的痛的领悟。相比之下,Rust 看起来还更有前途一些,可以用作 C++ 的替代物,当然和 OpenResty
也不在一个抽象层面上就是了。而 Erlang 的性能我也不敢恭维了,嘿嘿。
当然了,作为 OpenResty 的作者,我的观点肯定是具有偏向性的,仅供参考。
Regards,
Yichun
2017-09-05 2:58 GMT-07:00 <kfli...@gmail.com>:
> Openresty和Go的本质是一样的,都是用户态线程解决高并发问题,那么相对GO的优势是什么?该如何选择?这种选型问题一直困扰我
>
> 在 2017年8月31日星期四 UTC+8上午10:39:29,agentzh写道:
>>
>> Hello!
>>
>> 2017-08-30 2:01 GMT-07:00 鱼儿飞:
>> > openresty底层应该有个协程 调度器、然后socket都加入到epoll中了、我想知道、我在lua代码层面、这个函数
>> > ngx.socket.tcp() 是否挂起了当前协程、
>>
>> ngx.socket.tcp() 这个函数本身并不会 yield,因为这个函数调用本身并不涉及任何 I/O。返回的 cosocket
>> 对象如果有连接、读和写操作,那些这些涉及 I/O 的操作有可能会 yield 当前的 Lua 轻线程(当然,也不一定会
>> yield,如果只是纯缓冲区读写的话)。
>>
>> >
>> > 也就是说我调用这个函数生成一个socket(不管是创建了mysql、memcache、redis等)的连接、他是否会挂起当前的协程、把控制权交给主线程、也就是去处理其他的request去了、、
>> > 想先在这里问一下、有机会再看下源码~
>> >
>>
>> 对于一般的情况,自然会在 I/O 操作中把控制权交还给 nginx 事件循环的,要不然就阻塞了,就和 php
>> 这些东西没啥区别了,就无法单机很好地处理上万乃至上百万的并发连接了。
>>
>> Regards,
>> Yichun
>
> --
>