之前一直以 java 的服务器运行方式思考 rails 的服务器运行方式,导致心中一直在担心数据的安全。
到今天才明白,这种担心是没有必要的,rails 的服务器一般是以多进程的方式运行,每个进程同一时刻只处理一个 http 请求。
用 rack 简单证明其进程同一时间只处理一个 http 请求. config.ru
require 'rubygems'
require 'rack'
$i ||= 0
$i += 1
puts "$i: #{$i}"
app = proc do |env|
$i += 2
puts " #{$i} #{Time.now} - #{Thread.current.object_id}"
sleep 10
[ 200, {'Content-Type' => 'text/plain'}, ["hello kitty \n"] ]
end
run app
启动 web 服务之后 unicorn config.ru -p 3000 打开两个终端,同时输入 curl localhost:3000 可以看到运行 unicorn 的终端输出先后间隔 10 秒输出二行日志,而且打印出来的的 thread id 是一样的。由此可以证明 web 服务器同一时刻只处理一个请求。
另外多进程方式运行时,每个 web 服务器实例都是单独的 ruby vm. 可以尝试写一个 unicorn config file, 指定 worker_processes 2,可以看出,它输出了两行 "$i: 1", 同时 curl 请求时,打印出来$i值也一样。
这样多 web 服务器实例共享数据需要通过 redis 之类的来实现. 另外数据的跨层 (比如从 controller 传到 model) 共享也需要注意, 在 controller 设置值时失败,那么在 model 层拿到的数据有可能就是上一个 request 生成的数据。这样导致一个隐性的错误,我就犯过一次。-_-!
多线程方面还是了解的不是很清楚,不知道数据库查询怎么保证 threadsafe