database.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import traceback
  4. import mysql.connector
  5. import mysql.connector.pooling
  6. import redis
  7. from mysql.connector import errorcode
  8. import time
  9. import jimit as ji
  10. from initialize import app, logger
  11. __author__ = 'James Iter'
  12. __date__ = '16/6/8'
  13. __contact__ = 'james.iter.cn@gmail.com'
  14. __copyright__ = '(c) 2016 by James Iter.'
  15. class Database(object):
  16. cnxpool = None
  17. r = None
  18. def __init__(self):
  19. pass
  20. @classmethod
  21. def init_conn_mysql(cls):
  22. try:
  23. cls.cnxpool = mysql.connector.pooling.MySQLConnectionPool(
  24. host=app.config["db_host"],
  25. user=app.config["db_user"],
  26. password=app.config["db_password"],
  27. port=app.config["db_port"],
  28. database=app.config["db_name"],
  29. raise_on_warnings=app.config["DEBUG"],
  30. pool_size=app.config["db_pool_size"],
  31. charset=app.config["db_charset"]
  32. )
  33. except mysql.connector.Error as err:
  34. if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
  35. e_msg = u'用户名或密码错误'
  36. elif err.errno == errorcode.ER_BAD_DB_ERROR:
  37. e_msg = u'数据库不存在'
  38. else:
  39. e_msg = err.msg
  40. print(e_msg)
  41. exit(err.errno)
  42. @classmethod
  43. def keepalived_mysql(cls):
  44. def ping(label='', _cnxpool=None):
  45. if _cnxpool is None:
  46. logger.critical(''.join(['cnxpool must not None by ', label]))
  47. return
  48. try:
  49. _cnx = _cnxpool.get_connection()
  50. _cnx.ping(attempts=1, delay=0)
  51. except mysql.connector.errors.InterfaceError as err:
  52. logger.critical(err.msg)
  53. except mysql.connector.Error as err:
  54. logger.error(err)
  55. else:
  56. _cnx.close()
  57. while True:
  58. try:
  59. time.sleep(5)
  60. ping(label='', _cnxpool=cls.cnxpool)
  61. except:
  62. logger.error(traceback.format_exc())
  63. @classmethod
  64. def init_conn_redis(cls):
  65. """
  66. * Added TCP Keep-alive support by passing use the socket_keepalive=True
  67. option. Finer grain control can be achieved using the
  68. socket_keepalive_options option which expects a dictionary with any of
  69. the keys (socket.TCP_KEEPIDLE, socket.TCP_KEEPCNT, socket.TCP_KEEPINTVL)
  70. and integers for values. Thanks Yossi Gottlieb.
  71. TCP_KEEPDILE 设置连接上如果没有数据发送的话,多久后发送keepalive探测分组,单位是秒
  72. TCP_KEEPINTVL 前后两次探测之间的时间间隔,单位是秒
  73. TCP_KEEPCNT 关闭一个非活跃连接之前的最大重试次数
  74. """
  75. import socket
  76. cls.r = redis.StrictRedis(host=app.config.get('redis_host', '127.0.0.1'),
  77. port=app.config.get('redis_port', 6379),
  78. db=app.config.get('redis_dbid', 0), decode_responses=True, socket_timeout=5,
  79. socket_connect_timeout=5, socket_keepalive=True,
  80. socket_keepalive_options={socket.TCP_KEEPIDLE: 2, socket.TCP_KEEPINTVL: 5,
  81. socket.TCP_KEEPCNT: 10},
  82. retry_on_timeout=True)
  83. try:
  84. cls.r.ping()
  85. except redis.exceptions.ResponseError as e:
  86. logger.warn(e.message)
  87. cls.r = redis.StrictRedis(host=app.config.get('redis_host', '127.0.0.1'),
  88. port=app.config.get('redis_port', 6379),
  89. db=app.config.get('redis_dbid', 0), password=app.config.get('redis_password', ''),
  90. decode_responses=True, socket_timeout=5,
  91. socket_connect_timeout=5, socket_keepalive=True,
  92. socket_keepalive_options={socket.TCP_KEEPIDLE: 2, socket.TCP_KEEPINTVL: 5,
  93. socket.TCP_KEEPCNT: 10},
  94. retry_on_timeout=True)
  95. cls.r.client_setname(ji.Common.get_hostname())
  96. @classmethod
  97. def keepalived_redis(cls):
  98. while True:
  99. try:
  100. time.sleep(5)
  101. cls.r.ping()
  102. except redis.exceptions.ConnectionError as e:
  103. logger.error(e.message)
  104. cls.init_conn_redis()
  105. except:
  106. logger.error(traceback.format_exc())