[英]How can I tell if my Ruby server script is being overloaded?
I have a daemonized ruby script running on my server that looks like this: 我在我的服务器上运行了一个daemonized ruby脚本,如下所示:
@server = TCPServer.open(61101)
loop do
@thr = Thread.new(@server.accept) do |sock|
Thread.current[:myArrayOfHashes] = [] # hashes containing attributes of myObject
SystemTimer.timeout_after(5) do
Thread.current[:string] = sock.gets
sock.close
# parse the string and load the data into myArrayOfHashes
Myobject.transaction do # Update the myObjects Table
Thread.current[:myArrayOfHashes].each do |h|
Thread.current[:newMyObject] = Myobject.new
# load up the new object with data
Thread.current[:newMyObject].save
end
end
end
end
@thr.join
end
This server receives and manages data for my rails application which is all running on Mac OS 10.6. 此服务器接收并管理我的rails应用程序的数据,该应用程序全部在Mac OS 10.6上运行。 The clients call the server every 15 minutes on the 15 and while I currently only have 16 or so clients calling every 15 min on the 15, I'm wondering about the following:
客户端在15分钟内每隔15分钟呼叫一次服务器,而我目前只有16个左右的客户端在15分钟内每15分钟呼叫一次,我想知道以下内容:
Also, is there an article you can point me toward that discusses the best way to implement this kind of a server? 另外,是否有一篇文章可以指出我讨论实现这种服务器的最佳方法? I mean can I have multiple instances of the server listening on the same port?
我的意思是我可以在同一端口上监听多个服务器实例吗? Would that even help?
这会有帮助吗?
I am using Bluepill to monitor my server daemons. 我正在使用Bluepill监视我的服务器守护进程。
1 and 2 1和2
The answer is no, two clients connecting close to each other will not make the connection fail (however multiple clients connecting may fail, see below). 答案是否定的,两个彼此靠近连接的客户端不会使连接失败(但是多个客户端连接可能会失败,见下文)。
The reason is the operating system has a default so called listening queue built into all server sockets. 原因是操作系统在所有服务器套接字中都有一个默认的所谓的侦听队列 。 So even if you are not calling
accept
fast enough in your program, the OS will still keep buffering incoming connections for you. 因此,即使您在程序中没有足够快地调用
accept
,操作系统仍会继续为您缓冲传入连接。 It will buffer these connections for as long as the listening queue does not get filled. 只要侦听队列没有被填充,它就会缓冲这些连接。
Now what is the size of this queue then? 那么这个队列的大小是多少呢?
In most cases the default size typically used is 5. The size is set after you create the socket and you call listen
on this socket (see man page for listen here ). 在大多数情况下,通常使用的默认大小为5.在创建套接字后设置大小,并在此套接字上调用
listen
(请参阅监听此处的手册页 )。
For Ruby TCPSocket
automatically calls listen
for you, and if you look at the C-source code for TCPSocket
you will find that it indeed sets the size to 5: 对于Ruby
TCPSocket
自动调用listen
,如果你看一下TCPSocket
的C源代码,你会发现它确实将大小设置为5:
https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L108 https://github.com/ruby/ruby/blob/trunk/ext/socket/ipsocket.c#L108
SOMAXCONN
is defined as 5 here: SOMAXCONN
在这里定义为5:
https://github.com/ruby/ruby/blob/trunk/ext/socket/mkconstants.rb#L693 https://github.com/ruby/ruby/blob/trunk/ext/socket/mkconstants.rb#L693
Now what happens if you don't call accept fast enough and the queue gets filled? 现在如果你没有足够快地调用accept并且队列被填满会发生什么? The answer is found in the man page of
listen
: 答案可以在
listen
的手册页中找到:
The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.
backlog参数定义sockfd的挂起连接队列可能增长的最大长度。 If a connection request arrives when the queue is full, the client may receive an error with an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may be ignored so that a later reattempt at connection succeeds.
如果连接请求在队列已满时到达,则客户端可能会收到带有ECONNREFUSED指示的错误,或者,如果基础协议支持重新传输,则可以忽略该请求,以便稍后在连接时重新尝试成功。
In your code however there is one problem which can make the queue fill up if more than 5 clients try to connect at the same time: you're calling @thr.join
at the end of the loop. 但是在你的代码中有一个问题,如果超过5个客户端同时尝试连接,则会使队列填满:你在循环结束时调用
@thr.join
。
What effectively happens when you do this is that your server will not accept any new incoming connections until all your stuff inside your accept-thread has finished executing. 执行此操作时实际发生的情况是,在接受线程中的所有内容完成执行之前,您的服务器将不接受任何新的传入连接。
So if the database stuff and the other things you are doing inside the accept-thread takes a long time, the listening queue may fill up in the meantime. 因此,如果数据库内容和您在accept-thread内部执行的其他操作需要很长时间,那么侦听队列可能会在此期间填满。 It depends on how long your processing takes, and how many clients could potentially be connecting at the exact same time.
这取决于您的处理需要多长时间,以及有多少客户端可能在同一时间连接。
3 3
You didn't say which platform you are running on, but on linux/osx the easiest way is to just run top
in your console. 你没有说你正在运行哪个平台,但在linux / osx上最简单的方法是在你的控制台中运行
top
。 For more advanced memory monitoring options you might want to check these out: 有关更高级的内存监视选项,您可能需要检查这些:
ruby/ruby on rails memory leak detection ruby / ruby on rails内存泄漏检测
track application memory usage on heroku 跟踪heroku上的应用程序内存使用情况
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.