Explorar o código

uat环境 配置高可用redis配置

mengqiankang hai 1 mes
pai
achega
1a63a1437a
Modificáronse 3 ficheiros con 99 adicións e 8 borrados
  1. 24 3
      alien_gateway/config.py
  2. 14 5
      alien_util/celery_app.py
  3. 61 0
      alien_util/redis_client.py

+ 24 - 3
alien_gateway/config.py

@@ -21,9 +21,12 @@ class Settings(BaseSettings):
     DB_PORT: int = os.getenv("DB_PORT")
     DB_NAME: str = os.getenv("DB_NAME")
 
-    # redis配置
-    # REDIS_URL: str = "redis://:Alien123456@172.31.154.180:30002/0"
-    REDIS_URL: str = os.getenv("REDIS_URL")
+    # Redis Sentinel 高可用配置
+    # 例: REDIS_SENTINELS=192.168.2.251:36379,192.168.2.252:36379,192.168.2.253:36379
+    REDIS_SENTINELS: str = os.getenv("REDIS_SENTINELS", "")
+    REDIS_MASTER_NAME: str = os.getenv("REDIS_MASTER_NAME", "mymaster")
+    REDIS_PASSWORD: str = os.getenv("REDIS_PASSWORD", "")
+    REDIS_DB: int = int(os.getenv("REDIS_DB", "0"))
 
     # 下游服务地址
     STORE_BASE_URL: str = os.getenv("STORE_BASE_URL")  # alien_store 服务地址
@@ -40,6 +43,24 @@ class Settings(BaseSettings):
     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}"
 
+    @property
+    def REDIS_SENTINEL_NODES(self) -> List[tuple[str, int]]:
+        nodes: List[tuple[str, int]] = []
+        for item in self.REDIS_SENTINELS.split(","):
+            entry = item.strip()
+            if not entry:
+                continue
+            host, port = entry.split(":")
+            nodes.append((host.strip(), int(port.strip())))
+        return nodes
+
+    @property
+    def REDIS_SENTINEL_URL(self) -> str:
+        # Celery sentinel transport 需要 "sentinel://host:port;sentinel://host:port"
+        return ";".join(
+            f"sentinel://{host}:{port}" for host, port in self.REDIS_SENTINEL_NODES
+        )
+
     model_config = SettingsConfigDict(
         case_sensitive=True,
         env_file=".env",

+ 14 - 5
alien_util/celery_app.py

@@ -2,14 +2,11 @@ from celery import Celery
 from celery.schedules import crontab
 from alien_gateway.config import settings
 
-# Redis 配置(可以从环境变量读取,这里使用默认配置)
-REDIS_URL = settings.REDIS_URL
-
 # 创建 Celery 应用
 celery_app = Celery(
     "alien_cloud",
-    broker=REDIS_URL,
-    backend=REDIS_URL,
+    broker=settings.REDIS_SENTINEL_URL,
+    backend=settings.REDIS_SENTINEL_URL,
     include=["alien_util.tasks.contract_tasks"]
 )
 
@@ -20,6 +17,18 @@ celery_app.conf.update(
     result_serializer="json",
     timezone="Asia/Shanghai",
     enable_utc=True,
+    broker_transport_options={
+        "master_name": settings.REDIS_MASTER_NAME,
+        "sentinel_kwargs": {"password": settings.REDIS_PASSWORD},
+        "password": settings.REDIS_PASSWORD,
+        "db": settings.REDIS_DB,
+    },
+    result_backend_transport_options={
+        "master_name": settings.REDIS_MASTER_NAME,
+        "sentinel_kwargs": {"password": settings.REDIS_PASSWORD},
+        "password": settings.REDIS_PASSWORD,
+        "db": settings.REDIS_DB,
+    },
     # 定时任务配置
     beat_schedule={
         "check-contract-expiry": {

+ 61 - 0
alien_util/redis_client.py

@@ -0,0 +1,61 @@
+from redis import Redis
+from redis.asyncio import Redis as AsyncRedis
+from redis.asyncio.sentinel import Sentinel as AsyncSentinel
+from redis.sentinel import Sentinel
+
+from alien_gateway.config import settings
+
+
+def _sentinel_kwargs() -> dict:
+    kwargs = {}
+    if settings.REDIS_PASSWORD:
+        kwargs["password"] = settings.REDIS_PASSWORD
+    return kwargs
+
+
+def get_sentinel_client() -> Sentinel:
+    return Sentinel(
+        settings.REDIS_SENTINEL_NODES,
+        socket_timeout=0.5,
+        sentinel_kwargs=_sentinel_kwargs(),
+    )
+
+
+def get_async_sentinel_client() -> AsyncSentinel:
+    return AsyncSentinel(
+        settings.REDIS_SENTINEL_NODES,
+        socket_timeout=0.5,
+        sentinel_kwargs=_sentinel_kwargs(),
+    )
+
+
+def get_redis_master() -> Redis:
+    return get_sentinel_client().master_for(
+        service_name=settings.REDIS_MASTER_NAME,
+        password=settings.REDIS_PASSWORD or None,
+        db=settings.REDIS_DB,
+    )
+
+
+def get_redis_slave() -> Redis:
+    return get_sentinel_client().slave_for(
+        service_name=settings.REDIS_MASTER_NAME,
+        password=settings.REDIS_PASSWORD or None,
+        db=settings.REDIS_DB,
+    )
+
+
+def get_async_redis_master() -> AsyncRedis:
+    return get_async_sentinel_client().master_for(
+        service_name=settings.REDIS_MASTER_NAME,
+        password=settings.REDIS_PASSWORD or None,
+        db=settings.REDIS_DB,
+    )
+
+
+def get_async_redis_slave() -> AsyncRedis:
+    return get_async_sentinel_client().slave_for(
+        service_name=settings.REDIS_MASTER_NAME,
+        password=settings.REDIS_PASSWORD or None,
+        db=settings.REDIS_DB,
+    )