|
@ -6,24 +6,17 @@ import time |
|
|
import sys |
|
|
import sys |
|
|
from server_pool import ServerPool |
|
|
from server_pool import ServerPool |
|
|
import traceback |
|
|
import traceback |
|
|
from shadowsocks import common |
|
|
from shadowsocks import common, shell |
|
|
from configloader import load_config, get_config |
|
|
from configloader import load_config, get_config |
|
|
|
|
|
|
|
|
class DbTransfer(object): |
|
|
db_instance = None |
|
|
|
|
|
|
|
|
instance = None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DbTransfer(object): |
|
|
def __init__(self): |
|
|
def __init__(self): |
|
|
import threading |
|
|
import threading |
|
|
self.last_get_transfer = {} |
|
|
self.last_get_transfer = {} |
|
|
self.event = threading.Event() |
|
|
self.event = threading.Event() |
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
|
def get_instance(): |
|
|
|
|
|
if DbTransfer.instance is None: |
|
|
|
|
|
DbTransfer.instance = DbTransfer() |
|
|
|
|
|
return DbTransfer.instance |
|
|
|
|
|
|
|
|
|
|
|
def update_all_user(self, dt_transfer): |
|
|
def update_all_user(self, dt_transfer): |
|
|
import cymysql |
|
|
import cymysql |
|
|
query_head = 'UPDATE user' |
|
|
query_head = 'UPDATE user' |
|
@ -83,8 +76,7 @@ class DbTransfer(object): |
|
|
self.update_all_user(dt_transfer) |
|
|
self.update_all_user(dt_transfer) |
|
|
self.last_get_transfer = curr_transfer |
|
|
self.last_get_transfer = curr_transfer |
|
|
|
|
|
|
|
|
@staticmethod |
|
|
def pull_db_all_user(self): |
|
|
def pull_db_all_user(): |
|
|
|
|
|
import cymysql |
|
|
import cymysql |
|
|
#数据库所有用户信息 |
|
|
#数据库所有用户信息 |
|
|
try: |
|
|
try: |
|
@ -107,8 +99,7 @@ class DbTransfer(object): |
|
|
conn.close() |
|
|
conn.close() |
|
|
return rows |
|
|
return rows |
|
|
|
|
|
|
|
|
@staticmethod |
|
|
def del_server_out_of_bound_safe(self, last_rows, rows): |
|
|
def del_server_out_of_bound_safe(last_rows, rows): |
|
|
|
|
|
#停止超流量的服务 |
|
|
#停止超流量的服务 |
|
|
#启动没超流量的服务 |
|
|
#启动没超流量的服务 |
|
|
#需要动态载入switchrule,以便实时修改规则 |
|
|
#需要动态载入switchrule,以便实时修改规则 |
|
@ -180,7 +171,7 @@ class DbTransfer(object): |
|
|
|
|
|
|
|
|
if len(new_servers) > 0: |
|
|
if len(new_servers) > 0: |
|
|
from shadowsocks import eventloop |
|
|
from shadowsocks import eventloop |
|
|
DbTransfer.get_instance().event.wait(eventloop.TIMEOUT_PRECISION) |
|
|
self.event.wait(eventloop.TIMEOUT_PRECISION) |
|
|
for port in new_servers.keys(): |
|
|
for port in new_servers.keys(): |
|
|
passwd, cfg = new_servers[port] |
|
|
passwd, cfg = new_servers[port] |
|
|
logging.info('db start server at port [%s] pass [%s]' % (port, passwd)) |
|
|
logging.info('db start server at port [%s] pass [%s]' % (port, passwd)) |
|
@ -196,32 +187,68 @@ class DbTransfer(object): |
|
|
ServerPool.get_instance().cb_del_server(port) |
|
|
ServerPool.get_instance().cb_del_server(port) |
|
|
|
|
|
|
|
|
@staticmethod |
|
|
@staticmethod |
|
|
def thread_db(): |
|
|
def thread_db(obj): |
|
|
import socket |
|
|
import socket |
|
|
import time |
|
|
import time |
|
|
|
|
|
global db_instance |
|
|
timeout = 60 |
|
|
timeout = 60 |
|
|
socket.setdefaulttimeout(timeout) |
|
|
socket.setdefaulttimeout(timeout) |
|
|
last_rows = [] |
|
|
last_rows = [] |
|
|
|
|
|
db_instance = obj() |
|
|
try: |
|
|
try: |
|
|
while True: |
|
|
while True: |
|
|
load_config() |
|
|
load_config() |
|
|
try: |
|
|
try: |
|
|
DbTransfer.get_instance().push_db_all_user() |
|
|
db_instance.push_db_all_user() |
|
|
rows = DbTransfer.get_instance().pull_db_all_user() |
|
|
rows = db_instance.pull_db_all_user() |
|
|
DbTransfer.del_server_out_of_bound_safe(last_rows, rows) |
|
|
db_instance.del_server_out_of_bound_safe(last_rows, rows) |
|
|
last_rows = rows |
|
|
last_rows = rows |
|
|
except Exception as e: |
|
|
except Exception as e: |
|
|
trace = traceback.format_exc() |
|
|
trace = traceback.format_exc() |
|
|
logging.error(trace) |
|
|
logging.error(trace) |
|
|
#logging.warn('db thread except:%s' % e) |
|
|
#logging.warn('db thread except:%s' % e) |
|
|
if DbTransfer.get_instance().event.wait(get_config().MYSQL_UPDATE_TIME) or not ServerPool.get_instance().thread.is_alive(): |
|
|
if db_instance.event.wait(get_config().MYSQL_UPDATE_TIME) or not ServerPool.get_instance().thread.is_alive(): |
|
|
break |
|
|
break |
|
|
except KeyboardInterrupt as e: |
|
|
except KeyboardInterrupt as e: |
|
|
pass |
|
|
pass |
|
|
DbTransfer.del_servers() |
|
|
db_instance.del_servers() |
|
|
ServerPool.get_instance().stop() |
|
|
ServerPool.get_instance().stop() |
|
|
|
|
|
db_instance = None |
|
|
|
|
|
|
|
|
@staticmethod |
|
|
@staticmethod |
|
|
def thread_db_stop(): |
|
|
def thread_db_stop(): |
|
|
DbTransfer.get_instance().event.set() |
|
|
global db_instance |
|
|
|
|
|
db_instance.event.set() |
|
|
|
|
|
|
|
|
|
|
|
class MuJsonTransfer(DbTransfer): |
|
|
|
|
|
def __init__(self): |
|
|
|
|
|
super(MuJsonTransfer, self).__init__() |
|
|
|
|
|
|
|
|
|
|
|
def update_all_user(self, dt_transfer): |
|
|
|
|
|
import json |
|
|
|
|
|
rows = None |
|
|
|
|
|
|
|
|
|
|
|
config_path = "mudb.json" |
|
|
|
|
|
with open(config_path, 'r+') as f: |
|
|
|
|
|
rows = shell.parse_json_in_str(f.read().decode('utf8')) |
|
|
|
|
|
for row in rows: |
|
|
|
|
|
if "port" in row: |
|
|
|
|
|
port = row["port"] |
|
|
|
|
|
if port in dt_transfer: |
|
|
|
|
|
row["u"] += dt_transfer[port][0] |
|
|
|
|
|
row["d"] += dt_transfer[port][1] |
|
|
|
|
|
|
|
|
|
|
|
if rows: |
|
|
|
|
|
output = json.dumps(rows, sort_keys=True, indent=4, separators=(',', ': ')) |
|
|
|
|
|
with open(config_path, 'w') as f: |
|
|
|
|
|
f.write(output) |
|
|
|
|
|
|
|
|
|
|
|
def pull_db_all_user(self): |
|
|
|
|
|
rows = None |
|
|
|
|
|
|
|
|
|
|
|
config_path = "mudb.json" |
|
|
|
|
|
with open(config_path, 'r+') as f: |
|
|
|
|
|
rows = shell.parse_json_in_str(f.read().decode('utf8')) |
|
|
|
|
|
|
|
|
|
|
|
return rows |
|
|
|
|
|
|
|
|