Skip to content

Commit 2995a41

Browse files
authored
Update the "Use Consul as a membership provider" content (#35321)
* Edit pass * More updates to the consul bits
1 parent c520d5b commit 2995a41

File tree

4 files changed

+96
-92
lines changed

4 files changed

+96
-92
lines changed
Lines changed: 56 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,184 +1,148 @@
11
---
22
title: Use Consul as a membership provider
33
description: Learn how to use Consul as a membership provider in .NET Orleans.
4-
ms.date: 03/09/2022
4+
ms.date: 05/12/2023
55
---
66

77
# Use Consul as a membership provider
88

9-
[Consul](https://www.consul.io) is a distributed, highly available, and datacenter-aware service discovery platform that includes simple service registration, health checking, failure detection, and key/value storage. It is built on the premise that every node in the data center is running a Consul agent which is either acting as a server or client which communicates via a scalable gossip protocol.
9+
[Consul](https://www.consul.io) is a distributed, highly available, and data center-aware service discovery platform that includes simple service registration, health checking, failure detection, and key-value storage. It's built on the premise that every node in the data center is running a Consul agent that is either acting as a server or client. Each agent communicates via a scalable gossip protocol.
1010

11-
There is a very detailed overview of Consul including comparisons with similar solutions [here](https://www.consul.io/intro/index.html).
11+
There's a detailed overview of Consul including comparisons with similar solutions [here](https://www.consul.io/intro/index.html).
1212

13-
Consul is written in Go and is [open source](https://github.com/hashicorp/consul); compiled downloads are available for [Mac OS X, FreeBSD, Linux, Solaris and Windows](https://www.consul.io/downloads.html)
13+
Consul is written in [Go](https://go.dev) and is [open source](https://github.com/hashicorp/consul); compiled downloads are available for [macOS X, FreeBSD, Linux, Solaris and Windows](https://www.consul.io/downloads.html)
1414

1515
## Why choose Consul?
1616

17-
As an [Orleans Membership Provider](../implementation/cluster-management.md), Consul is a good choice when you need to deliver an on-premise solution that does not require your potential customers to have existing infrastructure and a cooperative IT provider. Consul is a very lightweight single executable, has no dependencies, and as such can easily be built into your middleware solution. And when Consul is already your solution for discovering, checking, and maintaining your microservices, it makes sense to fully integrate with Orleans membership for simplicity and ease of operation. We, therefore, implemented a membership table in Consul (also known as "Orleans Custom System Store"), which fully integrates with Orleans's [Cluster Management](../implementation/cluster-management.md).
17+
As an [Orleans Membership Provider](../implementation/cluster-management.md), Consul is a good choice when you need to deliver an on-premises solution that doesn't require your potential customers to have existing infrastructure and a cooperative IT provider. Consul is a lightweight single executable, has no dependencies, and as such can easily be built into your middleware solution. When Consul is your solution for discovering, checking, and maintaining your microservices, it makes sense to fully integrate with Orleans membership for simplicity and ease of operation. There also exists a membership table in Consul (also known as "Orleans Custom System Store"), which fully integrates with Orleans's [Cluster Management](../implementation/cluster-management.md).
1818

1919
## Set up Consul
2020

2121
There's extensive documentation available on [Consul.io](https://www.consul.io) about setting up a stable Consul cluster, and it doesn't make sense to repeat that here. However, for your convenience, we include this guide so you can quickly get Orleans running with a standalone Consul agent.
2222

23-
1. Create a folder to install Consul into, (for example _C:\Consul_).
24-
1. Create a subfolder: _C:\Consul\Data_ (Consul will not create this if it doesn't exist).
23+
1. Create a folder to install Consul into (for example _C:\Consul_).
24+
1. Create a subfolder: _C:\Consul\Data_ (Consul doesn't create this directory if it doesn't exist).
2525
1. [Download](https://www.consul.io/downloads.html) and unzip _Consul.exe_ into _C:\Consul_.
2626
1. Open a command prompt at _C:\Consul_ and run the following command:
2727

2828
```powershell
29-
Consul.exe agent -server -bootstrap -data-dir "C:\Consul\Data" -client=0.0.0.0
29+
./consul.exe agent -server -bootstrap -data-dir "C:\Consul\Data" -client='0.0.0.0'
3030
```
3131
3232
In the preceding command:
3333
34-
- `agent` Instructs Consul to run the agent process that hosts the services. Without this, the Consul process will attempt to use RPC to configure a running agent.
35-
- `-server` Defines the agent as a server and not a client (A Consul _client_ is an agent that hosts all the services and data, but does not have voting rights to decide, and cannot become, the cluster leader.
36-
- `-bootstrap` The first (and only the first!) node in a cluster must be bootstrapped so that it assumes the cluster leadership.
37-
- `-data-dir [path]` Specifies the path where all Consul data is stored, including the cluster membership table.
38-
- `-client=0.0.0.0` Informs Consul which IP to open the service on.
34+
- `agent`: Instructs Consul to run the agent process that hosts the services. Without this switch, the Consul process attempts to use RPC to configure a running agent.
35+
- `-server`: Defines the agent as a server and not a client (A Consul _client_ is an agent that hosts all the services and data, but doesn't have voting rights to decide, and can't become, the cluster leader.
36+
- `-bootstrap`: The first (and only the first!) node in a cluster must be bootstrapped so that it assumes the cluster leadership.
37+
- `-data-dir [path]`: Specifies the path where all Consul data is stored, including the cluster membership table.
38+
- `-client='0.0.0.0'`: Informs Consul which IP to open the service on.
3939
40-
There are many other parameters, and the option to use a JSON configuration file. Please consult the Consul documentation for a full listing of the options.
40+
There are many other parameters, and the option to use a JSON configuration file. Consult the Consul documentation for a full listing of the options.
4141
42-
1. Verify that Consul is running and ready to accept membership requests from Orleans by opening the services endpoint in your browser at `http://localhost:8500/v1/catalog/services`.
42+
1. Verify that Consul is running and ready to accept membership requests from Orleans by opening the services endpoint in your browser at <http://localhost:8500/v1/catalog/services>, when functioning correctly the browser should display the following JSON:
4343
44-
## Configure Orleans
45-
46-
There is a known issue with the "Custom" membership provider _OrleansConfiguration.xml_ configuration file that will fail to parse correctly. For this reason, you have to provide a placeholder SystemStore in the XML and then configure the provider in code before starting the silo.
47-
48-
**OrleansConfiguration.xml**
49-
50-
```xml
51-
<OrleansConfiguration xmlns="urn:orleans">
52-
<Globals>
53-
<SystemStore SystemStoreType="None"
54-
DataConnectionString="http://localhost:8500"
55-
DeploymentId="MyOrleansDeployment" />
56-
</Globals>
57-
<Defaults>
58-
<Networking Address="localhost" Port="22222" />
59-
<ProxyingGateway Address="localhost" Port="30000" />
60-
</Defaults>
61-
</OrleansConfiguration>
62-
```
63-
64-
**Code**
65-
66-
```csharp
67-
public void Start(ClusterConfiguration config)
68-
{
69-
_siloHost = new SiloHost(System.Net.Dns.GetHostName(), config);
44+
```json
45+
{
46+
"consul": []
47+
}
48+
```
7049
71-
_siloHost.Config.Globals.LivenessType =
72-
GlobalConfiguration.LivenessProviderType.Custom;
73-
_siloHost.Config.Globals.MembershipTableAssembly =
74-
"OrleansConsulUtils";
75-
_siloHost.Config.Globals.ReminderServiceType =
76-
GlobalConfiguration.ReminderServiceProviderType.Disabled;
50+
## Configure Orleans
7751
78-
_siloHost.InitializeOrleansSilo();
52+
To configure Orleans to use Consul as a membership provider, your silo project will need to reference the [Microsoft.Orleans.Clustering.Consul](https://www.nuget.org/packages/Microsoft.Orleans.Clustering.Consul) NuGet package. Once you've done that, you can configure the membership provider in your silo's _Program.cs_ file as follows:
7953
80-
var started = _siloHost.StartOrleansSilo();
81-
if (started is false)
82-
{
83-
throw new SystemException(
84-
$"Failed to start Orleans silo '{_siloHost.Name}' as a {_siloHost.Type} node");
85-
}
86-
}
87-
```
54+
:::code source="snippets/consul/Silo/Program.cs":::
8855
89-
Alternatively, you could configure the silo entirely in code. The client configuration is much simpler:
56+
The preceding code:
9057
91-
**ClientConfiguration.xml**
58+
- Creates a <xref:Microsoft.Extensions.Hosting.IHostBuilder> with defaults from the <xref:Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder?displayProperty=nameWithType>.
59+
- Chains a call to <xref:Microsoft.Extensions.Hosting.GenericHostExtensions.UseOrleans(Microsoft.Extensions.Hosting.IHostBuilder,System.Action{Microsoft.Extensions.Hosting.HostBuilderContext,Orleans.Hosting.ISiloBuilder})> which configures the Orleans silo.
60+
- Given the <xref:Orleans.Hosting.ISiloBuilder> calls <xref:Orleans.Hosting.ConsulUtilsHostingExtensions.UseConsulSiloClustering%2A>.
61+
- Configures the cluster membership provider to use Consul, given the Consul `address`.
9262
93-
```xml
94-
<ClientConfiguration xmlns="urn:orleans">
95-
<SystemStore SystemStoreType="Custom"
96-
CustomGatewayProviderAssemblyName="OrleansConsulUtils"
97-
DataConnectionString="http://192.168.1.26:8500"
98-
DeploymentId="MyOrleansDeployment" />
99-
</ClientConfiguration>
100-
```
63+
To configure the client, reference the same NuGet package and call the <xref:Orleans.Hosting.ConsulUtilsHostingExtensions.UseConsulClientClustering%2A> extension method.
10164
10265
## Client SDK
10366
104-
If you are interested in using Consul for your service discovery, there are [Client SDKs](https://www.consul.io/downloads_tools.html) for most popular languages.
67+
If you're interested in using Consul for your service discovery, there are [Client SDKs](https://www.consul.io/downloads_tools.html) for most popular languages.
10568
106-
## Implementation detail
69+
### Implementation detail
10770
108-
The Membership Table Provider makes use of [Consul's Key/Value store](https://www.consul.io/intro/getting-started/kv.html) functionality with Check-And-Set (CAS) operations. When each Silo starts, it registers two KV entries, one that contains the Silo details and one that holds the last time the Silo reported it was alive (the latter refers to diagnostics "I am alive" entries and not to failure detection heartbeats, which are sent directly between the silos and are not written into the table). All writes to the table are performed with CAS to provide concurrency control, as necessitated by Orleans's [Cluster Management Protocol](../implementation/cluster-management.md).
71+
The Membership Table Provider makes use of [Consul's Key/Value store](https://www.consul.io/intro/getting-started/kv.html) functionality with Check-And-Set (CAS) operations. When each Silo starts, it registers two key-value entries, one that contains the Silo details and one that holds the last time the Silo reported it was alive. The latter refers to diagnostics "I'm alive" entries and not to failure detection heartbeats, which are sent directly between the silos and aren't written into the table. All writes to the table are performed with CAS to provide concurrency control, as necessitated by Orleans's [Cluster Management Protocol](../implementation/cluster-management.md).
10972
110-
Once the Silo is running, you can view these entries in your web browser at `http://localhost:8500/v1/kv/?keys`, which will display something like:
73+
Once the Silo is running, you can view these entries in your web browser at <http://localhost:8500/v1/kv/?keys&pretty>, which displays something like:
11174
11275
```json
11376
[
114-
"orleans/MyOrleansDeployment/192.168.1.26:11111@191780753",
115-
"orleans/MyOrleansDeployment/192.168.1.26:11111@191780753/iamalive"
77+
"orleans/default/192.168.1.11:11111@43165319",
78+
"orleans/default/192.168.1.11:11111@43165319/iamalive",
79+
"orleans/default/version"
11680
]
11781
```
11882

119-
You'll notice that the keys are prefixed with `orleans`. This is hardcoded in the provider and is intended to avoid keyspace collision with other users of Consul. Each of these keys can be read by appending their key name (without quotes) to the Consul KV root at `http://localhost:8500/v1/kv/`. Doing so presents you with the following:
83+
All of the keys are prefixed with `orleans`, which is hard coded in the provider and is intended to avoid keyspace collision with other users of Consul. You can use any of these keys to retrieve additional information about Each of these keys can be read by appending their key name (without quotes) to the Consul KV root at `http://localhost:8500/v1/kv/`. Doing so presents you with the following JSON:
12084

12185
```json
12286
[
12387
{
12488
"LockIndex": 0,
125-
"Key": "orleans/MyOrleansDeployment/192.168.1.26:22222@191780753",
89+
"Key": "orleans/default/192.168.1.11:11111@43165319",
12690
"Flags": 0,
12791
"Value": "[BASE64 UTF8 Encoded String]",
128-
"CreateIndex": 10,
129-
"ModifyIndex": 12
92+
"CreateIndex": 321,
93+
"ModifyIndex": 322
13094
}
13195
]
13296
```
13397

134-
Decoding the string gives you the actual Orleans Membership data:
98+
Decoding the Base64 UTF-8 encoded string `Value` gives you the actual Orleans membership data:
13599

136-
**`http://localhost:8500/v1/KV/orleans/MyOrleansDeployment/[SiloAddress]`**
100+
**`http://localhost:8500/v1/KV/orleans/default/[SiloAddress]`**
137101

138102
```json
139103
{
140104
"Hostname": "[YOUR_MACHINE_NAME]",
141-
"ProxyPort": 22222,
142-
"StartTime": "2016-01-29T16:25:54.9538838Z",
105+
"ProxyPort": 30000,
106+
"StartTime": "2023-05-15T14:22:00.004977Z",
143107
"Status": 3,
108+
"SiloName": "Silo_fcad0",
144109
"SuspectingSilos": []
145110
}
146111
```
147112

148-
**`http://localhost:8500/v1/KV/orleans/MyOrleansDeployment/[SiloAddress]/IAmAlive`**
113+
**`http://localhost:8500/v1/KV/orleans/default/[SiloAddress]/IAmAlive`**
149114

150115
```plaintext
151-
2016-01-29T16:35:58.9193803Z
116+
"2023-05-15T14:27:01.1832828Z"
152117
```
153118

154-
When the Clients connect, they read the KVs for all silos in the cluster in one HTTP GET by using the URI `http://192.168.1.26:8500/v1/KV/orleans/MyOrleansDeployment/?recurse`.
119+
When the clients connect, they read the KVs for all silos in the cluster in one HTTP GET by using the URI `http://192.168.1.26:8500/v1/KV/orleans/default/?recurse`.
155120

156121
## Limitations
157122

123+
There are a few limitations to be aware of when using Consul as a membership provider.
124+
158125
### Orleans extended membership protocol (table version & ETag)
159126

160-
Consul KV currently does not support atomic updates.
161-
Therefore, the Orleans Consul Membership Provider only implements the Orleans basic membership protocol, as described in [Cluster management in Orleans](../implementation/cluster-management.md), and does not support the Extended Membership Protocol. This Extended protocol was introduced as an additional, but not essential, silo connectivity validation and as a foundation to functionality that has not yet been implemented.
162-
Providing your infrastructure is correctly configured you will not experience any detrimental effect of the lack of support.
127+
Consul KV currently doesn't support atomic updates. Therefore, the Orleans Consul Membership Provider only implements the Orleans basic membership protocol, as described in [Cluster management in Orleans](../implementation/cluster-management.md), and doesn't support the Extended Membership Protocol. This Extended protocol was introduced as an extra, but not essential, silo connectivity validation and as a foundation to functionality that hasn't yet been implemented.
163128

164129
### Multiple datacenters
165130

166-
The key-value pairs in Consul are not currently replicated between Consul datacenters. There is a [separate project](https://github.com/hashicorp/consul-replicate) to address this but it has not yet been proven to support Orleans.
131+
The key-value pairs in Consul aren't currently replicated between Consul data centers. There's a [separate project](https://github.com/hashicorp/consul-replicate) to address this replication effort, but it hasn't yet been proven to support Orleans.
167132

168133
### When running on Windows
169134

170-
When Consul starts on Windows it logs the following message:
135+
When Consul starts on Windows, it logs the following message:
171136

172137
```Output
173138
==> WARNING: Windows is not recommended as a Consul server. Do not use in production.
174139
```
175140

176-
This is displayed simply due to a lack of focus on testing when running in a Windows environment and not because of any actual known issues.
177-
Read the [discussion](https://groups.google.com/forum/#!topic/consul-tool/DvXYgZtUZyU) before deciding if Consul is the right choice for you.
141+
This warning message is displayed due to a lack of focus on testing when running in a Windows environment and not because of any actual known issues. Read the [discussion](https://groups.google.com/forum/#!topic/consul-tool/DvXYgZtUZyU) before deciding if Consul is the right choice for you.
178142

179143
## Potential future enhancements
180144

181-
1. Prove that the Consul KV replication project can support an Orleans cluster in a WAN environment between multiple Consul datacenters.
145+
1. Prove that the Consul KV replication project can support an Orleans cluster in a WAN environment between multiple Consul data centers.
182146
1. Implement the Reminder Table in Consul.
183147
1. Implement the Extended Membership Protocol.
184-
The team behind Consul does plan on implementing atomic operations, once this functionality is available it will be possible to remove the limitations in the provider.
148+
The team behind Consul does plan on implementing atomic operations, once this functionality is available it's possible to remove the limitations in the provider.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
IHostBuilder builder = Host.CreateDefaultBuilder(args)
2+
.UseOrleans(silo =>
3+
{
4+
silo.UseConsulSiloClustering(options =>
5+
{
6+
// The address of the Consul server
7+
var address = new Uri("http://localhost:8500");
8+
options.ConfigureConsulClient(address);
9+
});
10+
})
11+
.UseConsoleLifetime();
12+
13+
using IHost host = builder.Build();
14+
host.Run();
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"profiles": {
3+
"Silo": {
4+
"commandName": "Project",
5+
"launchBrowser": true,
6+
"environmentVariables": {
7+
"ASPNETCORE_ENVIRONMENT": "Development"
8+
},
9+
"applicationUrl": "https://localhost:52782;http://localhost:52783"
10+
}
11+
}
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net7.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.Orleans.Server" Version="7.1.2" />
11+
<PackageReference Include="Microsoft.Orleans.Clustering.Consul" Version="7.1.2" />
12+
</ItemGroup>
13+
14+
</Project>

0 commit comments

Comments
 (0)