azure - 如何设置两个都使用 https 端口的微服务?
问题描述
我有一个微服务是 Asp.Net Core 无状态服务。该服务运行良好,我可以在https://myazureresource.eastus.cloudapp.azure.com/controller/method访问。
我的 ServiceManifest.xml 是:
<Resources>
<Endpoints>
<Endpoint Protocol="https" Name="EndpointHttps" Type="Input" Port="443" />
</Endpoints>
</Resources>
MyService.cs 是:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "EndpointHttps", (url, listener) =>
{
var transportCertificate = GetCertificate(ConfigurationManager.Instance["mycert"]);
return new WebHostBuilder()
.UseKestrel(x =>
{
int port = serviceContext.CodePackageActivationContext.GetEndpoint("EndpointHttps").Port;
x.Listen(IPAddress.IPv6Any, port, listenOptions =>
{
listenOptions.UseHttps(transportCertificate);
listenOptions.NoDelay = true;
});
})
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.UseSerilog(Logger.Serilog)
.Build();
}))
};
}
一切正常,但是现在我不想创建另一个微服务。我收到一个错误,它显然无法绑定到 443,因为它已经被使用了。不知何故,我必须告诉它在 url 中使用我的服务名称。
我尝试了很多事情,包括附加到网址:
.UserUrls(url + "/myservice")
但我得到一个无法绑定的异常,因为它正在覆盖并使用 UseKestrel 端点。然后我尝试了 PreferHostingUrls(true),但随后出现错误,您必须使用 UsePathBase。
然后我尝试:
.UsePathBase("myservice")
然后我得到一个错误,它没有有效的 https 证书。但它适用于一个微服务。
1. 有谁知道你必须做什么才能让两个微服务同时工作?
2. 在单独的说明中(只是出于好奇)我一直想知道为什么你会使用动态端口。如果服务选择端口,你怎么知道给你的客户什么 url?
谢谢你的帮助。
解决方案
我正在回答这个问题,以防其他人有同样的问题。不确定这是唯一的方法,但我解决它的方法是使用反向代理。您也可以使用更强大的应用程序网关,但为了我的需要,我只需要反向代理。
我不得不重新创建我的服务结构(事后无法让它使用反向代理)。创建服务结构时选择反向代理。
注意:如果您想要 https,请先创建一个密钥保管库并添加两个证书。在证书页面上选择“自定义”并为集群和反向代理使用不同的。如果您使用相同的 Azure 部署失败。
还要至少选择一台 D1_s2 大小的机器,否则 Azure 在部署时会无限期挂起,并且不会告诉您任何信息。在这之后我没有头发了。
当您调用反向代理时,您指定结构和服务:
https://.eastus2.cloudapp.azure.com:19081/MyFabric/MyService/Controller/route
从一个服务到另一个服务时,您可以使用 localhost:19081 而不是 url。
在您的 servicemanifest.xml 中设置端点,例如:
<Resources>
<Endpoints>
<Endpoint Protocol="http" UriScheme="http" Name="EndpointHttp" Type="Input" />
</Endpoints>
</Resources>
代理知道发送到哪里。我设置了一个将请求转发到代理的应用程序管理 API。请注意,这是针对单个分区集群的。如果您有多个分区,则还需要在 url 中指定分区 ID。
https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reverseproxy
推荐阅读
- typescript - 创建在类型上定义的函数重载
- mysql - MySQL - 使用某些条件从每个组中使用一个值
- selenium - 如何使用 selenium WebDriver 单击没有定义 ID 的输入类型提交?
- c++ - 为什么范围不为非连续范围提供类型擦除视图?
- django - 如何通过电子邮件向用户 django 发送唯一链接,允许他们确认活动的可用性(以及更新数据库)
- javascript - TypeORM:使用 SQLITE 运行迁移时不创建数据库表
- json - 修改 JSON 对象数组
- javascript - 如何为排序数组设置动画?
- shell - 在 ansible jinja 模板中使用 shell 参数
- swift - SwiftUI 中表单的间距问题