Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix up xref issues, and remove section #40434

Merged
merged 4 commits into from
Apr 10, 2024
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 33 additions & 34 deletions docs/core/extensions/service-discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Service discovery in .NET
description: Learn how to use the Microsoft.Extensions.ServiceDiscovery library to simplify the integration of service discovery patterns in .NET applications.
author: IEvangelist
ms.author: dapine
ms.date: 12/11/2023
ms.date: 04/10/2024
ms.topic: overview
---

Expand Down Expand Up @@ -34,20 +34,20 @@ For more information, see [dotnet add package](../tools/dotnet-add-package.md) o

## Example usage

In the _Program.cs_ file of your project, call the <xref:Microsoft.Extensions.Hosting.HostingExtensions.AddServiceDiscovery%2A> extension method to add service discovery to the host, configuring default service endpoint resolvers:
In the _Program.cs_ file of your project, call the <xref:Microsoft.Extensions.DependencyInjection.ServiceDiscoveryHttpClientBuilderExtensions.AddServiceDiscovery%2A> extension method to add service discovery to the host, configuring default service endpoint resolvers:

```csharp
builder.Services.AddServiceDiscovery();
```

Add service discovery to an individual <xref:Microsoft.Extensions.DependencyInjection.IHttpClientBuilder> by calling the `UseServiceDiscovery` extension method:
Add service discovery to an individual <xref:Microsoft.Extensions.DependencyInjection.IHttpClientBuilder> by calling the `AddServiceDiscovery` extension method:

```csharp
builder.Services.AddHttpClient<CatalogServiceClient>(static client =>
{
client.BaseAddress = new("http://catalog");
client.BaseAddress = new("https://catalog");
})
.UseServiceDiscovery();
.AddServiceDiscovery();
```

Alternatively, you can add service discovery to all <xref:System.Net.Http.HttpClient> instances by default:
Expand All @@ -60,6 +60,27 @@ builder.Services.ConfigureHttpClientDefaults(static http =>
});
```

## Scheme selection when resolving HTTP(S) endpoints

It is common to use HTTP while developing and testing a service locally and HTTPS when the service is deployed. Service Discovery supports this by allowing for a priority list of URI schemes to be specified in the input string given to Service Discovery. Service Discovery will attempt to resolve the services for the schemes in order and will stop after an endpoint is found. URI schemes are separated by a `+` character, for example: `"https+http://basket"`. Service Discovery will first try to find HTTPS endpoints for the `"basket"` service and will then fall back to HTTP endpoints. If any HTTPS endpoint is found, Service Discovery will not include HTTP endpoints.

Schemes can be filtered by configuring the `AllowedSchemes` and `AllowAllSchemes` properties on `ServiceDiscoveryOptions`. The `AllowAllSchemes` property is used to indicate that all schemes are allowed. By default, `AllowAllSchemes` is `true` and all schemes are allowed. Schemes can be restricted by setting `AllowAllSchemes` to `false` and adding allowed schemes to the `AllowedSchemes` property. For example, to allow only HTTPS:

```csharp
services.Configure<ServiceDiscoveryOptions>(options =>
{
options.AllowAllSchemes = false;
options.AllowedSchemes = ["https"];
});
```

To explicitly allow all schemes, set the `ServiceDiscoveryOptions.AllowAllSchemes` property to `true`:

```csharp
services.Configure<ServiceDiscoveryOptions>(
options => options.AllowAllSchemes = true);
```

## Resolve service endpoints from configuration

The `AddServiceDiscovery` extension method adds a configuration-based endpoint resolver by default.
Expand All @@ -70,21 +91,23 @@ Here's an example demonstrating how to configure endpoints for the service named
```json
{
"Services": {
"https": {
"catalog": [
"localhost:8080",
"10.46.24.90:80",
"10.46.24.90:80"
]
}
}
}
```

The preceding example adds two endpoints for the service named _catalog_: `localhost:8080`, and `"10.46.24.90:80"`. Each time the _catalog_ is resolved, one of these endpoints is selected.
The preceding example adds two endpoints for the service named _catalog_: `https://localhost:8080`, and `"https://10.46.24.90:80"`. Each time the _catalog_ is resolved, one of these endpoints is selected.

If service discovery was added to the host using the <xref:Microsoft.Extensions.Hosting.HostingExtensions.AddServiceDiscoveryCore%2A> extension method on <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection>, the configuration-based endpoint resolver can be added by calling the <xref:Microsoft.Extensions.Hosting.HostingExtensions.AddConfigurationServiceEndPointResolver%2A> extension method on `IServiceCollection`.
If service discovery was added to the host using the <xref:Microsoft.Extensions.DependencyInjection.ServiceDiscoveryServiceCollectionExtensions.AddServiceDiscoveryCore%2A> extension method on <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection>, the configuration-based endpoint resolver can be added by calling the <xref:Microsoft.Extensions.DependencyInjection.ServiceDiscoveryServiceCollectionExtensions.AddConfigurationServiceEndPointResolver%2A> extension method on `IServiceCollection`.

