master
jinql 2025-09-08 17:50:27 +08:00
parent 01afa4d7b0
commit 617406cbbf
7 changed files with 89 additions and 17 deletions

View File

@ -1,11 +1,14 @@
services:
favicon-api:
favicon:
image: favicon-api:latest
container_name: favicon-api
ports:
- 8001:8000
env_file:
- .env
environment:
TZ: Asia/Shanghai
REDIS_URL: redis://redis:6379/0
volumes:
- /usr/share/zoneinfo/Asia/Shanghai:/usr/share/zoneinfo/Asia/Shanghai:ro
- /etc/localtime:/etc/localtime:ro
@ -13,4 +16,18 @@ services:
- ./data:/app/data:rw
- ./conf:/app/conf:rw
- ./logs:/app/logs:rw
restart: unless-stopped
restart: unless-stopped
networks:
- favicon_network
depends_on:
- redis
redis:
image: redis:7-alpine
container_name: favicon-redis
networks:
- favicon_network
networks:
favicon_network:
driver: bridge

View File

@ -7,6 +7,7 @@ from typing import Tuple, Optional
import aiohttp
import setting
from favicon_app.asyncs import redis_pool
from favicon_app.models import favicon
from favicon_app.utils import header
from favicon_app.utils.filetype import helpers, filetype
@ -135,6 +136,7 @@ class FaviconAsync(favicon.Favicon):
content = await resp.read()
return content, ct_type
else:
await redis_pool.set_cache(domain, setting.time_of_7_days, setting.time_of_7_days)
favicon.failed_url_cache(domain, setting.time_of_7_days)
logger.error('异步请求失败: %d, URL: %s', resp.status, url)
break
@ -146,6 +148,7 @@ class FaviconAsync(favicon.Favicon):
logger.warning('异步请求超时,正在重试(%d/%d): %s', retry_count, retries, url)
continue
except Exception as e:
await redis_pool.set_cache(domain, setting.time_of_7_days, setting.time_of_7_days)
favicon.failed_url_cache(domain, setting.time_of_7_days)
logger.error('异步请求异常: %s, URL: %s', str(e), url)
break

View File

@ -60,7 +60,7 @@ class FaviconServiceAsync(favicon_service.FaviconService):
strategy_url, strategy_name = strategy()
if strategy_url is not None:
logger.info(f"-> 异步尝试从 {strategy_name} 获取图标")
logger.debug(f"-> 异步尝试从 {strategy_name} 获取图标")
icon_content, icon_type = await entity.async_get_icon_file(strategy_url, strategy_url == '')
# 图标获取失败,或图标不是支持的图片格式,写入默认图标

View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
from typing import AsyncGenerator
from fastapi import Depends
from redis.asyncio import ConnectionPool, Redis
import setting
REDIS_URL = setting.REDIS_URL
pool = ConnectionPool.from_url(
REDIS_URL,
max_connections=200,
decode_responses=True,
)
async def get_redis() -> AsyncGenerator[Redis, None]:
async with Redis(connection_pool=pool) as conn:
yield conn
async def set_cache(
key: str,
value: str,
ttl: int | None = None,
r: Redis = Depends(get_redis),
):
await r.set(key, value, ex=ttl)
async def get_cache(key: str, r: Redis = Depends(get_redis)):
return await r.get(key)
async def del_cache(key: str, r: Redis = Depends(get_redis)):
await r.delete(key)

14
main.py
View File

@ -2,11 +2,13 @@
import logging
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.responses import Response
import setting
from favicon_app.asyncs.redis_pool import pool
from favicon_app.routes import favicon_router
from favicon_app.utils.file_util import FileUtil
@ -21,8 +23,18 @@ default_icon_file = setting.default_icon_file
# referer日志文件路径
referer_log_file = setting.referer_log_file
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用级生命周期:启动/清理。"""
print("Redis pool ready.")
yield
await pool.aclose()
print("Redis pool closed.")
# fastapi
app = FastAPI(title="Favicon API", description="获取网站favicon图标", version="3.0.0")
app = FastAPI(lifespan=lifespan, title="Favicon API", description="获取网站favicon图标", version="3.0")
app.include_router(favicon_router)

View File

@ -1,16 +1,17 @@
--index https://mirrors.xinac.net/pypi/simple
--extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple
fastapi~=0.116.1
pydantic~=2.11.7
pydantic_core~=2.33.2
starlette~=0.47.3
requests~=2.32.5
aiohttp~=3.12.15
bs4~=0.0.2
beautifulsoup4~=4.13.5
lxml~=6.0.1
PyYAML~=6.0.2
uvicorn~=0.35.0
uvicorn-worker~=0.3.0
gunicorn~=23.0.0
fastapi~=0.116
pydantic~=2.11
pydantic_core~=2.33
starlette~=0.47
requests~=2.32
aiohttp~=3.12
bs4~=0.0
beautifulsoup4~=4.13
lxml~=6.0
PyYAML~=6.0
uvicorn~=0.35
uvicorn-worker~=0.3
gunicorn~=23.0
redis[hiredis]~=6.4

View File

@ -39,3 +39,4 @@ time_of_30_days = 30 * time_of_1_days
# 是否使用同步方式
sync = 'false'
REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0")