无法从容器内的 ASP.NET 应用程序连接到 Redis Stack

Can't connect to Redis Stack from ASP.NET application inside a container

我有一个 asp.net webApi 应用程序并使用 redis 堆栈作为主数据库。我能够连接到数据库并正常执行操作,直到我从我的应用程序制作了一个 docker 图像并尝试在 docker 上 运行 它。即使我已将“localhost”更改为“容器名称”并将其设置为我的 docker-compose 文件中的环境变量,应用程序也无法连接到 redis 堆栈。这是我的连接代码和我的 docker-compose 文件以供参考。

连接到 Redis 堆栈代码(使用 Redis OM 包):

builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration[Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)]));
builder.Services.AddHostedService<IndexCreationService>();

Docker文件

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["API/API.csproj", "API/"]
COPY ["Core/Core.csproj", "Core/"]
COPY ["Persistence/Persistence.csproj", "Persistence/"]
COPY ["Service/Service.csproj", "Service/"]
RUN dotnet restore "API/API.csproj"
COPY . .
WORKDIR "/src/API"
RUN dotnet build "API.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "API.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "API.dll"]

Docker-compose.yaml

version: '3.7'

services:
  redis:
    image: redis/redis-stack
    container_name: redis
    volumes:
      - db-data:/data/redis
    ports:
      - "6379:6379"
      - "8001:8001"
    restart: unless-stopped
    networks:
      - course-network
    
  CourseService:
    image: dexam/course-service
    container_name: course-service
    volumes:
      - course-service-data:/data/course_service
    ports:
      - "443:443"
    environment:
      - REDIS_CONNECTION_STRING=redis://redis:6379
    restart: unless-stopped
    depends_on:
      - "redis"
    links:
      - "redis"
    networks:
      - course-network

volumes:
  db-data:
  course-service-data:

networks:
  course-network:
  driver: bridge

我得到的错误信息:

Unhandled exception. StackExchange.Redis.RedisConnectionException: It was not possible to connect to the redis server(s). Error connecting right now. To allow this multiplexer to continue retrying until it's able to connect, use abortConnect=false in your connection string or AbortOnConnectFail=false; in your code. at StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(ConfigurationOptions configuration, TextWriter log) in //src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1162 at StackExchange.Redis.ConnectionMultiplexer.Connect(ConfigurationOptions configuration, TextWriter log) in //src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1028 at Redis.OM.RedisConnectionProvider..ctor(String connectionString) at Program.$(String[] args) in /src/API/Program.cs:line 17

谁能找出问题所在?

您是否正在将连接字符串从您的环境或配置中拉出似乎有些混乱:

builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration[Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)]));

这一行没有意义,您正试图从您的 appsettings 文件中提取一个配置变量,该文件的名称是 REDIS_CONNECTION_STRING 环境变量的 VALUE (您在 docker-compose 中设置为 redis://redis:6379) - 这很可能是一个空字符串,因此无法 parse-correctly 和连接 - Redis OM 时的默认行为在配置中遇到一个空字符串是连接到 redis://localhost:6379,因为那里没有 redis 实例,它会像你展示的那样失败。

您正在寻找两件事中的一件

  1. 您想从环境变量中拉出连接字符串,如果将该行更改为以下内容,给定您的 docker-compose 文件,这应该可以正常工作
builder.Services.AddSingleton(new RedisConnectionProvider(Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)));
  1. 您确实想从配置中提取连接字符串,这是有效的,但您需要确保在构建映像之前在配置中设置连接字符串:
builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration["REDIS_CONNECTION_STRING"]));

这两种方法都有效,但它们不能很好地结合在一起,这就是为什么你在这里有点胃灼热。