Skip to content

Commit

Permalink
Fix up xref issues, and remove section (#40434)
Browse files Browse the repository at this point in the history
* Fix up xref issues, and remove section

* More fixes and corrections

* Fix last UseServiceDiscovery
  • Loading branch information
IEvangelist authored Apr 10, 2024
1 parent 09afefc commit 2c1b7aa
Showing 1 changed file with 35 additions and 36 deletions.
71 changes: 35 additions & 36 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 @@ -56,10 +56,31 @@ Alternatively, you can add service discovery to all <xref:System.Net.Http.HttpCl
builder.Services.ConfigureHttpClientDefaults(static http =>
{
// Turn on service discovery by default
http.UseServiceDiscovery();
http.AddServiceDiscovery();
});
```

## 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": {
"catalog": [
"catalog": {
"https": [
"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

0 comments on commit 2c1b7aa

Please sign in to comment.