gevent 是 python 中我最喜欢库之一。
只要 import gevent, 调用下 monkey patch 便会把线程替换为绿色线程,并且把标准库 socket 打上补丁。
每次 IO 操作都会由类库自动切换到其他绿色线程。对用户几乎完全透明,堪称 IO 性能的免费午餐。(建议看这里了解详细: gevent 和异步)
身为 rubyist 一直很羡慕隔壁的 gevent。之前虽也有过 em-synchronize 之类使用 Fiber 来表达同步的库( 也可以看这篇了解,不再累述),但总归昙花一现,而且无法做到对用户透明用起来没 gevent 这么方便。
最近耐心看了 gevent 源码,尝试在 ruby 中实现类似能力。产出是 LightIO,目标是为 ruby 用户提供免费的 IO 午餐
核心实现起来很简单。但 ruby 的标准库接口庞大,要实现可以 Monkey Patch 的类得花费一番功夫。所以目前只支持有限的几个类 (Socket, TCPSocket, IO 等等)
和 gevent 一样,可以显式的使用 LightIO 来编写代码,目前已经能稳定的支持
如下示例,使用 LightIO 下 的 Beam
, TCPServer
相比标准库可以获得更好的性能。(基础用法)
# echo server example, use telnet to test
LightIO::TCPServer.open('127.0.0.1', 3000) do |server|
puts "start echo server"
while (socket = server.accept)
LightIO::Beam.new(socket){|s|
_, port, host = s.peeraddr
puts "accept connection from #{host}:#{port}"
loop {s << s.readpartial(4096) rescue break puts("client leave #{host}:#{port}")}
}
end
end
另一种精髓用法是使用 LightIO
namespace 下的类进行全局 Monkey Patch, 目前仍未完美支持。
最近成功的用 LightIO Monkey Patch 了 Webrick,用 ab 本机测了下,性能的确有所提升。 https://github.com/jjyr/lightio_benchmark
在 aws 的 1G 机器上大概每秒多处理 100 个 请求。提升不太明显,原因 1 是和 Webrick 代码本身有关,2 是目前大多数服务器也是异步 IO,只测 Hello World 不会有太大区别。 在更贴近真实环境的情况下 LightIO 的绿色线程会有更大优势。
同时试了下 sinatra 还无法支持..应该是 sinatra 使用了目前 LightIO 没有包含的标准库。
目前的下个目标就定位可以 Monkey Patch sinatra 应用
道阻且长,完美的 Monkey Patch 标准库是难以短时间实现的。
但 LightiO 已经可以提供很好的支持使用,如果有人写一些高性能的 Server/爬虫 等服务,可以考虑使用 LightIO 来实现。