You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Service Fabric中如何从一个节点调用其他所有节点的端点

问题:Service Fabric无状态服务跨实例调用ASP.NET端点失败

我在使用Service Fabric无状态服务时,需要从某个服务实例调用其他所有实例的ASP.NET端点。尝试通过获取所有节点的node.IpAddressOrFQDN,直接向服务端口发起HTTP请求或通过DNS调用,但均失败,求解决方法。

尝试1:直接调用指定端口和端点的代码

FabricClient fabricClient = new FabricClient();
NodeList nodes = await fabricClient.QueryManager.GetNodeListAsync();
foreach (Node node in nodes) 
{ 
    var nodeIpAddr = node.IpAddressOrFQDN;
    string httpAddress = $"http://{nodeIpAddr}:<port>/api/endpoint";
    string httpsAddress = $"https://{nodeIpAddr}:<port>/api/endpoint";
    HttpClient client = new HttpClient();
    var responseA = await client.GetAsync(httpsAddress);
    var responseB = await client.GetAsync(httpAddress);
}
return Ok();

尝试2:通过DNS调用的代码

FabricClient fabricClient = new FabricClient();
NodeList nodes = await fabricClient.QueryManager.GetNodeListAsync();
foreach (Node node in nodes) 
{ 
    var nodeIpAddr = node.IpAddressOrFQDN;
    string httpAddress = $"http://{nodeIpAddr}:19081/Service/Application/api/endpoint";
    string httpsAddress = $"https://{nodeIpAddr}:19081/Service/Application/api/endpoint";
    HttpClient client = new HttpClient();
    var responseA = await client.GetAsync(httpsAddress);
    var responseB = await client.GetAsync(httpAddress);
}
return Ok();

遇到的错误

HTTPS调用异常

Error: The SSL connection could not be established, see inner exception. The SSL connection could not be established, see inner exception.    at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)

HTTP调用响应

StatusCode: 404, ReasonPhrase: 'FABRIC_E_ENDPOINT_NOT_FOUND', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
  Server: Microsoft-HTTPAPI/2.0
  Date: Wed, 08 Jan 2025 13:45:29 GMT
  Content-Length: 0
}

解决方案

1. 通过Service Fabric服务发现获取实例端点

不要遍历所有节点,直接查询服务的所有实例及其端点,这是最可靠的方式:

FabricClient fabricClient = new FabricClient();
// 替换为你的服务名称,格式为 fabric:/<应用名>/<服务名>
var serviceName = new Uri("fabric:/MyApplication/MyStatelessService");
var serviceInstances = await fabricClient.QueryManager.GetServiceInstanceListAsync(serviceName);

foreach (var instance in serviceInstances)
{
    // 筛选出HTTP/HTTPS类型的端点
    var targetEndpoint = instance.Endpoints.FirstOrDefault(e => 
        e.Protocol == EndpointProtocol.Http || e.Protocol == EndpointProtocol.Https);
    
    if (targetEndpoint != null)
    {
        string requestUrl = $"{targetEndpoint.Protocol.ToString().ToLower()}://{targetEndpoint.Address}/api/endpoint";
        using (HttpClient client = new HttpClient())
        {
            // 处理HTTPS证书验证(测试环境临时方案,生产环境禁用)
            if (targetEndpoint.Protocol == EndpointProtocol.Https)
            {
                var handler = new HttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
                client = new HttpClient(handler);
            }
            
            var response = await client.GetAsync(requestUrl);
            // 根据业务需求处理响应结果
        }
    }
}

说明:这种方式直接获取每个服务实例的实际运行端点,避免了节点上无服务实例的无效请求,也不需要手动拼接端口或路径。

2. 修复DNS调用的格式问题

Service Fabric的DNS访问格式并非节点IP+19081,正确的无状态服务实例DNS格式为:
http://<服务名>_<实例ID>.<应用名>.cluster.local:<端口>/api/endpoint
其中<服务名>、<实例ID>、<应用名>需要替换为你的实际信息,端口为服务端点配置的端口。

3. HTTPS问题处理

  • 生产环境:确保服务使用的SSL证书已被调用方信任,证书的Subject或SAN字段包含服务实例的访问地址。
  • 测试环境:可临时使用代码中的证书验证跳过逻辑,但生产环境必须使用合法的信任证书。

关键注意事项

  • 避免遍历所有节点:节点上可能未部署目标服务实例,会导致大量无效请求。
  • 复用HttpClient:频繁创建销毁HttpClient会导致资源浪费,建议使用单例或复用实例。
  • 动态刷新端点:服务实例可能会扩容、迁移,需定期刷新端点列表以保证有效性。

内容的提问来源于stack exchange,提问作者AAYUSH SHANDILYA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:50:15