简体   繁体   English

如何判断我的Ruby服务器脚本是否正在重载?

[英]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分钟呼叫一次,我想知道以下内容:

  1. If two clients call at close enough to the same time, will one client's connection attempt fail? 如果两个客户端的呼叫时间足够接近,那么一个客户端的连接尝试是否会失败?
  2. How I can figure out how many client connections my server can accommodate at the same time? 我怎样才能弄清楚我的服务器可以同时容纳多少个客户端连接?
  3. How can I monitor how much memory my server is using? 如何监控服务器使用的内存量?

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.

相关问题 启动Rails应用程序时如何启动ruby服务器脚本? - How can I start up a ruby server script when I start up my rails app? Ruby TCPSocket服务器-我可以告诉客户端连接的主机吗? - Ruby TCPSocket Server - Can I tell to what host a client was connecting? (异步/多线程)如何告诉 ruby 保存到我的数据库,但继续处理而不是等待保存事件完成? - (Async/MultiThread) How can I tell ruby to save to my database, but to continue processing and not to wait for the save event to complete? 如何通过Ruby脚本在桌面上创建文件? - How can I create a file on my desktop from a Ruby script? 如何使Ruby脚本(而不是Rails)在任何地方运行? - How can I make my Ruby script (not Rails) run anywhere? 如何让我的Ruby脚本在运行时宣布值? - How can I make my Ruby script announce values as it runs? Ruby 脚本可以告诉它在哪个目录中吗? - Can a Ruby script tell what directory it’s in? Ruby on Rails:XSS预防:如何防止将null作为数据传递到服务器? - Ruby on rails: XSS prevention: how do I prevent null from being passed as data to my server? linux说我的ruby程序的语法错误。 我怎样才能说出我的意思? 有没有记录的方法? - linux says my ruby program's syntax is wrong. How can I tell what I'm saying? Is there a way to log it? 我如何知道jQueryUI是否已在Rails 3.1中正确加载? - How can I tell if jQueryUI is being loaded properly in Rails 3.1?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM