Răsfoiți Sursa

倒序依次挨个分配虚拟机的创建任务

James Iter 9 ani în urmă
părinte
comite
3843d8c4cc
8 a modificat fișierele cu 83 adăugiri și 26 ștergeri
  1. 11 2
      api/guest.py
  2. 6 21
      api/host.py
  3. 1 1
      docs/todo.md
  4. 5 1
      models/__init__.py
  5. 22 0
      models/guest.py
  6. 33 0
      models/host.py
  7. 4 0
      state_code.py
  8. 1 1
      static/themes/components/border-radius.css

+ 11 - 2
api/guest.py

@@ -88,6 +88,12 @@ def r_create():
             ret['state'] = ji.Common.exchange_state(50350)
             return ret
 
+        available_hosts = Guest.get_available_hosts()
+
+        if available_hosts.__len__() == 0:
+            ret['state'] = ji.Common.exchange_state(50351)
+            return ret
+
         quantity = request.json.get('quantity')
 
         while quantity:
@@ -118,7 +124,7 @@ def r_create():
 
             disk = Disk()
             disk.uuid = guest.uuid
-            disk.remark = guest.label + '_SystemImage'
+            disk.remark = guest.label.__str__() + '_SystemImage'
             disk.format = 'qcow2'
             disk.sequence = 0
             disk.size = 0
@@ -149,13 +155,16 @@ def r_create():
                     replace('{DNS1}', config.dns1). \
                     replace('{DNS2}', config.dns2)
 
