NET6+Ocelot+Consul遇到问题:不知道这样的主机(Name or service not known)

环境

Ocelot Nuget:24.0.1
Consul Version:1.18.1+
.NET SDK:6.0.425

问题简介

本地调试时API应用服务注册及健康检查没有问题,直接访问也能成功,但是通过Ocelot Getway访问后出现 不知道这样的主机([node.name]:[port]) 问题。将服务全部以Docker部署也存在相同的问题 Name or service not known([node.name]:[port]),具体异常如下图所示。
服务注册及健康检查正常:
image

本地调试时通过网关访问异常:
image

以Docker部署通过网关访问异常:
image

问题解决

Ocelot对于Consul的服务发现机制默认优先取节点名,如果为null则取服务注册时的地址(ServiceAddress)。
所以有以下解决方式:

方式一

修改Consul节点名为IP,运行命令中使用-node=[ip]进行指定即可

点击查看(Consul命令中指定节点名为IP)
docker run -id \
  --name=ladder_consul \
  -p 8300:8300 \
  -p 8301:8301 \
  -p 8302:8302 \
  -p 8500:8500 \
  -p 8600:8600 \
  -v consul-data:/consul/data \
  hashicorp/consul agent \
  -server \
  -ui \
  -node=<your ip> \ #设置节点名为你的ip
  -bootstrap-expect=1 \
  -client=0.0.0.0 \
  -datacenter=ladder_dc1

方式二

Ocelot中增加自定义ConsulServiceBuilder,重写GetDownstreamHost方法,让其直接获取Service.Address而不是优先获取节点名称

点击查看(增加自定义ConsulServiceBuilder)
using Consul;
using Ocelot.Logging;
using Ocelot.Provider.Consul.Interfaces;

namespace OcelotDemo.Gateway;

public class CustomConsulServiceBuilder : DefaultConsulServiceBuilder
{
    public CustomConsulServiceBuilder(
        IHttpContextAccessor contextAccessor,
        IConsulClientFactory clientFactory,
        IOcelotLoggerFactory loggerFactory) : base(contextAccessor, clientFactory, loggerFactory)
    {
    }

    protected override string GetDownstreamHost(ServiceEntry entry, Node node)
    {
        return entry.Service.Address;
    }
}

Program.cs里注册Consul时使用
builder.Services.AddOcelot().AddConsul<CustomConsulServiceBuilder>();

问题分析

默认情况下builder.Services.AddOcelot().AddConsul();使用的是DefaultConsulServiceBuilder类,查看其GetDownstreamHost方法的实现确实是先取的node.Name,所以修改Consul的节点名称为IP或者自定义ConsulServiceBuilder类来重写该方法可解决。
image

参考文章记录

Ocelot项目中Consul服务发现的最佳实践与自定义配置

至此本次分享就结束了,希望这些能帮助到您,如文中内容有误或者您有其他看法,还望在评论区指正或讨论。
END

posted @ 2025-07-25 14:01  AND1云梯  阅读(579)  评论(0)    收藏  举报