Net :: SSH性能,为什么这么慢?

时间:2017-08-30 21:51:45

标签: ruby net-ssh

我在Ruby中有一个自动化测试用例(使用我正在构建see github的框架),就像大约15-20个SSH连接到被测服务器收集各种数据和日志一样。

问题是它需要很长时间才能实际执行任何操作,这意味着要执行自己。我启用了require 'profile'探查器,试图找出它究竟在做什么。 这是列表的顶部:

     time   seconds   seconds    calls  ms/call  ms/call  name
 18.84     8.37      8.37       82   102.10   102.10  OpenSSL::PKey::DH#generate_key!
  6.20    11.13      2.75    45978     0.06     0.26  Net::SSH::Transport::PacketStream#poll_next_packet
  3.93    12.87      1.75    83928     0.02     0.06  OpenSSL::PKey::DH#valid?
  2.64    14.05      1.17    27319     0.04     0.22  Wasabi::Parser#process_type
  2.57    15.19      1.14    13698     0.08     0.11  Net::SSH::Buffer#read
  1.94    16.05      0.86    24438     0.04     0.64  Net::SSH::Transport::PacketStream#next_packet
  1.83    16.87      0.81    47183     0.02     0.03  Net::SSH::Buffer#available
  1.66    17.61      0.74    47183     0.02     0.05  Net::SSH::BufferedIo#available
  1.58    18.31      0.70    46662     0.02     1.25  Net::SSH::Transport::Session#poll_message
  1.57    19.00      0.70    21819     0.03     2.07  Net::SSH::Transport::Session#wait
  1.48    19.66      0.66       84     7.83    34.37  Integer#times
  1.48    20.32      0.66    64205     0.01     0.01  Net::SSH::Buffer#length
  1.41    20.94      0.63    31212     0.02     0.77  Nokogiri::XML::NodeSet#each
  1.34    21.54      0.60      834     0.71    25.34  Kernel#gem_original_require
  1.15    22.05      0.51    26202     0.02     3.04  Array#each
  1.06    22.52      0.47    15127     0.03     0.04  Net::SSH::Transport::HMAC::Abstract.mac_length
  0.96    22.95      0.43     9520     0.04     0.14  Wasabi::Parser#input_output_for
  0.94    23.37      0.42    12291     0.03     0.07  Nokogiri::XML::Searchable#extract_params
  0.85    23.75      0.38    24438     0.02     2.26  Kernel#loop
  0.81    24.10      0.36    19890     0.02     0.02  #<OpenSSL::Cipher:0x58730a0>.xor!
  0.78    24.45      0.35     4346     0.08     0.35  Net::SSH::Buffer.from
  0.78    24.80      0.34    28736     0.01     0.03  Savon::Builder#namespace_by_uri
  0.73    25.12      0.33     4845     0.07     0.09  Net::SSH::Transport::State#update_next_iv
  0.68    25.42      0.30    10865     0.03     0.14  Net::SSH::Transport::PacketStream#enqueue_packet
  0.67    25.72      0.30       82     3.62     3.62  OpenSSL::PKey::DH#compute_key
  0.63    26.00      0.28    12819     0.02     0.51  Hash#each
  0.63    26.28      0.28    13003     0.02     4.07  Class#new
  0.63    26.57      0.28    38403     0.01     0.01  Nokogiri::XML::Node#attribute
  0.63    26.84      0.28    23036     0.01     0.02  Net::SSH::Compat.io_select
  0.56    27.09      0.25    84338     0.00     0.00  OpenSSL::PKey::DH#pub_key
  0.52    27.33      0.23     7893     0.03     0.10  Gem::BasicSpecification#have_file?
  0.50    27.55      0.22   102844     0.00     0.00  Fixnum#-
  0.49    27.77      0.22    22278     0.01     0.03  Net::SSH::Transport::PacketStream#available_for_read?
  0.49    27.98      0.22     4525     0.05     0.18  Net::SSH::Buffer#read_long
  0.49    28.20      0.22     4838     0.04     0.42  Net::SSH::KnownHosts#keys_for
  0.49    28.42      0.22     2025     0.11     0.14  Net::SSH::Transport::State#increment
  0.45    28.62      0.20   121786     0.00     0.00  Fixnum#+
  0.45    28.82      0.20     1966     0.10     0.39  Net::SSH::Transport::ServerVersion#negotiate!
  0.45    29.02      0.20    15117     0.01     0.06  

有没有人经历过类似的事情并且可能找到解决方案?

这是我的代码:

    ##
    # generic SSH request
    # 
    # ==== Attributes
    # * +ssh_h+ - host
    # * +ssh_u+ - user
    # * +ssh_u+ - user
    # * +ssh_p+ - password
    # * +cmd+ - command
    # * +onlyOutput+ - if true, return only the result of the command, else, return the command itself as well
    # * +options+ - various options like custom port for ex
    # 
    def sshcmd(ssh_h, ssh_u, ssh_p, cmd, onlyOutput = false, options = {})
        ssh_port = options[:port] ? options[:port] : '22'
        logger.debug "SSH (#{ssh_u}@#{ssh_h}:#{ssh_port}): " + cmd
        Net::SSH.start(
            ssh_h,
            ssh_u,
            {:port => ssh_port,
            :password => ssh_p,
            # :verbose => :debug,
            :auth_methods => ['publickey','hostbased','password','keyboard-interactive'],
            :forward_agent => true}
        ) do|ssh| 
            out = ''
            if onlyOutput == true
                out = ssh.exec!(cmd)
            else
                out = cmd+"\n"+ssh.exec!(cmd)
            end
            logger.debug out
            return out
        end
