我在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