首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >容器化.net核心应用程序无法连接到容器化mongo数据库

容器化.net核心应用程序无法连接到容器化mongo数据库
EN

Stack Overflow用户
提问于 2020-11-02 02:54:07
回答 1查看 327关注 0票数 0

我在本地机器上运行.net核心应用程序。以下是连接到mongo db的代码

代码语言:javascript
复制
public BookService(IBookstoreDatabaseSettings settings)
        {
            var client = new MongoClient("mongodb://admin:password@localhost:27017");
            var database = client.GetDatabase("BookstoreDb");

            _books = database.GetCollection<Book>(settings.BooksCollectionName);
        }

此外,我正在运行以下docker组合文件

代码语言:javascript
复制
version: '3'
services: 
        mongodb:
        image: mongo
        ports:
            - 27017:27017
        environment:
            - MONGO_INITDB_ROOT_USERNAME=admin
            - MONGO_INITDB_ROOT_PASSWORD=password
    mongo-express:
        image: mongo-express
        ports:
            - 8081:8081
        environment:
            - ME_CONFIG_MONGODB_ADMINUSERNAME=admin
            - ME_CONFIG_MONGODB_ADMINPASSWORD=password
            - ME_CONFIG_MONGODB_SERVER=mongodb

当我使用dotnet运行应用程序时,运行然后请求http://localhost:5001/api/books。一切都运行得很好,api能够连接到mongo数据库。

接下来,我使用标准的.net核心Docker文件来容器化我的应用程序

代码语言:javascript
复制
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "BooksApi.dll"]

接下来,我将通过运行以下命令创建Docker镜像

代码语言:javascript
复制
docker build -t sample:1.0 .  

然后通过添加以下内容扩展docker-compose

代码语言:javascript
复制
sampleapp:
        image: sample:1.0
        ports:
            - 5001:80

我正在运行docker-compose -f .\mongo.yaml up

代码语言:javascript
复制
docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
86ae717ef475        mongo-express       "tini -- /docker-ent…"   About an hour ago   Up About an hour    0.0.0.0:8081->8081/tcp     sampleapp_mongo-express_1
3c068306c6e2        mongo               "docker-entrypoint.s…"   About an hour ago   Up About an hour    0.0.0.0:27017->27017/tcp   sampleapp_mongodb_1
f275479d2467        sample:1.0          "dotnet BooksApi.dll"    About an hour ago   Up About an hour    0.0.0.0:5001->80/tcp       sampleapp_sampleapp_1

在浏览器http://localhost:5001/api/books中请求api返回500

docker日志f275479d2467返回

代码语言:javascript
复制
Hosting environment: Production
Content root path: /app
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HM3UHJ593UOV", Request id "0HM3UHJ593UOV:00000001": An unhandled exception was thrown by the application.
System.TimeoutException: A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "Automatic", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", EndPoint: "Unspecified/localhost:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server.
 ---> System.Net.Sockets.SocketException (99): Cannot assign requested address
   at System.Net.Sockets.Socket.BeginConnectEx(EndPoint remoteEP, Boolean flowContext, AsyncCallback callback, Object state)
   at System.Net.Sockets.Socket.ConnectAsync(EndPoint remoteEP)
   at MongoDB.Driver.Core.Connections.TcpStreamFactory.ConnectAsync(Socket socket, EndPoint endPoint, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Connections.TcpStreamFactory.CreateStreamAsync(EndPoint endPoint, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Servers.ServerMonitor.HeartbeatAsync(CancellationToken cancellationToken)", LastUpdateTimestamp: "2020-11-01T17:38:08.7321465Z" }] }.
   at MongoDB.Driver.Core.Clusters.Cluster.ThrowTimeoutException(IServerSelector selector, ClusterDescription description)
   at MongoDB.Driver.Core.Clusters.Cluster.WaitForDescriptionChangedHelper.HandleCompletedTask(Task completedTask)
   at MongoDB.Driver.Core.Clusters.Cluster.WaitForDescriptionChanged(IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Clusters.Cluster.SelectServer(IServerSelector selector, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoClient.AreSessionsSupportedAfterServerSelection(CancellationToken cancellationToken)
   at MongoDB.Driver.MongoClient.AreSessionsSupported(CancellationToken cancellationToken)
   at MongoDB.Driver.MongoClient.StartImplicitSession(CancellationToken cancellationToken)
   at MongoDB.Driver.OperationExecutor.StartImplicitSession(CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.FindSync[TProjection](FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
   at MongoDB.Driver.FindFluent`2.ToCursor(CancellationToken cancellationToken)
   at MongoDB.Driver.IAsyncCursorSourceExtensions.ToList[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)
   at BooksApi.Services.BookService.Get() in /app/Services/BookService.cs:line 24
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-03 18:58:19

简短的回答

将mongo uri更改为mongodb://admin:password@mongodb:27017并重新构建映像。

长长的答案

当您将应用程序放入停靠容器中时,localhost不再指向您的主机,而是指向容器的localhost。显然,mongodb不是在那里运行的,而是在单独的容器中运行的。

当您从docker-compose运行您的容器时,它们都连接到由compose创建的公共docker网络。然后,组合中的服务名称就是DNS名称,可以通过此网络将其解析为容器的IP。这就是为什么在您的例子中应该在连接字符串中使用mongodb作为mongodb的主机。你可以在docker-compose networking docs上阅读更多关于它的内容。

还需要注意的是,连接字符串应该从环境中获取,而不是硬编码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64635716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档