+            # 在可用计算节点中平均分配任务
+            chosen_host = available_hosts[quantity % available_hosts.__len__()]
+
             message = {
                 '_object': 'guest',
                 'action': 'create',
                 'uuid': guest.uuid,
                 'storage_mode': config.storage_mode,
                 'dfs_volume': config.dfs_volume,
-                'hostname': Guest.get_lightest_host()['hostname'],
+                'hostname': chosen_host['hostname'],
                 'name': guest.label,
                 'template_path': os_template.path,
                 'disk': disk.__dict__,

+ 6 - 21
api/host.py

@@ -3,11 +3,11 @@
 
 
 import json
-from flask import Blueprint, request, g
+from flask import Blueprint, request
 import jimit as ji
 
 from models import Database as db
-from models import Utils, Rules
+from models import Utils, Rules, Host
 from models.initialize import app
 
 
@@ -30,21 +30,6 @@ blueprints = Blueprint(
 )
 
 
-def alive_check(v):
-    """
-    JimV-C 2 秒更新一次宿主机信息,这里以 5 秒内没收到更新,作为判断宿主机是否在线的标准
-    """
-
-    if 'timestamp' not in v:
-        return v
-
-    v['alive'] = False
-    if v['timestamp'] + 5 >= g.ts:
-        v['alive'] = True
-
-    return v
-
-
 @Utils.dumps2response
 def r_get(nodes_id):
 
@@ -63,7 +48,7 @@ def r_get(nodes_id):
             node_id = nodes_id
             if db.r.hexists(app.config['hosts_info'], node_id):
                 v = json.loads(db.r.hget(app.config['hosts_info'], node_id))
-                v = alive_check(v)
+                v = Host.alive_check(v)
                 v['node_id'] = node_id
                 ret['data'] = v
 
@@ -71,7 +56,7 @@ def r_get(nodes_id):
             for node_id in nodes_id.split(','):
                 if db.r.hexists(app.config['hosts_info'], node_id):
                     v = json.loads(db.r.hget(app.config['hosts_info'], node_id))
-                    v = alive_check(v)
+                    v = Host.alive_check(v)
                     v['node_id'] = node_id
                     ret['data'].append(v)
 
@@ -90,7 +75,7 @@ def r_get_by_filter():
         ret['data'] = list()
         for k, v in db.r.hgetall(app.config['hosts_info']).items():
             v = json.loads(v)
-            v = alive_check(v)
+            v = Host.alive_check(v)
             v['node_id'] = k
             ret['data'].append(v)
 
@@ -118,7 +103,7 @@ def r_content_search():
         for k, v in db.r.hgetall(app.config['hosts_info']).items():
             v = json.loads(v)
             if -1 != v['hostname'].find(keyword):
-                v = alive_check(v)
+                v = Host.alive_check(v)
                 v['node_id'] = k
                 ret['data'].append(v)
 

+ 1 - 1
docs/todo.md

@@ -35,7 +35,7 @@
 - [ ] 虚拟机状态变化时时展现在前端页面上
 - [ ] 迁移时计算出剩余时间
 - [x] 重新设计 JimV-N 到 JimV-C 的回调机制,现有实现比较混乱。改进为基于对象的回调
-- [ ] 重新设计创建虚拟机机制,批量创建虚拟机时,依照宿主机负载大小,倒序依次挨个分配虚拟机的创建任务,并且在计算节点上,创建虚拟机的任务单独开辟独立的线程
+- [x] 重新设计创建虚拟机机制,批量创建虚拟机时,依照宿主机负载大小,倒序依次挨个分配虚拟机的创建任务
 - [x] 规范日志路径。把日志路径调整至 /var/log/ 下
 - [ ] 去除15天前的监控日志
 - [ ] 初始化页面检测redis、mysql是否准备好

+ 5 - 1
models/__init__.py

@@ -69,6 +69,10 @@ from performance import (
     DiskIO
 )
 
+from host import (
+    Host
+)
+
 from host_performance import (
     HostCPUMemory,
     HostTraffic,
@@ -90,7 +94,7 @@ __all__ = [
     'Rules', 'Utils', 'Init', 'Database', 'FilterFieldType', 'Filter', 'EmitKind', 'GuestState', 'DiskState',
     'LogLevel', 'ORM', 'User', 'Config', 'Guest', 'Disk', 'BootJob', 'OperateRule', 'OSTemplate', 'GuestXML', 'Log',
     'EventProcessor', 'ResponseState', 'CPUMemory', 'Traffic', 'DiskIO', 'HostCPUMemory', 'HostTraffic',
-    'HostDiskUsageIO'
+    'HostDiskUsageIO', 'Host'
 ]
 
 

+ 22 - 0
models/guest.py

@@ -116,6 +116,28 @@ class Guest(ORM):
 
         return lightest_host
 
+    @staticmethod
+    def get_available_hosts():
+
+        from models import Host
+
+        hosts = list()
+
+        for k, v in db.r.hgetall(app.config['hosts_info']).items():
+            v = json.loads(v)
+
+            v = Host.alive_check(v)
+
+            if not v['alive']:
+                continue
+
+            v['system_load_per_cpu'] = float(v['system_load'][0]) / v['cpu']
+            hosts.append(v)
+
+        hosts.sort(key=lambda _k: _k['system_load_per_cpu'])
+
+        return hosts
+
 
 class Disk(ORM):
 

+ 33 - 0
models/host.py

@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+from flask import g
+
+
+__author__ = 'James Iter'
+__date__ = '2017/9/19'
+__contact__ = 'james.iter.cn@gmail.com'
+__copyright__ = '(c) 2017 by James Iter.'
+
+
+class Host(object):
+
+    def __init__(self):
+        pass
+
+    @staticmethod
+    def alive_check(v):
+        """
+        JimV-C 2 秒更新一次宿主机信息,这里以 5 秒内没收到更新,作为判断宿主机是否在线的标准
+        """
+
+        if 'timestamp' not in v:
+            return v
+
+        v['alive'] = False
+        if v['timestamp'] + 5 >= g.ts:
+            v['alive'] = True
+
+        return v
+

+ 4 - 0
state_code.py

@@ -69,4 +69,8 @@ own_state_branch = {
         'code': '50350',
         'zh-cn': u'无可用IP地址,请联系 JimV 管理员'
     },
+    '50351': {
+        'code': '50351',
+        'zh-cn': u'无可用计算节点,请联系 JimV 管理员'
+    },
 }

+ 1 - 1
static/themes/components/border-radius.css

@@ -91,7 +91,7 @@ div[id^='uniform-'] span,
 .dropdown-submenu.float-left > .dropdown-menu,
 .nav-list,
 .nav-list-horizontal-alt li a {
-    border-radius: 3px;
+    border-radius: 0;
 }
 .ui-datepicker-title,
 .panel > .list-group:first-child .list-group-item:first-child,