mengqiankang 2 месяцев назад
Родитель
Сommit
5a9aa5e22b
4 измененных файлов с 102 добавлено и 2 удалено
  1. 19 0
      alien_gateway/Dockerfile
  2. 3 0
      alien_gateway/config.py
  3. 61 2
      alien_gateway/main.py
  4. 19 0
      alien_store/Dockerfile

+ 19 - 0
alien_gateway/Dockerfile

@@ -0,0 +1,19 @@
+FROM python:3.12-slim
+
+WORKDIR /app
+
+ENV POETRY_VIRTUALENVS_CREATE=false \
+    PYTHONUNBUFFERED=1 \
+    PYTHONDONTWRITEBYTECODE=1
+
+RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple \
+    && pip install --no-cache-dir poetry
+
+COPY pyproject.toml poetry.lock ./
+RUN poetry install --no-root --no-interaction --no-ansi
+
+COPY . .
+
+EXPOSE 33333
+
+CMD ["uvicorn", "alien_gateway.main:app", "--host", "0.0.0.0", "--port", "33333"]

+ 3 - 0
alien_gateway/config.py

@@ -20,6 +20,9 @@ class Settings(BaseSettings):
 
     # redis配置
     REDIS_URL: str = "redis://:Alien123456@172.31.154.180:30002/0"
+
+    # 下游服务地址
+    STORE_BASE_URL: str = "http://127.0.0.1:8001"  # alien_store 服务地址
     @property
     def SQLALCHEMY_DATABASE_URI(self) -> str:
         return f"mysql+pymysql://{self.DB_USER}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"

+ 61 - 2
alien_gateway/main.py

@@ -1,4 +1,8 @@
-from fastapi import FastAPI
+import logging
+from typing import List
+import httpx
+from fastapi import FastAPI, Request, Response, HTTPException
+from starlette.status import HTTP_502_BAD_GATEWAY
 from alien_gateway.config import settings
 
 app = FastAPI(
@@ -6,6 +10,8 @@ app = FastAPI(
     version="1.0.0"
 )
 
+logger = logging.getLogger("alien_gateway")
+
 @app.get("/health")
 async def health():
     return {"service": "alien_gateway", "status": "ok"}
@@ -15,6 +21,59 @@ async def health():
 async def login():
     return {"message": "Auth logic here"}
 
+
+HOP_BY_HOP_HEADERS: List[str] = [
+    "connection",
+    "keep-alive",
+    "proxy-authenticate",
+    "proxy-authorization",
+    "te",
+    "trailers",
+    "transfer-encoding",
+    "upgrade",
+]
+
+
+def _clean_headers(headers):
+    """移除 hop-by-hop 头,避免转发问题。"""
+    return {k: v for k, v in headers.items() if k.lower() not in HOP_BY_HOP_HEADERS}
+
+
+@app.api_route("/api/store/{full_path:path}", methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"])
+async def proxy_to_store(full_path: str, request: Request):
+    """
+    简易网关:监听 33333 端口,将 /api/store/* 转发到 alien_store 服务。
+    """
+    target_url = f"{settings.STORE_BASE_URL}/api/store/{full_path}"
+    client_ip = request.client.host if request.client else "-"
+
+    # 读取请求体
+    body = await request.body()
+
+    # 过滤头部
+    headers = _clean_headers(dict(request.headers))
+
+    try:
+        async with httpx.AsyncClient(timeout=30.0) as client:
+            resp = await client.request(
+                request.method,
+                target_url,
+                content=body,
+                headers=headers,
+                params=request.query_params,
+            )
+    except Exception as exc:
+        logger.error("proxy to store failed ip=%s url=%s err=%s", client_ip, target_url, exc)
+        raise HTTPException(status_code=HTTP_502_BAD_GATEWAY, detail="Upstream unavailable")
+
+    # 返回下游响应
+    return Response(
+        content=resp.content,
+        status_code=resp.status_code,
+        headers=_clean_headers(resp.headers),
+        media_type=resp.headers.get("content-type"),
+    )
+
 if __name__ == "__main__":
     import uvicorn
-    uvicorn.run(app, host="0.0.0.0", port=8000)
+    uvicorn.run(app, host="0.0.0.0", port=33333)

+ 19 - 0
alien_store/Dockerfile

@@ -0,0 +1,19 @@
+FROM python:3.12-slim
+
+WORKDIR /app
+
+ENV POETRY_VIRTUALENVS_CREATE=false \
+    PYTHONUNBUFFERED=1 \
+    PYTHONDONTWRITEBYTECODE=1
+
+RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple \
+    && pip install --no-cache-dir poetry
+
+COPY pyproject.toml poetry.lock ./
+RUN poetry install --no-root --no-interaction --no-ansi
+
+COPY . .
+
+EXPOSE 8001
+
+CMD ["uvicorn", "alien_store.main:app", "--host", "0.0.0.0", "--port", "8001"]