end

更新:这是我目前的版本,效果更好一点。至少现在连接3次(每台服务器1个连接):

##
# generic SSH request
# 
# ==== Attributes
# * +ssh_h+ - host
# * +ssh_u+ - user
# * +ssh_u+ - user
# * +ssh_p+ - password
# * +cmd+ - command
# * +onlyOutput+ - if true, return only the result of the command, else, return the command itself as well
# * +options+ - various options like custom port for ex
# 
def sshcmd(ssh_h, ssh_u, ssh_p, cmd, onlyOutput = false, options = {})
    ssh_port = options[:port] ? options[:port] : '22'
    logger.debug "SSH (#{ssh_u}@#{ssh_h}:#{ssh_port}): " + cmd
    logger.debug "SSH number of SSH connections in $sshConnnections pool: #{$sshConnnections.size}"
    Thread.current[:user_connections] ||= {}
    connectionName = ssh_h+"-"+ssh_port+"-"+ssh_u
    unless Thread.current[:user_connections].key?(connectionName)
        logger.debug "SSH Create new SSH connection (#{ssh_u}@#{ssh_h}:#{ssh_port}) for command: " + cmd + ""
        Thread.current[:user_connections][connectionName] = Net::SSH.start(
            ssh_h,
            ssh_u,
            {:port => ssh_port,
            :password => ssh_p,
            # :verbose => :debug,
            :max_pkt_size => 0x10000,
            :paranoid => false,
            :keepalive => true,
            :config => false,
            :compression => true,
            # :auth_methods => ['password','publickey','hostbased','keyboard-interactive'],
            :auth_methods => ['password'],
            :forward_agent => true}
        )
    else
        logger.debug "SSH Using existing SSH connection (#{ssh_u}@#{ssh_h}:#{ssh_port}) for command: " + cmd + ""
    end

    if onlyOutput == true
        out = Thread.current[:user_connections][connectionName].exec!(cmd)
    else
        out = cmd+"\n"+Thread.current[:user_connections][connectionName].exec!(cmd)
    end
    logger.debug out
    out
end

剖析器显示:

 time   seconds   seconds    calls  ms/call  ms/call  name
 38.21     8.20      8.20        3  2734.33  2734.33  OpenSSL::PKey::DH#generate_key!
  5.25     9.33      1.13    27319     0.04     0.23  Wasabi::Parser#process_type
  3.13    10.00      0.67      843     0.80    23.56  Kernel#gem_original_require
  2.91    10.63      0.62    31212     0.02     0.78  Nokogiri::XML::NodeSet#each
  2.76    11.22      0.59    12291     0.05     0.09  Nokogiri::XML::Searchable#extract_params
  1.89    11.63      0.41    18391     0.02     2.42  Array#each
  1.80    12.01      0.39    28736     0.01     0.03  Savon::Builder#namespace_by_uri
  1.54    12.35      0.33    70350     0.00     0.00  Hash#[]
  1.47    12.66      0.31     9520     0.03     0.13  Wasabi::Parser#input_output_for
  1.23    12.92      0.26     4606     0.06     0.08  Net::SSH::Buffer#read
  1.16    13.17      0.25    38403     0.01     0.01  Nokogiri::XML::Node#attribute
  1.09    13.41      0.23    12468     0.02     0.12  Hash#each
  1.03    13.63      0.22    47225     0.00     0.01  Hash#[]=
  0.88    13.82      0.19     4097     0.05     0.16  Nokogiri::XML::Searchable#xpath_impl
  0.86    14.00      0.18     4097     0.05     0.21  Nokogiri::XML::Searchable#xpath_internal
  0.82    14.18      0.18     8361     0.02     0.09  Gem::BasicSpecification#have_file?
  0.82    14.35      0.17     7200     0.02     0.30  Savon::Builder#convert_type_namespaces_to_hash
  0.73    14.51      0.16     1623     0.10     0.15  Wasabi::CoreExt::String#snakecase
  0.72    14.66      0.15     8194     0.02     0.05  Nokogiri::XML::XPathContext#register_namespaces
  0.67    14.81      0.14     7446     0.02     0.03  Nokogiri::XML::Node#[]
  0.65    14.95      0.14    31841     0.00     0.00  Nokogiri::XML::Node#to_s
  0.58    15.07      0.12     1377     0.09     2.11  Wasabi::Parser#parse_operations
  0.52    15.18      0.11     2995     0.04     0.12  Net::SSH::Transport::PacketStream#enqueue_packet
  0.51    15.29      0.11    10303     0.01     0.01  Array#hash
  0.51    15.40      0.11     1238     0.09     0.86  Net::SSH::Transport::PacketStream#poll_next_packet
  0.50    15.51      0.11     5232     0.02     5.47  nil#
  0.44    15.60      0.09      912     0.10     0.41  Net::SSH::Buffer.from
  0.44    15.70      0.09     1699     0.06    11.36  Net::SSH::Transport::Session#poll_message
  0.44    15.79      0.09     9486     0.01     1.26  Integer#upto

0 个答案:

没有答案