diff --git a/backend/core/path_conf.py b/backend/core/path_conf.py index d05fc683..cfe6824f 100644 --- a/backend/core/path_conf.py +++ b/backend/core/path_conf.py @@ -17,9 +17,6 @@ STATIC_DIR = BASE_PATH / 'static' # 上传文件目录 UPLOAD_DIR = STATIC_DIR / 'upload' -# 离线 IP 数据库路径 -IP2REGION_XDB = STATIC_DIR / 'ip2region.xdb' - # 插件目录 PLUGIN_DIR = BASE_PATH / 'plugin' diff --git a/backend/static/ip2region.xdb b/backend/static/ip2region_v4.xdb similarity index 56% rename from backend/static/ip2region.xdb rename to backend/static/ip2region_v4.xdb index c78b7928..6f86c7d9 100644 Binary files a/backend/static/ip2region.xdb and b/backend/static/ip2region_v4.xdb differ diff --git a/backend/utils/request_parse.py b/backend/utils/request_parse.py index e0bc382a..1ace5cdc 100644 --- a/backend/utils/request_parse.py +++ b/backend/utils/request_parse.py @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- import httpx -from asgiref.sync import sync_to_async from fastapi import Request from ip2loc import XdbSearcher from user_agents import parse @@ -10,7 +9,7 @@ from user_agents import parse from backend.common.dataclasses import IpInfo, UserAgentInfo from backend.common.log import log from backend.core.conf import settings -from backend.core.path_conf import IP2REGION_XDB +from backend.core.path_conf import STATIC_DIR from backend.database.redis import redis_client @@ -55,7 +54,10 @@ async def get_location_online(ip: str, user_agent: str) -> dict | None: return None -@sync_to_async +# 离线 IP 搜索器单例(数据将缓存到内存,缓存大小取决于 IP 数据文件大小) +__xdb_searcher = XdbSearcher(contentBuff=XdbSearcher.loadContentFromFile(dbfile=STATIC_DIR / 'ip2region_v4.xdb')) + + def get_location_offline(ip: str) -> dict | None: """ 离线获取 IP 地址属地,无法保证准确率,100% 可用 @@ -64,15 +66,12 @@ def get_location_offline(ip: str) -> dict | None: :return: """ try: - cb = XdbSearcher.loadContentFromFile(dbfile=IP2REGION_XDB) - searcher = XdbSearcher(contentBuff=cb) - data = searcher.search(ip) - searcher.close() + data = __xdb_searcher.search(ip) data = data.split('|') return { 'country': data[0] if data[0] != '0' else None, - 'regionName': data[2] if data[2] != '0' else None, - 'city': data[3] if data[3] != '0' else None, + 'regionName': data[1] if data[1] != '0' else None, + 'city': data[2] if data[2] != '0' else None, } except Exception as e: log.error(f'离线获取 IP 地址属地失败,错误信息:{e}') @@ -97,7 +96,7 @@ async def parse_ip_info(request: Request) -> IpInfo: if settings.IP_LOCATION_PARSE == 'online': location_info = await get_location_online(ip, request.headers.get('User-Agent')) elif settings.IP_LOCATION_PARSE == 'offline': - location_info = await get_location_offline(ip) + location_info = get_location_offline(ip) if location_info: country = location_info.get('country')