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]),具体异常如下图所示。
服务注册及健康检查正常:

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

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

问题解决
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类来重写该方法可解决。

参考文章记录
Ocelot项目中Consul服务发现的最佳实践与自定义配置
至此本次分享就结束了,希望这些能帮助到您,如文中内容有误或者您有其他看法,还望在评论区指正或讨论。
END

浙公网安备 33010602011771号