访问量: 51 次浏览
OSGeo中国中心网站自全面使用Django作为后台程序后,运行还算稳定,在去年年底针对DDOS攻击也进行专门的问题查找与处理,访问体验改善了许多。
但是在近期网站访问又出现了问题,主要表现形式就是打开页面缓慢,甚至无法打开。从服务器角度来看,发现CPU占用过高,包括 uwsgi 与 postgres 的进程。其中 uwsgi 主要运行 Django 程序,可以理解;但是 postgres 过高是有些问题。在访问不算太大的情况下,数据库的访问不应导致显著的CPU占用率问题。
问题的排查相对简单一些,前段时间针对访问日志与页面访问量专门开发了相关功能,数据存储于数据库,每次产生访问的时候直接进行计算与数据库存储。可能会导致的问题也有过估计,现在应该是数据量的快速增加导致性能出现的问题。
于是询问AI解决的方式,给出的方案是比较靠谱的,后续的解决也是按其方案。
对于访问量,通过 Redis 缓存进行临时存储,达到一定的数量后再写入数据库。代码如下:
def update_view(clean_url: str, site_id: Site): """ 更新页面访问量 """ key = f'view_count:{clean_url}' # 确保 key 存在,避免 incr 报错 if not cache.has_key(key): cache.set(key, 0, timeout=None) count = cache.incr(key, 1) # 自增 # 集中写入数据库一次;计数归0 # 避免数值尾数一样,使用随机数 if count >= 10: UrlViewModel.objects.filter(url=clean_url, site=site_id).update( views=F('views') , dt_update=timezone.now(), ) cache.set(key, 0, timeout=None) 对于访问日志,同样在 Redis 中存储,不过是放到队列中,注意队列的使用需要直接通过 redis 的 get_redis_connection() 函数来调用,不能通过Django本身的 cache 模块 ; 通过定时任务,在特定的时间集中写入,并对缓存进行清空。写入Redis缓存的代码如下:
from django_redis import get_redis_connection redis_conn = get_redis_connection() def record_loger(clean_url: str, ip_address, site_id: Site, user_agent): """ 方案:日志先写缓存 → 定时批量入库 """ log_data = { 'url': clean_url, 'ipaddr': ip_address, 'user_agent': user_agent, 'site': site_id, } redis_conn.rpush('access_log_queue_8zD', json.dumps(log_data))