mirror of
https://github.com/keycloak/keycloak.git
synced 2025-12-21 06:20:05 -06:00
Update docs how to verify that a cluster has formed
Closes #40296 Signed-off-by: Pedro Ruivo <1492066+pruivo@users.noreply.github.com> Signed-off-by: Alexander Schwartz <aschwart@redhat.com> Co-authored-by: Pedro Ruivo <1492066+pruivo@users.noreply.github.com> Co-authored-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
BIN
docs/guides/images/server/infinispan_info.png
Normal file
BIN
docs/guides/images/server/infinispan_info.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
@@ -408,6 +408,46 @@ m|cache-embedded-network-external-address
|
||||
|
||||
|===
|
||||
|
||||
== Verify cluster and network health
|
||||
|
||||
This section provides methods to verify that your {project_name} cluster has formed correctly and that network communication between instances is functioning as expected.
|
||||
It is crucial to perform these checks after deployment to ensure high availability and data consistency.
|
||||
|
||||
To verify if the cluster is formed properly, check one of these locations:
|
||||
|
||||
* Admin UI
|
||||
+
|
||||
Access the {project_name} Web UI, typically available at `++https://<your-host>/admin/master/console/#/master/providers++`.
|
||||
Under the *Provider Info* section, locate the *connectionsInfinispan* entry.
|
||||
Click on *Show more* to expand its details.
|
||||
You should find information about the cluster status and the health of individual caches.
|
||||
+
|
||||
image:server/infinispan_info.png[Infinispan Cluster Information in Web UI]
|
||||
|
||||
* Logs
|
||||
+
|
||||
Infinispan logs a cluster view every time a new instance joins or leaves the cluster.
|
||||
Search for log entries with the ID `ISPN000094`.
|
||||
+
|
||||
A healthy cluster view will show all expected nodes.
|
||||
For example:
|
||||
+
|
||||
[source,text]
|
||||
----
|
||||
ISPN000094: Received new cluster view for channel ISPN: [node1-26186|1] (2) [node1-26186, node2-37007]
|
||||
----
|
||||
+
|
||||
This log entry indicates that the cluster named "ISPN" currently has 2 nodes: `node1-26186` and `node2-37007`.
|
||||
The `(2)` confirms the total number of nodes in the cluster.
|
||||
|
||||
* Metrics
|
||||
+
|
||||
{project_name} exposes Infinispan metrics via a Prometheus endpoint, which can be visualized in tools like Grafana.
|
||||
The metric `vendor_cluster_size` shows the current number of instances in the cluster.
|
||||
You should verify that this metric matches the expected number of running instances configured in your cluster.
|
||||
+
|
||||
Refer to <@links.observability id="metrics-for-troubleshooting-clustering-and-network" anchor="_cluster_size"/> for more information.
|
||||
|
||||
== Exposing metrics from caches
|
||||
|
||||
Metrics from caches are automatically exposed when the metrics are enabled.
|
||||
|
||||
@@ -17,16 +17,23 @@
|
||||
|
||||
package org.keycloak.connections.infinispan;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.infinispan.client.hotrod.RemoteCacheManager;
|
||||
import org.infinispan.commons.util.Version;
|
||||
import org.infinispan.configuration.cache.Configuration;
|
||||
import org.infinispan.eviction.EvictionStrategy;
|
||||
import org.infinispan.health.CacheHealth;
|
||||
import org.infinispan.manager.DefaultCacheManager;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.jboss.logging.Logger;
|
||||
@@ -52,6 +59,7 @@ import org.keycloak.provider.InvalidationHandler.ObjectType;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderEvent;
|
||||
import org.keycloak.provider.ProviderEventListener;
|
||||
import org.keycloak.provider.ServerInfoAwareProviderFactory;
|
||||
import org.keycloak.spi.infinispan.CacheEmbeddedConfigProvider;
|
||||
import org.keycloak.spi.infinispan.CacheRemoteConfigProvider;
|
||||
import org.keycloak.spi.infinispan.impl.embedded.CacheConfigurator;
|
||||
@@ -73,7 +81,7 @@ import static org.keycloak.models.cache.infinispan.InfinispanCacheRealmProviderF
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class DefaultInfinispanConnectionProviderFactory implements InfinispanConnectionProviderFactory, ProviderEventListener {
|
||||
public class DefaultInfinispanConnectionProviderFactory implements InfinispanConnectionProviderFactory, ProviderEventListener, ServerInfoAwareProviderFactory {
|
||||
|
||||
private static final ReadWriteLock READ_WRITE_LOCK = new ReentrantReadWriteLock();
|
||||
private static final Logger logger = Logger.getLogger(DefaultInfinispanConnectionProviderFactory.class);
|
||||
@@ -278,4 +286,32 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
|
||||
KeycloakModelUtils.runJobInTransaction(pme.getFactory(), this::registerSystemWideListeners);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getOperationalInfo() {
|
||||
Map<String, String> info = new LinkedHashMap<>();
|
||||
info.put("product", Version.getBrandName());
|
||||
info.put("version", Version.getBrandVersion());
|
||||
if (InfinispanUtils.isRemoteInfinispan()) {
|
||||
addRemoteOperationalInfo(info);
|
||||
} else {
|
||||
addEmbeddedOperationalInfo(info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
private void addEmbeddedOperationalInfo(Map<String, String> info) {
|
||||
var cacheManagerInfo = cacheManager.getCacheManagerInfo();
|
||||
info.put("clusterSize", Integer.toString(cacheManagerInfo.getClusterSize()));
|
||||
var cacheNames = Arrays.stream(InfinispanConnectionProvider.CLUSTERED_CACHE_NAMES)
|
||||
.sorted()
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
for (CacheHealth health : cacheManager.getHealth().getCacheHealth(cacheNames)) {
|
||||
info.put(health.getCacheName() + ":Cache", health.getStatus().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void addRemoteOperationalInfo(Map<String, String> info) {
|
||||
info.put("connectionCount", Integer.toString(remoteCacheManager.getConnectionCount()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user