host.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import json
  4. import jimit as ji
  5. from jimvc.models import app_config
  6. from jimvc.models import Database as db
  7. __author__ = 'James Iter'
  8. __date__ = '2017/9/19'
  9. __contact__ = 'james.iter.cn@gmail.com'
  10. __copyright__ = '(c) 2017 by James Iter.'
  11. class Host(object):
  12. def __init__(self):
  13. pass
  14. @staticmethod
  15. def alive_check(v):
  16. """
  17. 60 秒内没收到更新,作为判断 [计算节点] 是否在线的标准。包含了 [计算节点] 与 [控制节点] 间的时间差。
  18. """
  19. coupler_length = 60
  20. ts = ji.Common.ts()
  21. if 'timestamp' not in v:
  22. return v
  23. v['alive'] = False
  24. if v['timestamp'] + coupler_length >= ts:
  25. v['alive'] = True
  26. if 'threads_status' not in v:
  27. v['threads_status'] = {
  28. 'instruction_process_engine': {
  29. 'timestamp': 0
  30. },
  31. 'host_state_report_engine': {
  32. 'timestamp': 0
  33. },
  34. 'guest_creating_progress_report_engine': {
  35. 'timestamp': 0
  36. },
  37. 'guest_performance_collection_engine': {
  38. 'timestamp': 0
  39. },
  40. 'host_performance_collection_engine': {
  41. 'timestamp': 0
  42. }
  43. }
  44. v['threads_status']['instruction_process_engine']['alive'] = False
  45. if v['threads_status']['instruction_process_engine']['timestamp'] + coupler_length >= ts:
  46. v['threads_status']['instruction_process_engine']['alive'] = True
  47. v['threads_status']['host_state_report_engine']['alive'] = False
  48. if v['threads_status']['host_state_report_engine']['timestamp'] + coupler_length >= ts:
  49. v['threads_status']['host_state_report_engine']['alive'] = True
  50. v['threads_status']['guest_creating_progress_report_engine']['alive'] = False
  51. if v['threads_status']['guest_creating_progress_report_engine']['timestamp'] + coupler_length >= ts:
  52. v['threads_status']['guest_creating_progress_report_engine']['alive'] = True
  53. v['threads_status']['guest_performance_collection_engine']['alive'] = False
  54. if v['threads_status']['guest_performance_collection_engine']['timestamp'] + coupler_length >= ts:
  55. v['threads_status']['guest_performance_collection_engine']['alive'] = True
  56. v['threads_status']['host_performance_collection_engine']['alive'] = False
  57. if v['threads_status']['host_performance_collection_engine']['timestamp'] + coupler_length >= ts:
  58. v['threads_status']['host_performance_collection_engine']['alive'] = True
  59. return v
  60. @staticmethod
  61. def set_allocation_mode(hosts_name=None, random=True):
  62. if not isinstance(hosts_name, list):
  63. raise ValueError('The hosts_name must be a list.')
  64. if random:
  65. db.r.sadd(app_config['compute_nodes_of_allocation_by_nonrandom'], *hosts_name)
  66. else:
  67. db.r.srem(app_config['compute_nodes_of_allocation_by_nonrandom'], *hosts_name)
  68. @classmethod
  69. def get_all(cls):
  70. ret = list()
  71. compute_nodes_of_allocation_by_nonrandom = \
  72. list(db.r.smembers(app_config['compute_nodes_of_allocation_by_nonrandom']))
  73. for k, v in db.r.hgetall(app_config['hosts_info']).items():
  74. v = json.loads(v)
  75. v = cls.alive_check(v)
  76. v['node_id'] = k
  77. if v['hostname'] in compute_nodes_of_allocation_by_nonrandom:
  78. v['nonrandom'] = True
  79. else:
  80. v['nonrandom'] = False
  81. ret.append(v)
  82. if ret.__len__() > 1:
  83. ret.sort(key=lambda _k: _k['boot_time'])
  84. return ret
  85. @classmethod
  86. def get_available_hosts(cls, nonrandom=None):
  87. """
  88. :param nonrandom: {None, True, False}
  89. None for all;
  90. False for host can be allocation guest by random;
  91. True on the contrary.
  92. :return:
  93. """
  94. hosts = list()
  95. for host in cls.get_all():
  96. if not host['alive']:
  97. continue
  98. if nonrandom is not None and host['nonrandom'] != nonrandom:
  99. continue
  100. host['system_load_per_cpu'] = float(host['system_load'][0]) / host['cpu']
  101. hosts.append(host)
  102. hosts.sort(key=lambda _k: _k['system_load_per_cpu'])
  103. return hosts
  104. @staticmethod
  105. def get_lightest_host():
  106. # 负载最小的宿主机
  107. lightest_host = None
  108. for k, v in db.r.hgetall(app_config['hosts_info']).items():
  109. v = json.loads(v)
  110. if lightest_host is None:
  111. lightest_host = v
  112. if float(lightest_host['system_load'][0]) / lightest_host['cpu'] > \
  113. float(v['system_load'][0]) / v['cpu']:
  114. lightest_host = v
  115. return lightest_host