我有一个 asp.net webApi 应用程序并使用 redis 堆栈作为主数据库。我能够连接到数据库并正常执行操作,直到我从我的应用程序制作了一个 docker 图像并尝试在 docker 上运行它。即使我已将“localhost”更改为“容器名称”并将其设置为我的 docker-compose 文件中的环境变量,应用程序也无法连接到 redis 堆栈。这是我的连接代码和我的 docker-compose 文件供参考。
连接到 Redis 堆栈代码(使用 https://redis.io/docs/stack/get-started/tutorials/stack-dotnet/ 包):
builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration[Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)]));
builder.Services.AddHostedService<IndexCreationService>();
Dockerfile
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
我得到的错误信息:
未处理的异常。 StackExchange.Redis.RedisConnectionException:无法连接到 redis 服务器。立即连接错误。要允许此多路复用器继续重试直到能够连接,请在连接字符串中使用 abortConnect=false 或 AbortOnConnectFail=false;在你的代码中。在 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 ) 在 //src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1028 at Redis.OM.RedisConnectionProvider..ctor(String connectionString) at Program.$(String[] args) in /src/API/Program .cs:第 17 行
谁能发现问题?
回答1
看起来您是否将连接字符串从环境或配置中拉出有点混乱:
builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration[Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)]));
这一行实际上没有意义,您正试图从您的 appsettings 文件中提取一个配置变量,其名称是您的 REDIS_CONNECTION_STRING
环境变量的 VALUE (您在 docker-compose 中设置为 redis://redis:6379
) - 这很可能以空字符串的形式出现,因此无法正确解析和连接 - Redis OM 在配置中遇到空字符串时的默认行为是连接到 redis:// localhost:6379,因为那里没有 redis 实例,它会像你展示的那样失败。
您正在寻找两件事中的一件
- 您想从环境变量中提取连接字符串,如果您将该行更改为以下内容,鉴于您的 docker-compose 文件,这应该可以正常工作
builder.Services.AddSingleton(new RedisConnectionProvider(Environment.GetEnvironmentVariable("REDIS_CONNECTION_STRING", EnvironmentVariableTarget.Process)));
- 您确实想从配置中提取连接字符串,这是有效的,但您需要确保在构建映像之前在配置中设置连接字符串:
builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration["REDIS_CONNECTION_STRING"]));
这两种方法都是有效的,但它们不能很好地结合在一起,这就是为什么你在这里会有点胃灼热。