Replies: 5 comments 3 replies
-
@NullRefer Paddi,
You have to provide full call stack of the exception from debug session. Or, at least full text of the error message! |
Beta Was this translation helpful? Give feedback.
-
Aha-hah! LoL! Young people asks ChatGPT how to live, and how to work... That's really funny! 🤣 @ggnaegi FYI To have a fun... 😉 |
Beta Was this translation helpful? Give feedback.
-
@NullRefer Based on IP address you want to route traffic to different hosts... Also some mix of Ocelot Routing feature (path template placeholders), but I believe placeholders must work with Service Discovery feature. So, I see 2 possible solutions:
If you will find some interesting and popular Service Discovery product, we can integrate it to Ocelot as separate service discovery provider. So, we are open to your PRs/issues. |
Beta Was this translation helpful? Give feedback.
-
You cannot change it! This config being generated by ChatGPT is absolutely incorrect! "RouteClaimsRequirement": {
"sourceIp": "ip1|ip2"
} The RouteClaimsRequirement property of route configuration is used for Authorization feature only! Finally, |
Beta Was this translation helpful? Give feedback.
-
@NullRefer Hello Paddi, I'm not sure I understand what you're trying to achieve. Do both services offer the same functionalities? If so, using Load Balancing with consul is a good strategy, but you will need a consul instance and to register your services to consul. var consulClient = CreateConsulClient(serviceDiscoveryConfig);
services.AddSingleton<IConsulClient, ConsulClient>(p => consulClient);
...
private static ConsulClient CreateConsulClient(ServiceDiscoveryConfig serviceConfig)
{
return new ConsulClient(config => { config.Address = serviceConfig.ServiceDiscoveryAddress; });
}
...
var registrationId = $"{_config.Value.ServiceName}-{_config.Value.ServiceId}";
var registration = new AgentServiceRegistration
{
ID = registrationId,
Name = _config.Value.ServiceName,
Address = _config.Value.ServiceAddress.Host,
Port = _config.Value.ServiceAddress.Port,
Check = new AgentCheckRegistration
{
HTTP =
$"{_config.Value.ServiceAddress.Scheme}://{_config.Value.ServiceAddress.Host}:{_config.Value.ServiceAddress.Port}/{_config.Value.HealthCheckPath}",
Interval = TimeSpan.FromSeconds(10)
}
};
await _client.Agent.ServiceRegister(registration, cancellationToken); Then you need to implement your own Load Balancer using the ILoadBalancer and ILoadBalancerCreator interfaces. In your implementation, there's a method called Lease whose parameter is the HttpContext and the list of available services as a local variable. Using HttpContext.Connection.RemoteIpAddress?.ToString(), you can obtain the source IP, and then depending on the IP, return the appropriate service. public class CustomLoadBalancer : ILoadBalancer
{
private readonly Func<Task<List<Service>>> _services;
public CustomLoadBalancer(Func<Task<List<Service>>> services)
{
_services = services ?? throw new ArgumentNullException(nameof(services));
}
public async Task<Response<ServiceHostAndPort>> Lease(HttpContext httpContext)
{
var services = await _services();
if (services == null || services.Count == 0)
{
return new ErrorResponse<ServiceHostAndPort>(new ServicesAreEmptyError("There were no services in CustomLoadBalancer"));
}
var service = services.First(x => x.Id == "my-order2-webapi-service");
if (httpContext.Connection.RemoteIpAddress?.ToString() != "192.168.1.20")
{
return new OkResponse<ServiceHostAndPort>(service.HostAndPort);
}
service = services.First(x => x.Id == "my-order1-webapi-service");
return new OkResponse<ServiceHostAndPort>(service.HostAndPort);
}
public void Release(ServiceHostAndPort hostAndPort)
{
throw new NotImplementedException();
}
} As for the LoadBalancerCreator: using Ocelot.Configuration;
using Ocelot.Responses;
using Ocelot.ServiceDiscovery.Providers;
namespace Ocelot.LoadBalancer.LoadBalancers;
public class CustomLoadBalancerCreator : ILoadBalancerCreator
{
public string Type => nameof(CustomLoadBalancer);
public Response<ILoadBalancer> Create(DownstreamRoute route, IServiceDiscoveryProvider serviceProvider)
{
return new OkResponse<ILoadBalancer>(new CustomLoadBalancer(async () => await serviceProvider.GetAsync()));
}
} I reckon, you could even just return two services in CustomLoadBalancerCreator instead of calling serviceProvider.GetAsync... and you could avoid using consul or another service discovery... I'm not sure though. Services.AddSingleton<ILoadBalancerCreator, CustomLoadBalancerCreator>(); If the features aren't the same, then I don't understand why you want to use the same route... 😸 |
Beta Was this translation helpful? Give feedback.
-
Hello, I'm using Ocelot as API gateway. And I'm encountering a situation.
As for same UpstreamPathTemplate, I need to proxy it to difference backend service base on request ip address.
Given current configuration
If ip1, ip2 request for GET /order/1, it goes to my-order1-webapi-service;
If ip3, ip4 request for GET /order/1, it goes to my-order2-webapi-service;
And the other requests go to my-order-webapi-service.
I ask for ChatGPT, it give me an configuration of below. But ocelot starts with exception that /order{catchall} has duplicate.
How could I change my configuration to solve it?
Specifications
Beta Was this translation helpful? Give feedback.
All reactions