2017-01-17 3 views
0

У нас есть веб-сайт работает в Windows Server 2008 + SQLServer 2008 + рубин + Синатра + Sequel/PumaSequel + ADO + Puma не пронизывающие запросы

Мы разработали API для нашего сайта. Когда точки доступа запрашиваются многими клиентами, в то же время клиенты начинают получать исключения RequestTimeout.

Я немного расследовал, и я отметил, что Puma управляет многопоточным тонким доступом. Но Sequel (или любой слой ниже Sequel) обрабатывает один запрос вовремя, даже если они поступают от разных клиентов.

Фактически исключения RequestTimeout не возникают, если я запускаю много веб-серверов, каждый из которых прослушивает один другой порт, и каждый клиент назначает один другой порт.

Я еще не знаю, есть ли проблема Sequel, ADO, ODBC, Windows, SQLServer или что. Истина заключается в том, что я не могу переключиться на любой другой технологии (как TinyTDS)

Беллоу маленький кусочек кода со скриншотами, которые вы можете использовать, чтобы воспроизвести ошибку:

require 'sinatra' 
require 'sequel' 
CONNECTION_STRING = 
"Driver={SQL Server};Server=.\\SQLEXPRESS;" + 
"Trusted_Connection=no;" + 
"Database=pulqui;Uid=;Pwd=;" 

DB = Sequel.ado(:conn_string=>CONNECTION_STRING) 
enable :sessions 
configure { set :server, :puma } 
set :public_folder, './public/' 
set :bind, '0.0.0.0' 
get '/delaybyquery.json' do 
tid = params[:tid].to_s 
begin 
puts "(track-id=#{tid}).starting access point" 
q = "select p1.* from liprofile p1, liprofile p2, liprofile p3, liprofile p4, liprofile p5" 
DB[q].each { |row| # this query should takes a lot of time 
puts row[:id] 
} 
puts "(track-id=#{tid}).done!" 
rescue=>e 
puts "(track-id=#{tid}).error:#{e.to_s}" 
end 
end 
get '/delaybycode.json' do 
tid = params[:tid].to_s 
begin 
puts "(track-id=#{tid}).starting access point" 
sleep(30) 
puts "(track-id=#{tid}).done!" 
rescue=>e 
puts "(track-id=#{tid}).error:#{e.to_s}" 
end 
end 

Есть 2 точки доступа в приведенном выше коде:

  1. delaybyquery.json, который генерирует задержку путем присоединения к той же таблицы 5 раз. Обратите внимание, что таблица должна составлять около 1000 строк, чтобы запрос работал очень медленно; и

  2. delaybycode.json, который генерирует задержку просто вызов Рубиновом SLEEP функцию.

Обе точки доступа принимает параметр TID (отслеживание-идентификатор), и оба написать Outout в CMD, так что вы можете следить за активностью процесса, так в том же окна и проверьте, какая точка доступа является блокировка входящих запросов от других браузеров.

Для тестирования я открываю 2 вкладки в одном браузере Chrome. Ниже приведены 2 теста, которые я выполняю.

Шаг 1: Запустите веб-сервер

C: \ источник \ pulqui> рубин example.app.rb -p 81 Я получаю выход ниже

Шаг № 2: Тестирование задержки Кодексом

Я позвонил этому адресу: 127.0.0.1:81/delaybycode.json?tid=123 и через 5 секунд я назвал этот другой URL 127.0.0.1:81/delaybycode.json?TID = 456 Ниже выход, где вы можете увидеть, что оба соединения работают параллельно

click here to see the screenshot

Шаг № 3: Тестирование задержки с помощью Query

Я позвонил этому адресу: 127.0.0.1:81/delaybyquery.json?tid=123 и через 5 секунд я назвал этот другой URL 127.0.0.1:81/delaybyquery.json?tid=456 Ниже приведен вывод, где вы можете видеть, что вызовы работая 1 вовремя. Каждый вызов точки доступа заканчивается исключением таймаута запроса.

click here to see the screenshot

+0

Пожалуйста, нажмите на ссылки, чтобы увидеть скриншоты. Извинения, но StackOverflow не позволяет мне публиковать изображения. –

ответ

0

Это почти наверняка связано с win32ole (драйвер, который использует лукаво адаптер сиквела). Вероятно, это не освобождает GVL во время запросов, что вызовет проблемы, которые вы видите.

Если вы не можете переключиться на TinyTDS или переключиться на JRuby, то ваш единственный вариант, если вы хотите, чтобы параллельные запросы заключались в том, чтобы запускать отдельные процессы веб-сервера и иметь обратный запрос на обратный прокси-сервер.

+0

Спасибо, Джереми. –

Смежные вопросы