wangwei01 e6c845004a 1
2019-07-30 20:39:52 +08:00

265 lines
8.9 KiB
Python

# -*- coding: utf-8 -*-
#!/usr/bin/python
import pymysql
import hashlib
import json
import urllib.request
import base64
import tornado.ioloop
import tornado.web
import time
import datetime
import redis
import os
CONFIG_DIR = ''
def IsOnlineEnv():
return os.getenv("SERVER_ENV");
if (IsOnlineEnv()):
CONFIG_DIR = '/var/data/conf_test/game2001api_rankserver/config'
else:
CONFIG_DIR = '../config'
def info(msg):
print(str(datetime.datetime.now()) + '[INFO] ' + msg)
def take_kills(elem):
return elem[3]
def take_alive_time(elem):
return elem[4]
def take_harms(elem):
return elem[5]
def take_win_times(elem):
return elem[6]
def take_game_times(elem):
return elem[7]
def safeDiv(a, b):
if b == 0:
return 0
else:
return a / b
def getRedis():
redis_conf = json.loadsmysql_conf = json.loads(open(CONFIG_DIR + '/rankserver.redis.cluster.json', 'r').read())
for conf in redis_conf:
r = redis.Redis(host = conf['host'],
port = conf['port'],
password = conf['passwd'],
charset = 'utf8'
)
return r;
def getDaySeconds(time_val, incdays):
time_zone = 8
dayseconds = int((time_val + time_zone * 3600)/3600/24 + incdays) * 3600 * 24 - 3600 * time_zone;
return dayseconds
#刷新数据
def refreshData(row, kill_list, alive_list, harm_list, rate_list, win_list):
kill = safeDiv(row[3], row[7])
alive_time = safeDiv(row[4], row[7])
harm = safeDiv(row[5], row[7])
win_times = safeDiv(row[6], row[7])
kill_list.append((row[0], row[1].decode('utf-8'), row[2], kill, alive_time, harm, win_times, row[6]))
kill_list.sort(key=take_kills, reverse=True)
if (len(kill_list) > 50):
del kill_list[50:]
alive_list.append((row[0], row[1].decode('utf-8'), row[2], kill, alive_time, harm, win_times, row[6]))
alive_list.sort(key=take_alive_time, reverse=True)
if (len(alive_list) > 50):
del alive_list[50:]
harm_list.append((row[0], row[1].decode('utf-8'), row[2], kill, alive_time, harm, win_times, row[6]))
harm_list.sort(key=take_harms, reverse=True)
if (len(harm_list) > 50):
del harm_list[50:]
rate_list.append((row[0], row[1].decode('utf-8'), row[2], kill, alive_time, harm, win_times, row[6]))
rate_list.sort(key=take_win_times, reverse=True)
if (len(rate_list) > 50):
del rate_list[50:]
win_list.append((row[0], row[1].decode('utf-8'), row[2], kill, alive_time, harm, win_times, row[6]))
win_list.sort(key=take_game_times, reverse=True)
if (len(win_list) > 50):
del win_list[50:]
#更新排行榜
def updateRank(r, kill_list, alive_list, harm_list, rate_list, win_list):
kill_list.sort(key=take_kills, reverse=True)
kill_rank = []
for kill_index in range(min(50, len(kill_list))):
kill_rank.append(kill_list[kill_index])
r.set("game2001api: kill_rank", json.dumps(kill_rank))
alive_list.sort(key=take_alive_time, reverse=True)
alive_rank = []
for alive_index in range(min(50, len(alive_list))):
alive_rank.append(alive_list[alive_index])
r.set("game2001api: alive_rank", json.dumps(alive_rank))
harm_list.sort(key=take_harms, reverse=True)
harm_rank = []
for harm_index in range(min(50, len(harm_list))):
harm_rank.append(harm_list[harm_index])
r.set("game2001api: harm_rank", json.dumps(harm_rank))
rate_list.sort(key=take_win_times, reverse=True)
rate_rank = []
for rate_index in range(min(50, len(rate_list))):
rate_rank.append(rate_list[rate_index])
r.set("game2001api: rate_rank", json.dumps(rate_rank))
win_list.sort(key=take_game_times, reverse=True)
win_rank = []
for win_index in range(min(50, len(win_list))):
win_rank.append(win_list[win_index])
r.set("game2001api: win_rank", json.dumps(win_rank))
#每日定时读取mysql里的数据生成排行榜写入redis后php读取redis返回客户端显示
def dayReadMysqlData(rushtime):
mysql_conf = json.loads(open(CONFIG_DIR + '/rankserver.mysql.cluster.json', 'r').read())
kill_list = []
alive_list = []
harm_list = []
rate_list = []
win_list = []
for conf in mysql_conf:
conn = pymysql.connect(host = conf['host'],
port = conf['port'],
user = conf['user'],
passwd = conf['passwd'],
db = 'gamedb2001_' + str(conf['instance_id']),
charset = 'utf8'
)
cursor = conn.cursor()
last_idx = 0
temp_idx = 0
while 1:
cursor.execute('SELECT accountid, user_name, avatar_url, kills, alive_time,'
' harm, win_times, game_times, idx FROM user WHERE idx > %s LIMIT 0, 1000' % (last_idx))
has_data = False
print(kill_list)
for row in cursor:
refreshData(row, kill_list, alive_list, harm_list, rate_list, win_list)
temp_idx = int(row[8])
if (temp_idx > last_idx) :
last_idx = int(row[8])
if not has_data:
break
r = getRedis()
updateRank(r, kill_list, alive_list, harm_list, rate_list, win_list)
tornado.ioloop.IOLoop.current().call_later(getDaySeconds(time.time(), 1) + rushtime,
lambda : dayReadMysqlData(rushtime)
)
#每5分钟读取mysql里发生改变过的数据更新排行榜
def readMysqlData(rushtime):
mysql_conf = json.loads(open(CONFIG_DIR + '/rankserver.mysql.cluster.json', 'r').read())
r = getRedis()
kill_list_str = r.get("game2001api: kill_rank")
if (not kill_list_str):
kill_list = []
else:
kill_list = json.loads(kill_list_str)
alive_list_str = r.get("game2001api: alive_rank")
if (not alive_list_str):
alive_list = []
else:
alive_list = json.loads(alive_list_str)
harm_list_str = r.get("game2001api: harm_rank")
if (not harm_list_str):
harm_list = []
else:
harm_list = json.loads(harm_list_str)
rate_list_str = r.get("game2001api: rate_rank")
if (not rate_list_str):
rate_list = []
else:
rate_list = json.loads(rate_list_str)
win_list_str = r.get("game2001api: win_rank")
if (not win_list_str):
win_list = []
else:
win_list = json.loads(win_list_str)
for conf in mysql_conf:
conn = pymysql.connect(host = conf['host'],
port = conf['port'],
user = conf['user'],
passwd = conf['passwd'],
db = 'gamedb2001_' + str(conf['instance_id']),
charset = 'utf8'
)
cursor = conn.cursor()
last_idx = 0
temp_idx = 0
flag = 0
while 1:
cursor.execute('SELECT accountid, user_name, avatar_url, kills, alive_time,'
' harm, win_times, game_times, idx, modify_time FROM user '
' WHERE modify_time > %s AND idx > %s LIMIT 0, 1000' % (time.time() - 300, last_idx))
has_data = False
print(3333333)
print(kill_list)
for row in cursor:
for rowKill in kill_list:
if (rowKill[0] == row[0]):
flag = 1
break
if (flag != 1):
refreshData(row, kill_list, alive_list, harm_list, rate_list, win_list)
temp_idx = int(row[8])
if (temp_idx > last_idx) :
last_idx = int(row[8])
if not has_data:
break
updateRank(r, kill_list, alive_list, harm_list, rate_list, win_list)
tornado.ioloop.IOLoop.current().call_later(rushtime,
lambda : readMysqlData(rushtime)
)
class SelfCheckingHandler(tornado.web.RequestHandler):
def get(self):
self.write(json.dumps({
'errcode': 0,
'errmsg': '',
'healthy': 1,
'max_rundelay': 10
}))
def make_app():
return tornado.web.Application([
(r"/webapp/index[\.]php", SelfCheckingHandler),
])
if __name__ == "__main__":
conf = json.loads(open(CONFIG_DIR + '/rankserver.json', 'r').read())
app = make_app()
app.listen(conf['listen_port'])
conf['rushtime'] = 300
tornado.ioloop.IOLoop.current().call_later(conf['rushtime'],
lambda : readMysqlData(conf['rushtime'])
)
conf['rushtime'] = 3600 * 17
tornado.ioloop.IOLoop.current().call_later(getDaySeconds(time.time(), 1) + conf['rushtime'],
lambda : dayReadMysqlData(conf['rushtime'])
)
tornado.ioloop.IOLoop.current().start()