大佬教程收集整理的这篇文章主要介绍了为什么我的 .NET Web API 应用程序在使用 docker-compose 时无法连接到 docker 上的 MySQL?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个在 docker 中运行的 .NET Core 应用程序,它连接到 docker 上的 MysqL 数据库,
当 MysqL docker 容器使用 docker run 命令运行时:
C:\dev>docker run -p 3310:3306 --name=MysqL1 -e MysqL_ROOT_password=pw -d MysqL:5.6
C:\dev>docker run -p 3311:3306 --name=MysqL2 -e MysqL_ROOT_password=pw -d MysqL:5.6
我没有收到错误消息,但是当我尝试使用 docker-compose 时出现此错误:
ConnectionString: server=database0; port=3312; database=post; user=root; password=pw; Persist Security Info=false; Connect Timeout=300
ConnectionString: server=database1; port=3313; database=post; user=root; password=pw; Persist Security Info=false; Connect Timeout=300
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection ID "0HMA1R75ALK39",request ID "0HMA1R75ALK39:00000002": An unhandled exception was thrown by the application.
System.TypeInitializationException: The type initializer for 'mysql.data.MysqLClIEnt.Replication.ReplicationManager' threw an exception.
---> System.TypeInitializationException: The type initializer for 'mysql.data.MysqLClIEnt.MysqLConfiguration' threw an exception.
---> System.Configuration.ConfigurationErrorsException: Configuration system Failed to initialize
---> System.NotSupportedException: CodeBase is not supported on assemblIEs loaded from a single-file bundle.
at System.Reflection.RuntimeAssembly.get_CodeBase()
at System.Configuration.ClIEntConfigPaths..ctor(String exePath,Boolean includeUserConfig)
at System.Configuration.ClIEntConfigPaths.GetPaths(String exePath,Boolean includeUserConfig)
at System.Configuration.ClIEntConfigurationHost.get_ConfigPaths()
at System.Configuration.ClIEntConfigurationHost.GetStreamname(String configPath)
at System.Configuration.ClIEntConfigurationHost.get_IsAppConfighttp()
at System.Configuration.Internal.DelegaTingConfigHost.get_IsAppConfighttp()
at System.Configuration.ClIEntConfigurationSystem..ctor()
at System.Configuration.ConfigurationManager.EnsureConfigurationSystem()
--- End of inner exception stack trace ---
at System.Configuration.ConfigurationManager.EnsureConfigurationSystem()
at System.Configuration.ConfigurationManager.PrepareConfigSystem()
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at mysql.data.MysqLClIEnt.MysqLConfiguration..cctor()
--- End of inner exception stack trace ---
at mysql.data.MysqLClIEnt.MysqLConfiguration.get_SetTings()
at mysql.data.MysqLClIEnt.Replication.ReplicationManager..cctor()
--- End of inner exception stack trace ---
at mysql.data.MysqLClIEnt.Replication.ReplicationManager.IsReplicationGroup(String groupName)
at mysql.data.MysqLClIEnt.MysqLConnection.open()
at System.Data.Common.DbConnection.openAsync(CancellationToken cancellationToken)
--- End of stack trace from prevIoUs LOCATIOn ---
at Mysql.EntityFrameworkCore.MysqLDatabaseCreator.<>c__displayClass20_0.<<ExistsAsync>b__0>d.MoveNext()
--- End of stack trace from prevIoUs LOCATIOn ---
at Mysql.EntityFrameworkCore.Storage.Internal.MysqLEXECUTIONStrategy.ExecuteAsync[TState,TResult](TState state,Func`4 operation,Func`4 verifySucceeded,CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsuredeletedAsync(CancellationToken cancellationToken)
at postservice.Data.DataAccess.InitDatabase(Int32 countUsers,Int32 countCategorIEs)
at postservice.Controllers.postsController.InitDatabase(Int32 countUsers,Int32 countCategorIEs)
at lambda_method4(Closure,Object )
at Microsoft.Extensions.Internal.objectMethodExecutorAwaitable.Awaiter.GetResult()
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper mapper,ObjectMethodExecutor executor,Object controller,Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker,ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterasync>g__Awaited|10_0(ControllerActionInvoker invoker,Task lastTask,State next,Scope scope,Object state,Boolean isCompleted)
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 ---
at Microsoft.AspNetCore.Mvc.Infrastructure.resourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(resourceInvoker invoker,Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.resourceInvoker.<InvokeAsync>g__Awaited|17_0(resourceInvoker invoker,Task task,Idisposable scopE)
at Microsoft.AspNetCore.RoutIng.EndpointMIDdleware.<Invoke>g__AwaitrequestTask|6_0(Endpoint endpoint,Task requestTask,ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMIDdleware.Invoke(httpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.http.httpProtocol.Processrequests[TContext](IhttpApplication`1 application)
经过数小时尝试不同的东西后,我发现在谷歌上搜索,仍然无法连接到 MysqL。
这是我的 docker-compose.yaml
version: '3.8'
services:
webservice:
image: 'arIEfs/postservice:v1.0.0'
cpus: 0.5
scale: 4
environment:
- PostDbConnectionStrings__Shard0=server=database0; port=3312; database=post; user=root; password=pw; Persist Security Info=false; Connect Timeout=300
- PostDbConnectionStrings__Shard1=server=database1; port=3313; database=post; user=root; password=pw; Persist Security Info=false; Connect Timeout=300
# - PostDbConnectionStrings__Shard2=server=database2; port=3306; database=post; user=root; password=pw; Persist Security Info=false; Connect Timeout=300
loadbalancer:
image: dockercloud/haproxy
links:
- webservice
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 5001:80
database0:
image: 'MysqL:5.6'
cpus: 0.5
ports:
- 3312:3306
environment:
- MysqL_ROOT_password=pw
database1:
image: 'MysqL:5.6'
cpus: 0.5
ports:
- 3313:3306
environment:
- MysqL_ROOT_password=pw
database2:
image: 'MysqL:5.6'
cpus: 0.5
ports:
- 3314:3306
environment:
- MysqL_ROOT_password=pw
这是我的 docker ps :
❯ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
nameS
668b32b68d0f dockercloud/haproxy "/sbin/Tini -- docke…" 3 minutes ago Up 3 minutes 443/tcp,1936/tcp,0.0.0.0:5001->80/tcp,:::5001->80/tcp postservice_loadbalancer_1
a2f3be18868c arIEfs/postservice:v1.0.0 "./postservice --url…" 3 minutes ago Up 3 minutes 80/tcp
postservice_webservice_3
ac8c9d791cc5 arIEfs/postservice:v1.0.0 "./postservice --url…" 3 minutes ago Up 3 minutes 80/tcp
postservice_webservice_2
7fe86c655063 arIEfs/postservice:v1.0.0 "./postservice --url…" 3 minutes ago Up 3 minutes 80/tcp
postservice_webservice_4
5105d0472f78 arIEfs/postservice:v1.0.0 "./postservice --url…" 3 minutes ago Up 3 minutes 80/tcp
postservice_webservice_1
f8f8e5a1ed86 MysqL:5.6 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:3313->3306/tcp,:::3313->3306/tcp postservice_database1_1
c4aafd2b2182 MysqL:5.6 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:3312->3306/tcp,:::3312->3306/tcp postservice_database0_1
和我的 DataAccess 类
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using postservice.EntitIEs;
using System;
using System.Collections.Generic;
using System.linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace postservice.Data
{
public class DataAccess
{
private Readonly List<String> _connectionStrings = new List<String>();
public DataAccess(IConfiguration configuration)
{
var connectionStrings = configuration.GetSection("PostDbConnectionStrings");
foreach (var connectionString in connectionStrings.GetChildren())
{
Console.Writeline("ConnectionString: " + connectionString.value);
_connectionStrings.Add(connectionString.value);
}
}
public async Task<ActionResult<IEnumerable<Post>>> ReadLatestposts(String category,int count)
{
using var dbContext = new postserviceContext(GetConnectionString(category));
return await dbContext.Post.orderByDescending(p => p.postID)
.Take(count)
.Include(x => x.User)
.Where(p => p.categoryID == category)
.ToListAsync();
}
public async Task<int> CreatePost(Post post)
{
using var dbContext = new postserviceContext(GetConnectionString(post.categoryID));
dbContext.Post.Add(post);
return await dbContext.SaveChangesAsync();
}
public async Task InitDatabase(int countUsers,int countCategorIEs)
{
foreach (var connectionString in _connectionStrings)
{
using var dbContext = new postserviceContext(connectionString);
await dbContext.Database.EnsuredeletedAsync();
await dbContext.Database.EnsuredeletedAsync();
for (int i = 1; i <= countUsers; i++)
{
await dbContext.User.AddAsync(new User { name = "User" + i,Version = 1 });
await dbContext.SaveChangesAsync();
}
for (int i = 1; i <= countCategorIEs; i++)
{
await dbContext.category.AddAsync(new category { categoryID = "category" + i });
await dbContext.SaveChangesAsync();
}
}
}
private String GetConnectionString(String category)
{
using var md5 = MD5.Create();
var hash = md5.ComputeHash(EnCoding.ASCII.GetBytes(category));
var x = BitConverter.ToUInt16(hash,0) % _connectionStrings.Count;
return _connectionStrings[x];
}
}
}
更新
我正在尝试更改环境中的端口 = 3360
环境:
- PostDbConnectionStrings__Shard0=server=database0;端口=3312;数据库=帖子;用户=root;密码=密码;持久安全信息=假;连接超时=300
- PostDbConnectionStrings__Shard1=server=database1;端口=3313;数据库=帖子;用户=root;密码=密码;持久安全信息=假;连接超时=300
# - PostDbConnectionStrings__Shard2=server=database2;端口=3306;数据库=帖子;用户=root;密码=密码;持久安全信息=假;连接超时=300
并得到了这个异常:
ConnectionString: server=database1; port=3306; database=post; user=root; password=pw; Persist Security Info=false; Connect Timeout=300
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection ID "0HMA1U8GBSBGK",request ID "0HMA1U8GBSBGK:00000002": An unhandled exception was thrown by the application.
System.TypeInitializationException: The type initializer for 'mysql.data.MysqLClIEnt.Replication.ReplicationManager' threw an exception.
---> System.TypeInitializationException: The type initializer for 'mysql.data.MysqLClIEnt.MysqLConfiguration' threw an exception.
---> System.Configuration.ConfigurationErrorsException: Configuration system Failed to initialize
---> System.NotSupportedException: CodeBase is not supported on assemblIEs loaded from a single-file bundle.
at System.Reflection.RuntimeAssembly.get_CodeBase()
at System.Configuration.ClIEntConfigPaths..ctor(String exePath,ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMIDdleware.Invoke(httpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.http.httpProtocol.Processrequests[TContext](IhttpApplication`1 application)
这是我的 dockerfile
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS publish
workdir /src
copY ["postservice.csproj","./"]
RUN dotnet restore "postservice.csproj" --runtime alpine-x64
copY . .
RUN dotnet publish "postservice.csproj" -c Release -o /app/publish \
--no-restore \
--runtime alpine-x64 \
--self-contained true \
/p:PublishTrimmed=true \
/p:PublishSinglefile=true
FROM mcr.microsoft.com/dotnet/runtime-deps:5.0-alpine AS final
RUN adduser --Disabled-password \
--home /app \
--gecos '' dotnetuser && chown -R dotnetuser /app
RUN apk upgrade musl
USER dotnetuser
workdir /app
EXPOSE 80
copY --from=publish /app/publish .
ENTRYPOINT ["./postservice","--urls","http://0.0.0.0:80"]
这里是我的 .csproj 文件
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<packagereference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.7">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</packagereference>
<packagereference Include="Mysql.EntityFrameworkCore" Version="5.0.3.1" />
<packagereference Include="Newtonsoft.Json" Version="13.0.1" />
<packagereference Include="Swashbuckle.AspNetCore" Version="6.1.4" />
</ItemGroup>
</Project>
我只关注这个article
您尚未显示应用程序的 Dockerfile,但我猜您正在使用 dotnet publish
创建单文件应用程序。
正如异常消息所说:
System.Configuration.ConfigurationErrorsException:配置系统初始化失败
System.NotSupportedException:从单文件包加载的程序集不支持 CodeBase。
您正在使用的 .NET MySQL 库 (MySql.Data) 依赖于 ConfigurationManager
,这会导致此异常。您有两个选择:
要停止作为单个文件发布,请将 RUN dotnet publish
中的 Dockerfile
块更改为:
RUN dotnet publish "Postservice.csproj" -c Release -o /app/publish \
--no-restore \
--runtime alpine-x64 \
--self-contained true
以上是大佬教程为你收集整理的为什么我的 .NET Web API 应用程序在使用 docker-compose 时无法连接到 docker 上的 MySQL?全部内容,希望文章能够帮你解决为什么我的 .NET Web API 应用程序在使用 docker-compose 时无法连接到 docker 上的 MySQL?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。