mirror of https://github.com/jumpserver/jumpserver
perf: 优化 applet 发布机选择
parent
642f92c0a3
commit
bebb90f688
|
@ -1,6 +1,7 @@
|
|||
import os.path
|
||||
import random
|
||||
import shutil
|
||||
from collections import defaultdict
|
||||
|
||||
import yaml
|
||||
from django.conf import settings
|
||||
|
@ -148,6 +149,22 @@ class Applet(JMSBaseModel):
|
|||
shutil.copytree(path, pkg_path)
|
||||
return instance, serializer
|
||||
|
||||
host_prefer_key_tpl = 'applet_host_prefer_{}'
|
||||
|
||||
@classmethod
|
||||
def clear_host_prefer(cls):
|
||||
cache.delete_pattern(cls.host_prefer_key_tpl.format('*'))
|
||||
|
||||
def _select_by_load(self, hosts):
|
||||
using_keys = cache.keys(self.host_prefer_key_tpl.format('*'))
|
||||
using_host_ids = cache.get_many(using_keys)
|
||||
counts = defaultdict(int)
|
||||
for host_id in using_host_ids.values():
|
||||
counts[host_id] += 1
|
||||
|
||||
hosts = list(sorted(hosts, key=lambda h: counts[h.id]))
|
||||
return hosts[0]
|
||||
|
||||
def select_host(self, user, asset):
|
||||
hosts = self.hosts.filter(is_active=True)
|
||||
hosts = [host for host in hosts if host.load != 'offline']
|
||||
|
@ -161,14 +178,15 @@ class Applet(JMSBaseModel):
|
|||
return matched[0]
|
||||
|
||||
hosts = [h for h in hosts if h.auto_create_accounts]
|
||||
prefer_key = 'applet_host_prefer_{}'.format(user.id)
|
||||
prefer_key = self.host_prefer_key_tpl.format(user.id)
|
||||
prefer_host_id = cache.get(prefer_key, None)
|
||||
pref_host = [host for host in hosts if host.id == prefer_host_id]
|
||||
|
||||
if pref_host:
|
||||
host = pref_host[0]
|
||||
else:
|
||||
host = random.choice(hosts)
|
||||
cache.set(prefer_key, host.id, timeout=None)
|
||||
host = self._select_by_load(hosts)
|
||||
cache.set(prefer_key, str(host.id), timeout=None)
|
||||
return host
|
||||
|
||||
def get_related_platform(self):
|
||||
|
@ -241,9 +259,9 @@ class Applet(JMSBaseModel):
|
|||
def select_host_account(self, user, asset):
|
||||
# 选择激活的发布机
|
||||
host = self.select_host(user, asset)
|
||||
logger.info('Select applet host: {}'.format(host.name))
|
||||
if not host:
|
||||
return None
|
||||
logger.info('Select applet host: {}'.format(host.name))
|
||||
|
||||
valid_accounts = host.accounts.all().filter(is_active=True, privileged=False)
|
||||
account = self.try_to_use_private_account(user, host, valid_accounts)
|
||||
|
|
|
@ -20,6 +20,9 @@ logger = get_logger(__file__)
|
|||
def on_applet_host_create(sender, instance, created=False, **kwargs):
|
||||
if not created:
|
||||
return
|
||||
# 新建时,清除原来的首选,避免一直调度到一个上面
|
||||
Applet.clear_host_prefer()
|
||||
|
||||
applets = Applet.objects.all()
|
||||
instance.applets.set(applets)
|
||||
|
||||
|
|
Loading…
Reference in New Issue