Для Ваших потребностей используйте ConcurrentHashMap
. Это позволяет параллельную модификацию Карты от нескольких потоков без потребности заблокировать их. Collections.synchronizedMap(map)
создает блокирующуюся Карту, которая ухудшит производительность, хотя гарантируют непротиворечивость (если используется правильно).
Использование вторая опция, если необходимо гарантировать непротиворечивость данных и каждый поток, должна иметь актуальное представление карты. Используйте первое, если производительность очень важна, и каждый поток только вставляет данные в карту с чтениями, происходящими менее часто.
Вот простое и дешевое решение для начала работы
from subprocess import *
p = Popen('ssh servername who', shell=True, stdout=PIPE)
p.wait()
print p.stdout.readlines()
возвращает (например)
['usr pts/0 2009-08-19 16:03 (kakapo)\n',
'usr pts/1 2009-08-17 15:51 (kakapo)\n',
'usr pts/5 2009-08-17 17:00 (kakapo)\n']
и для cpuinfo:
p = Popen('ssh servername cat /proc/cpuinfo', shell=True, stdout=PIPE)
Если ваши потребности перерастают в простой " ssh remote-host.example.org who
", то есть замечательная библиотека Python, которая называется RPyC . Он имеет так называемый «классический» режим, который позволяет почти прозрачно выполнять код Python по сети с помощью нескольких строк кода. Очень полезный инструмент для надежных сред.
Вот пример из Википедии:
import rpyc
# assuming a classic server is running on 'hostname'
conn = rpyc.classic.connect("hostname")
# runs os.listdir() and os.stat() remotely, printing results locally
def remote_ls(path):
ros = conn.modules.os
for filename in ros.listdir(path):
stats = ros.stat(ros.path.join(path, filename))
print "%d\t%d\t%s" % (stats.st_size, stats.st_uid, filename)
remote_ls("/usr/bin")
Если вам интересно, есть хороший учебник на их вики .
Но, конечно, если вы ' Вы прекрасно справляетесь с вызовами ssh с использованием Popen
или просто не хотите запускать отдельный демон "RPyC", тогда это определенно излишек.
Я использовали Pexpect , который позволяет вам подключаться к машинам по ssh, отправлять команды, читать вывод и успешно реагировать на него. Я даже начал вокруг него проект с открытым исходным кодом, Proxpect , который не обновлялся уже много лет, но я отвлекся ...
Модуль pexpect может помочь вам взаимодействовать с ssh. Более или менее вот как будет выглядеть ваш пример.
child = pexpect.spawn('ssh servername')
child.expect('Password:')
child.sendline('ABCDEF')
(output,status) = child.sendline('who')
Это касается баз. Обратите внимание на использование sudo для вещей, требующих дополнительных привилегий. Мы настроили sudo так, чтобы эти команды были разрешены для этого пользователя без необходимости ввода пароля.
Также имейте в виду, что вы должны запустить ssh-agent, чтобы это "имело смысл". Но в целом работает очень хорошо. Запуск deploy-control httpd configtest
проверит конфигурацию apache на всех удаленных серверах.
#!/usr/local/bin/python
import subprocess
import sys
# The user@host: for the SourceURLs (NO TRAILING SLASH)
RemoteUsers = [
"deploy@host1.example.com",
"deploy@host2.appcove.net",
]
###################################################################################################
# Global Variables
Arg = None
# Implicitly verified below in if/else
Command = tuple(sys.argv[1:])
ResultList = []
###################################################################################################
for UH in RemoteUsers:
print "-"*80
print "Running %s command on: %s" % (Command, UH)
#----------------------------------------------------------------------------------------------
if Command == ('httpd', 'configtest'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd configtest'))
#----------------------------------------------------------------------------------------------
elif Command == ('httpd', 'graceful'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd graceful'))
#----------------------------------------------------------------------------------------------
elif Command == ('httpd', 'status'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd status'))
#----------------------------------------------------------------------------------------------
elif Command == ('disk', 'usage'):
CommandResult = subprocess.call(('ssh', UH, 'df -h'))
#----------------------------------------------------------------------------------------------
elif Command == ('uptime',):
CommandResult = subprocess.call(('ssh', UH, 'uptime'))
#----------------------------------------------------------------------------------------------
else:
print
print "#"*80
print
print "Error: invalid command"
print
HelpAndExit()
#----------------------------------------------------------------------------------------------
ResultList.append(CommandResult)
print
###################################################################################################
if any(ResultList):
print "#"*80
print "#"*80
print "#"*80
print
print "ERRORS FOUND. SEE ABOVE"
print
sys.exit(0)
else:
print "-"*80
print
print "Looks OK!"
print
sys.exit(1)
Fabric - это простой способ автоматизировать некоторые простые задачи, подобные этой, версия, которую я сейчас использую, позволяет вам обернуть up такие команды:
run('whoami', fail='ignore')
вы можете указать параметры конфигурации (config.fab_user, config.