我的當前設置存在問題,它不像預期的那樣工作,並且阻止我進一步擁有服務器(SSE)啓用的網站。我的主要問題可以在下面以粗體顯示,但歸結爲「我如何從Passenger設置中的Sinatra Web應用程序啓動額外的線程?」。乘客,Sinatra,Nginx,RabbitMQ和SSE(乘客啓動過程以及Ruby線程在圖片中的位置)
我使用Passenger 5.0.21和Sinatra 1.4.6。該應用程序被編寫爲經典的Sinatra應用程序,不是模塊化的,但可以根據需要進行更改。
我已將指令passenger_min_instances 3
置於Nginx配置中,以啓動至少3個啓動的web應用程序實例。我有兩個puts
在config.ru
文件我的末日應用程序,以便當線程啓動我進去/var/log/nginx/passenger.log
反饋,也當線程通過其RabbitMQ的隊列接收消息:
...
Thread.new {
puts " [* #{Thread.current.inspect}] Waiting for logs. To exit press CTRL+C"
begin
q.subscribe(:block => true) do |delivery_info, properties, body|
puts " [x #{Thread.current.inspect}] #{body}"
end
rescue Interrupt => _
ch.close
conn.close
end
}
run Sinatra::Application
我希望這個代碼來運行ñ次,n是Passenger發起的進程數。看起來情況並非如此。
此外,我app.rb
包含了很多的東西,它可以簡化爲:
puts "(CLASS)... Inside thread #{Thread.current.inspect}"
configure do
puts "(CONFIGURE)... Inside thread #{Thread.current.inspect}"
end
get '/debug' do
puts "(DEBUG)... Inside thread #{Thread.current.inspect}"
end
當我重新啓動Nginx的,使第一HTTP GET訪問URL /debug
,該過程被實例化和的一個進程服務於請求。我在/var/log/nginx/passenger.log
中得到什麼?
(CLASS)... Inside thread #<Thread:0x007fb29f4ca258 run>
(CONFIGURE)... Inside thread #<Thread:0x007fb29f4ca258 run>
[* #<Thread:[email protected]:68 run>] Waiting for logs. To exit press CTRL+C
(DEBUG)... Inside thread #<Thread:[email protected]/usr/lib/ruby/vendor_ruby/phusion_passenger
192.168.0.11 - test [30/Dec/2015:10:09:08 +0100] "GET /debug HTTP/1.1" 200 2184 0.0138
開始CLASS
和CONFIGURE
兩個消息都被印刷在同一線程內。我預計這會發生在流程實例化時間,但它只發生一次,這讓我認爲乘客只會觸發一個流程。但是我可以看到3個進程passenger-status --verbose
。創建另一個線程(在config.ru
)接收RabbitMQ消息。
正如你可以看到第一處理已處理1周的請求(縮短爲清楚起見):
$ passenger-status --verbose
----------- General information -----------
Max pool size : 6
App groups : 1
Processes : 3
Requests in top-level queue : 0
----------- Application groups -----------
/home/hydro/web2/public:
App root: /home/hydro/web2
Requests in queue: 0
* PID: 1116 Sessions: 0 Processed: 1 Uptime: 2m 19s
CPU: 0% Memory : 18M Last used: 2m 19s ago
* PID: 1123 Sessions: 0 Processed: 0 Uptime: 2m 19s
CPU: 0% Memory : 3M Last used: 2m 19s ago
* PID: 1130 Sessions: 0 Processed: 0 Uptime: 2m 19s
CPU: 0% Memory : 2M Last used: 2m 19s ago
紅寶石性能測試,其公佈爲所述訂戶接收有時工作,有時不RabbitMQ的消息。也許Passenger關閉了正在運行的流程,即使它在特定時間內沒有看到請求。日誌中沒有顯示任何內容。沒有來自訂閱者線程的反饋,沒有來自Passenger本身的消息。
如果我刷新頁面,我會得到DEBUG
消息和GET /debug
跟蹤。 passenger-status --verbose
顯示第一個進程現在已經處理了兩個請求。
我在我的不同測試中看到,我必須發出很多請求來使其他2個進程發出Passenger serve請求,甚至啓動新進程最多6個。讓我們從另一臺機器局域網與
[email protected]:~# ab -A test:test -kc 1000 -n 10000 https://192.168.0.10:445/debug
。 Passenger已啓動最多6個進程來處理請求但我看不到passenger.log
文件中的任何內容,但DEBUG
消息和GET /debug
跟蹤中沒有其他進程已啓動。
$ passenger-status --verbose
----------- General information -----------
Max pool size : 6
App groups : 1
Processes : 6
Requests in top-level queue : 0
----------- Application groups -----------
/home/hydro/web2/public:
App root: /home/hydro/web2
Requests in queue: 0
* PID: 1116 Sessions: 0 Processed: 664 Uptime: 16m 29s
CPU: 0% Memory : 28M Last used: 32s ago
* PID: 1123 Sessions: 0 Processed: 625 Uptime: 16m 29s
CPU: 0% Memory : 27M Last used: 32s ago
* PID: 1130 Sessions: 0 Processed: 614 Uptime: 16m 29s
CPU: 0% Memory : 27M Last used: 32s ago
* PID: 2105 Sessions: 0 Processed: 106 Uptime: 33s
CPU: 0% Memory : 23M Last used: 32s ago
* PID: 2112 Sessions: 0 Processed: 103 Uptime: 33s
CPU: 0% Memory : 22M Last used: 32s ago
* PID: 2119 Sessions: 0 Processed: 92 Uptime: 33s
CPU: 0% Memory : 21M Last used: 32s ago
所以,主要的問題是:我怎麼可以發動(RabbitMQ的用戶)線程從西納特拉Web應用程序每次開始處理時?
我希望能夠將數據發送到我的Web應用程序進程,以便他們可以使用SSE將其發送回Web客戶端。我想每個Web應用程序進程有兩個線程:Sinatra使用的主線程和我的額外線程來執行一些RabbitMQ內容。還有一個Oracle數據庫和一個Erlang後端,但我不認爲它們在這裏相關。
我也想知道Passenger如何在Sinatra Web應用程序的情況下處理進程實例。多個Ruby環境?如果多個進程啓動時,它看起來像只實例化了一次類似的情況呢?即使啓動多個進程,文件config.ru
(甚至app.rb
)是否僅處理一次?我在網上閱讀了很多東西,但無法弄清楚。
更一般地說,用Ruby,Nginx,Passenger和Sinatra做SSE的正確方法是什麼。
有關Nginx的詳細信息已在下面進行了闡述。
Nginx的配置爲在乘客前方一個反向代理的地位和Web應用程序server
和location /
下使用SSL配置和HTTP基本身份驗證和以下指令:
location/{
proxy_buffering off;
proxy_cache off;
proxy_pass_request_headers on;
passenger_set_header Host $http_host;
passenger_set_header X-Real-IP $remote_addr;
passenger_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
passenger_set_header X-Forwarded-Proto $scheme;
passenger_set_header X-Remote-User $remote_user;
passenger_set_header Host $http_host;
passenger_min_instances 3;
proxy_redirect off;
passenger_enabled on;
passenger_ruby /home/hydro/.rbenv/versions/2.3.0/bin/ruby;
passenger_load_shell_envvars on;
passenger_nodejs /usr/bin/nodejs;
passenger_friendly_error_pages on;
}
我認爲你是對的。我選擇的建築是錯誤的。我喜歡單獨推送服務器談論HTTP的想法。 Erlang或Oracle數據庫很容易使用。 – lkuty
我還發現[nchan模塊](https://www.nginx.com/resources/wiki/modules/Nchan/) – lkuty