### Configuration

The configuration resolver is configured using the <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.ConfigurationServiceEndPointResolverOptions> class, which offers these configuration options:
The configuration resolver is configured using the <xref:Microsoft.Extensions.ServiceDiscovery.ConfigurationServiceEndPointResolverOptions> class, which offers these configuration options:

- **SectionName**: The name of the configuration section that contains service endpoints. It defaults to `"Services"`.

Expand Down Expand Up @@ -120,31 +143,7 @@ The pass-through resolver performs no external resolution and instead resolves e

The pass-through provider is configured by-default when adding service discovery via the `AddServiceDiscovery` extension method.

If service discovery was added to the host using the `AddServiceDiscoveryCore` extension method on `IServiceCollection`, the pass-through provider can be added by calling the <xref:Microsoft.Extensions.Hosting.HostingExtensions.AddPassThroughServiceEndPointResolver%2A> extension method on `IServiceCollection`.

## Load-balancing with endpoint selectors

Each time an endpoint is resolved via the `HttpClient` pipeline, a single endpoint is selected from the set of all known endpoints for the requested service. If multiple endpoints are available, it may be desirable to balance traffic across all such endpoints. To accomplish this, a customizable _endpoint selector_ can be used. By default, endpoints are selected in round-robin order. To use a different endpoint selector, provide an <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.IServiceEndPointSelector> instance to the <xref:Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.UseServiceDiscovery%2A> method call. For example, to select a random endpoint from the set of resolved endpoints, specify <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.RandomServiceEndPointSelectorProvider.Instance?displayProperty=nameWithType> as the endpoint selector:

```csharp
builder.Services.AddHttpClient<CatalogServiceClient>(
static client => client.BaseAddress = new("http://catalog")
)
.UseServiceDiscovery(RandomServiceEndPointSelectorProvider.Instance);
```

The `Microsoft.Extensions.ServiceDiscovery` package includes the following endpoint selector providers:

- <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.PickFirstServiceEndPointSelectorProvider.Instance?displayProperty=nameWithType>: Pick-first, which always selects the first endpoint.
- <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.RoundRobinServiceEndPointSelectorProvider.Instance?displayProperty=nameWithType>: Round-robin, which cycles through endpoints.
- <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.RandomServiceEndPointSelectorProvider.Instance?displayProperty=nameWithType>: Random, which selects endpoints randomly.
- <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.PowerOfTwoChoicesServiceEndPointSelectorProvider.Instance?displayProperty=nameWithType>: Power-of-two-choices, which attempt to pick the least used endpoint based on the _Power of Two Choices_ algorithm for distributed load balancing, degrading to randomly selecting an endpoint when either of the provided endpoints don't have the <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.IEndPointLoadFeature> feature.

Endpoint selectors are created via an <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.IServiceEndPointSelectorProvider> instance, such as the providers previously listed. The provider's <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.IServiceEndPointSelectorProvider.CreateSelector> method is called to create a selector, which is an instance of <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.IServiceEndPointSelector>. The `IServiceEndPointSelector` instance is given the set of known endpoints when they're resolved, using the <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.IServiceEndPointSelector.SetEndPoints%2A?displayProperty=nameWithType> method. To choose an endpoint from the collection, the <xref:Microsoft.Extensions.ServiceDiscovery.Abstractions.IServiceEndPointSelector.GetEndPoint%2A?displayProperty=nameWithType> method is called, returning a single `ServiceEndPoint`. The `context` value passed to `GetEndPoint` is used to provide extra context that may be useful to the selector. For example, in the `HttpClient` case, the <xref:System.Net.Http.HttpRequestMessage> is passed. None of the provided implementations of `IServiceEndPointSelector` inspect the context, and it can be ignored unless you're using a selector, which does make use of it.

### Resolution order

When service endpoints are being resolved, each registered resolver is called in the order of registration and given the opportunity to modify the collection of `ServiceEndPoint`s which are returned back to the caller. The providers included in the `Microsoft.Extensions.ServiceDiscovery` series of packages skip resolution if there are existing endpoints in the collection when they're called. For example, consider a case where the following providers are registered: _Configuration_, _DNS SRV_, _Pass-through_. When resolution occurs, the providers are called in-order. If the _Configuration_ providers discover no endpoints, the _DNS SRV_ provider performs resolution and may add one or more endpoints. If the _DNS SRV_ provider adds an endpoint to the collection, the _Pass-through_ provider skips its resolution and returns immediately instead.
If service discovery was added to the host using the `AddServiceDiscoveryCore` extension method on `IServiceCollection`, the pass-through provider can be added by calling the <xref:Microsoft.Extensions.DependencyInjection.ServiceDiscoveryServiceCollectionExtensions.AddPassThroughServiceEndPointResolver%2A> extension method on `IServiceCollection`.

## See also

Expand Down
Loading