mirror of https://github.com/jumpserver/jumpserver
perf: 优化 applet 选择账号调度
parent
680d31dad2
commit
a33540710e
|
@ -14,6 +14,7 @@ class AccountFilterSet(BaseFilterSet):
|
||||||
username = drf_filters.CharFilter(field_name="username", lookup_expr='exact')
|
username = drf_filters.CharFilter(field_name="username", lookup_expr='exact')
|
||||||
address = drf_filters.CharFilter(field_name="asset__address", lookup_expr='exact')
|
address = drf_filters.CharFilter(field_name="asset__address", lookup_expr='exact')
|
||||||
asset_id = drf_filters.CharFilter(field_name="asset", lookup_expr='exact')
|
asset_id = drf_filters.CharFilter(field_name="asset", lookup_expr='exact')
|
||||||
|
asset = drf_filters.CharFilter(field_name='asset', lookup_expr='exact')
|
||||||
assets = drf_filters.CharFilter(field_name='asset_id', lookup_expr='exact')
|
assets = drf_filters.CharFilter(field_name='asset_id', lookup_expr='exact')
|
||||||
nodes = drf_filters.CharFilter(method='filter_nodes')
|
nodes = drf_filters.CharFilter(method='filter_nodes')
|
||||||
node_id = drf_filters.CharFilter(method='filter_nodes')
|
node_id = drf_filters.CharFilter(method='filter_nodes')
|
||||||
|
|
|
@ -156,10 +156,11 @@ class Applet(JMSBaseModel):
|
||||||
|
|
||||||
spec_label = asset.labels.filter(name__in=['AppletHost', '发布机']).first()
|
spec_label = asset.labels.filter(name__in=['AppletHost', '发布机']).first()
|
||||||
if spec_label:
|
if spec_label:
|
||||||
host = [host for host in hosts if host.name == spec_label.value]
|
matched = [host for host in hosts if host.name == spec_label.value]
|
||||||
if host:
|
if matched:
|
||||||
return host[0]
|
return matched[0]
|
||||||
|
|
||||||
|
hosts = [h for h in hosts if h.auto_create_accounts]
|
||||||
prefer_key = 'applet_host_prefer_{}'.format(user.id)
|
prefer_key = 'applet_host_prefer_{}'.format(user.id)
|
||||||
prefer_host_id = cache.get(prefer_key, None)
|
prefer_host_id = cache.get(prefer_key, None)
|
||||||
pref_host = [host for host in hosts if host.id == prefer_host_id]
|
pref_host = [host for host in hosts if host.id == prefer_host_id]
|
||||||
|
@ -213,22 +214,26 @@ class Applet(JMSBaseModel):
|
||||||
|
|
||||||
private_account = valid_accounts.filter(username='js_{}'.format(user.username)).first()
|
private_account = valid_accounts.filter(username='js_{}'.format(user.username)).first()
|
||||||
if not private_account:
|
if not private_account:
|
||||||
|
logger.debug('Private account not found ...')
|
||||||
return None
|
return None
|
||||||
# 优先使用 private account,支持并发或者不支持并发时,如果私有没有被占用,则使用私有
|
# 优先使用 private account,支持并发或者不支持并发时,如果私有没有被占用,则使用私有
|
||||||
account = None
|
account = None
|
||||||
# 如果都支持,不管私有是否被占用,都使用私有
|
# 如果都支持,不管私有是否被占用,都使用私有
|
||||||
if all_can_concurrent:
|
if all_can_concurrent:
|
||||||
|
logger.debug('All can concurrent, use private account')
|
||||||
account = private_account
|
account = private_account
|
||||||
# 如果主机都不支持并发,则查询一下私有账号有没有任何应用使用,如果没有被使用,则使用私有
|
# 如果主机都不支持并发,则查询一下私有账号有没有任何应用使用,如果没有被使用,则使用私有
|
||||||
elif not host_can_concurrent:
|
elif not host_can_concurrent:
|
||||||
private_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, '*')
|
private_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, '*')
|
||||||
private_is_using = len(cache.keys(private_using_key, [])) > 0
|
private_is_using = len(cache.keys(private_using_key))
|
||||||
|
logger.debug("Private account is using: {}".format(private_is_using))
|
||||||
if not private_is_using:
|
if not private_is_using:
|
||||||
account = private_account
|
account = private_account
|
||||||
# 如果主机支持,但是应用不支持并发,则查询一下私有账号有没有被这个应用使用, 如果没有被使用,则使用私有
|
# 如果主机支持,但是应用不支持并发,则查询一下私有账号有没有被这个应用使用, 如果没有被使用,则使用私有
|
||||||
elif host_can_concurrent and not app_can_concurrent:
|
elif host_can_concurrent and not app_can_concurrent:
|
||||||
private_app_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, self.name)
|
private_app_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, self.name)
|
||||||
private_is_using_by_this_app = cache.get(private_app_using_key, False)
|
private_is_using_by_this_app = cache.get(private_app_using_key, False)
|
||||||
|
logger.debug("Private account is using {} by {}".format(private_is_using_by_this_app, self.name))
|
||||||
if not private_is_using_by_this_app:
|
if not private_is_using_by_this_app:
|
||||||
account = private_account
|
account = private_account
|
||||||
return account
|
return account
|
||||||
|
@ -236,24 +241,32 @@ class Applet(JMSBaseModel):
|
||||||
def select_host_account(self, user, asset):
|
def select_host_account(self, user, asset):
|
||||||
# 选择激活的发布机
|
# 选择激活的发布机
|
||||||
host = self.select_host(user, asset)
|
host = self.select_host(user, asset)
|
||||||
|
logger.info('Select applet host: {}'.format(host.name))
|
||||||
if not host:
|
if not host:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
valid_accounts = host.accounts.all().filter(is_active=True, privileged=False)
|
valid_accounts = host.accounts.all().filter(is_active=True, privileged=False)
|
||||||
account = self.try_to_use_private_account(user, host, valid_accounts)
|
account = self.try_to_use_private_account(user, host, valid_accounts)
|
||||||
if not account:
|
if not account:
|
||||||
|
logger.debug('No private account, try to use public account')
|
||||||
account = self.select_a_public_account(user, host, valid_accounts)
|
account = self.select_a_public_account(user, host, valid_accounts)
|
||||||
|
|
||||||
|
if not account:
|
||||||
|
logger.debug('No available account for applet host: {}'.format(host.name))
|
||||||
|
return None
|
||||||
|
|
||||||
ttl = 60 * 60 * 24
|
ttl = 60 * 60 * 24
|
||||||
lock_key = self.accounts_using_key_tmpl.format(host.id, account.username, self.name)
|
lock_key = self.accounts_using_key_tmpl.format(host.id, account.username, self.name)
|
||||||
cache.set(lock_key, account.username, ttl)
|
cache.set(lock_key, account.username, ttl)
|
||||||
|
|
||||||
return {
|
res = {
|
||||||
'host': host,
|
'host': host,
|
||||||
'account': account,
|
'account': account,
|
||||||
'lock_key': lock_key,
|
'lock_key': lock_key,
|
||||||
'ttl': ttl
|
'ttl': ttl
|
||||||
}
|
}
|
||||||
|
logger.debug('Select host and account: {}'.format(res))
|
||||||
|
return res
|
||||||
|
|
||||||
def delete(self, using=None, keep_parents=False):
|
def delete(self, using=None, keep_parents=False):
|
||||||
platform = self.get_related_platform()
|
platform = self.get_related_platform()
|
||||||
|
|
Loading…
Reference in New Issue