A reverse proxy is a server that sits in fronts of one or more backend servers and handles requests from clients on behalf of those servers.
A reverse proxy provides several benefits:
- Routing
- Load balancing
- Scalability: By distributing traffic across multiple serves, a reverse proxy helps scale apps to handle more users and higher loads.
- SSL/TLS Termination
- Incoming URLs can be transformed before forwarding to the backend. Internal service endpoints can change without affecting external URLs.
- Security: Internal service endpoints can be hidden from external exposure.
- Caching
# YARP
## 1. Load Balancing
Load balancing policies are registered in the DI container via the
AddLoadBalancingPolicies()method, which is automatically called byAddReverseProxy(). The middleware is added withUseLoadBalancing, which is included by default in the parameterlessMapReverseProxymethod. ### Cluster Configuration The algorithm used to determine the destination can be configured by setting theLoadBalancingPolicy. If no policy is specified,PowerOfTwoChoiceswill be used. Built-in policies: - FirstAlphabetical
- Random
- PowerOfTwoChoices (default)
- RoundRobin
- LeastRequests
"ReverseProxy": {
"Clusters": {
"cluster1": {
"LoadBalancingPolicy": "RoundRobin",
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10000/"
},
"cluster1/destination2": {
"Address": "https://localhost:10010/"
}
}
}
}
}
2. Session Affinity
Session affinity is a mechanism to bind a causally related request sequence to the destination that handled the first request when the load is balanced among several destinations.
What is an Affinity Key
In YARP, an Affinity Key is simply the identifier that ties a client's subsequent requests to the same backend destination.
- The key itself is just a container name.
- The value stored inside that key is generated dynamically by YARP at runtime and is different for each client or session.
- This value encodes the target destination ID - or sometimes a group of destinations - so that the proxy knows where to route the next request. ### Affinity failure policy
- Redistribute (default)- tries to establish a new affinity to one of available healthy destinations by skipping the affinity lookup step and passing all healthy destination to the load balancer the same way it is done for a request without any affinity.
-
Return503Error - send a
503response back to the client and request processing is terminated. ## 3. Destination health checks ### Active health checks YARP can proactively monitor destination health by sending periodic probing requests to designated health endpoints and analyzing responses.
"Clusters": {
"cluster1": {
"HealthCheck": {
"Active": {
"Enabled": "true",
"Interval": "00:00:10",
"Timeout": "00:00:10",
"Policy": "ConsecutiveFailures",
"Path": "/api/health",
"Query": "?foo=bar"
}
},
"Metadata": {
"ConsecutiveFailuresHealthPolicy.Threshold": "3"
},
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10000/"
},
"cluster1/destination2": {
"Address": "http://localhost:10010/",
"Health": "http://localhost:10020/"
}
}
}
}
Passive health checks
YARP can passively watch for successes and failures in client request proxying to reactively evaluate destination health states.
"Clusters": {
"cluster1": {
"HealthCheck": {
"Passive": {
"Enabled": "true",
"Policy": "TransportFailureRate",
"ReactivationPeriod": "00:02:00"
}
},
"Metadata": {
"TransportFailureRateHealthPolicy.RateLimit": "0.5"
},
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10000/"
},
"cluster1/destination2": {
"Address": "http://localhost:10010/"
}
}
}
}
When a destination gets marked as unhealthy, it stops receiving new requests until it gets reactivated after a configured period.
4. Rate Limiting
The reverse proxy can be used to rate-limit requests before they are proxied to the destination servers. This can reduce load on the destination servers, add a layer of protection, and ensure consistent policies are implemented across your applications.
Global Limiter
globalLimiter is an illustration here, we need to implement it by ourself.
services.AddRateLimiter(options => options.GlobalLimiter = globalLimiter);
Route Limiter
Rate limiter policies can be specified per route.
{
"ReverseProxy": {
"Routes": {
"route1" : {
"ClusterId": "cluster1",
"RateLimiterPolicy": "customPolicy",
"Match": {
"Hosts": [ "localhost" ]
}
}
},
"Clusters": {
"cluster1": {
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10001/"
}
}
}
}
}
}
RateLimiter policies can be configured in services as follows:
services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("customPolicy", opt =>
{
opt.PermitLimit = 4;
opt.Window = TimeSpan.FromSeconds(12);
opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
opt.QueueLimit = 2;
});
});
Then add the RateLimiter middleware:
app.UseRateLimiter();
app.MapReverseProxy();
Disable Rate Limiting
Specifying the value disable in a route's RateLimiterPolicy parameter means the rate limiter middleware will not apply any policies to this route, even the default policy.
Top comments (0)