Dev*_*ngh 4 docker .net-core grpc kestrel-http-server asp.net-core
我有两个带有普通 Web API 和 gRPC 服务的 .net 核心微服务(PatientService 和 AppointmentService)。我使用 gRPC 进行服务间通信,而不是使用 HTTP 调用。
预约服务依赖于患者服务的数据,这意味着当我点击预约服务的端点以获取预约时,我需要来自患者服务的患者信息,因此我使用 gRPC 进行此调用。
现在我的应用程序运行良好,我能够在两者之间进行通信,而无需在本地环境中使用 kestrel 做任何额外的事情。但是当我在 Docker 中运行相同的应用程序时,该应用程序没有运行,我无法访问 HTTP1 和 HTTp2 端口。我正在运行 Linux 容器。
我的问题是如何在 .net 核心应用程序中运行 HTTP1 和 HTTP2?如何使用grpc在.net微服务中进行服务间通信?
如何使用 Linux 容器(Ubuntu 18.04)在 docker 中运行 .net core web API + gRPC 服务?如何在没有 TLS 的情况下运行 gRPC?
请帮助我已经尝试了一切,但我被卡住了。我有这个重要的版本要发布。
Docker 文件。
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf
WORKDIR /app
EXPOSE 80
EXPOSE 6002
EXPOSE 443
EXPOSE 5001
EXPOSE 6001
#our sql server was use this port for connect
EXPOSE 7007
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["API/API.csproj", "API/"]
COPY ["Infrastructure/Infrastructure.csproj", "Infrastructure/"]
COPY ["Application/Application.csproj", "Application/"]
COPY ["Domain/Domain.csproj", "Domain/"]
COPY ["Common/Common.csproj", "Common/"]
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"]
Run Code Online (Sandbox Code Playgroud)
我找到了一个对我有用的解决方案,我只用了 3 周就搞定了。
有3个主要问题:
应该在 appsetting.json 或程序 cs 中使用以下参数设置 Kestrel:
"Kestrel": {
"EndPoints": {
"Grpc": {
"Url": "http://*:8080",
"Protocols": "Http2"
},
"webApi": {
"Protocols": "Http1",
"Url": "http://*:80"
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者
ConfigureKestrel(options =>
{
options.ListenAnyIP(80, listenOptions => listenOptions.Protocols = HttpProtocols.Http1); //webapi
options.ListenAnyIP(8080, listenOptions => listenOptions.Protocols = HttpProtocols.Http2); //grpc
})
Run Code Online (Sandbox Code Playgroud)
完成此设置后,您可以使用以下命令启动 docker(端口和 ip 可能会有所不同,请确保没有其他东西在监听这些端口 ips):
docker run -p 127.0.0.40:8080:80 -p 127.0.0.40:8081:8080 --env ASPNETCORE_ENVIRONMENT=Development -it my_project -e ASPNETCORE_ENVIRONMENT=Development -e ASPNETCORE_URLS=http://+
Run Code Online (Sandbox Code Playgroud)
在此之后,您必须配置您的频道(不要使用 Grpc.AspNetCore 中的“.AddGrpcClient”扩展名):
services.AddSingleton(x =>
{
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
return GrpcChannel.ForAddress("127.0.0.40:8081",
//TODO:GRPC Root SSL Creds
channelOptions: new GrpcChannelOptions()
{
Credentials = ChannelCredentials.Insecure
});
});
Run Code Online (Sandbox Code Playgroud)
在此之后,您可以根据自己的意愿使用您创建的频道创建您的客户,无论您想做什么都应该没问题。没有其他方法对我有用。
更新: 我找到了一种方法让它与 Grpc.AspNetCore 的“AddGrpcClient”一起工作。
services.AddGrpcClient<ControllerGuide.GuideClient>(
(x, opt) =>
{
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
opt.Address = new Uri("UriGRPC:5001");
opt.ChannelOptionsActions.Add(act =>
{
act.Credentials = ChannelCredentials.Insecure;
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2479 次 |
| 最近记录: |