Sinatra 框架中线程安全 lock 参数介绍_友好速搭

友好速搭

Sinatra 框架中线程安全 lock 参数介绍

分类: 电商搭建 | 发表时间:2015.06.10 11:18
Kevin
·
-
电商搭建 2015.06.10 11:18

#图片名称 友好速搭的核心业务系统,都是基于 Ruby 的 Padrino 框架开发。它比知名的 Rails 框架轻量很多,是基于 Sinatra 开发。在部署上,使用多线程的 Puma。Puma 使用多线程,来处理 Web 请求。因此,线程安全,是尤其要留意的问题。之前的博客剖析过 Ruby 语言层面的线程安全问题,这篇博客,主要从框架层面,谈谈线程安全。

在 Sinatra 的官方文档中,介绍了用于线程安全的:lock参数:

Sinatra can be used in threaded environments where more than a single request is processed at a time. However, not all applications and libraries are thread-safe and may cause intermittent errors or general weirdness. Enabling the :lock setting causes all requests to synchronize on a mutex lock, ensuring that only a single request is processed at a time.
The :lock setting is disabled by default.

可以通过一段简单的代码,来检验下 Sinatra 的:lock配置:

require 'sinatra'

set :bind, '0.0.0.0'
# 指定 app server
set :server, 'puma'
# 指定端口号
set :port, '8001'
# 开启锁保护
set :lock, true

# 用于测试的 model
class User
  class << self
    attr_accessor :counter
  end
  @counter = 0
end

# 线程不安全接口
get "/unsafe" do
  counter = User.counter
  sleep(0.1)
  counter += 1
  sleep(0.1)
  User.counter = counter
end

# 查看结果
get "/result" do
  User.counter.to_s
end

启动上面的代码,使用 Apache 的 ab 工具,模拟大量请求,访问不安全接口:
ab -n 200 -c 100 http://localtest:8001/unsafe
测试完成后,显示的请求处理速度,为平均4.98个每秒,/result接口返回200(多次执行 ab 测试,返回都是200)。
/unsafe接口中,指定线程 sleep 了200毫秒,平级每秒处理5个请求以下,很正常,说明请求是被逐个执行。

将上述代码中,set :lock true一句注释以后,再执行相同的 ab 命令。测试完成后,显示的请求处理速度,为平均75.45个每秒,/result接口返回小于200(多次执行 ab 测试,返回的值都不同)。
结果说明请求是被多线程并发处理,使得请求处理速度,提升15倍,但由于代码线程不安全,导致数据不准确。

在多线程环境下,如果应用本身,或者依赖的Gem,并非线程安全,可以启用这个配置:set :lock true。启用后,进入 Sinatra 的请求,需要先获取锁,才会被处理。这种情况下,使用 Puma 的多线程并没优势,可以将 Puma 的线程数量,配置为1:threads 0, 1,保持 Sinatra 的:lock为默认关闭,可以达到同样效果。

一旦关闭了多线程,那访问站点的众多请求,在一个进程中,只能被顺序逐一处理,无法实现高效并发处理。

分享文章
免费领取15天试用
立即注册
联系客服
微信咨询
微信二维码

领取免费试用资格

姓名 *

电话 *

公司名称

所在地区

意向产品

提交

提交成功

你好, XXX女士/先生 ,你的需求已提交成功,后续会有专门的客户经理与你电话联系。谢谢!