mirror of
https://github.com/keycloak/keycloak.git
synced 2025-12-21 14:30: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
|
== Exposing metrics from caches
|
||||||
|
|
||||||
Metrics from caches are automatically exposed when the metrics are enabled.
|
Metrics from caches are automatically exposed when the metrics are enabled.
|
||||||
|
|||||||
@@ -17,16 +17,23 @@
|
|||||||
|
|
||||||
package org.keycloak.connections.infinispan;
|
package org.keycloak.connections.infinispan;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.infinispan.client.hotrod.RemoteCacheManager;
|
import org.infinispan.client.hotrod.RemoteCacheManager;
|
||||||
|
import org.infinispan.commons.util.Version;
|
||||||
import org.infinispan.configuration.cache.Configuration;
|
import org.infinispan.configuration.cache.Configuration;
|
||||||
import org.infinispan.eviction.EvictionStrategy;
|
import org.infinispan.eviction.EvictionStrategy;
|
||||||
|
import org.infinispan.health.CacheHealth;
|
||||||
import org.infinispan.manager.DefaultCacheManager;
|
import org.infinispan.manager.DefaultCacheManager;
|
||||||
import org.infinispan.manager.EmbeddedCacheManager;
|
import org.infinispan.manager.EmbeddedCacheManager;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
@@ -52,6 +59,7 @@ import org.keycloak.provider.InvalidationHandler.ObjectType;
|
|||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
import org.keycloak.provider.ProviderEvent;
|
import org.keycloak.provider.ProviderEvent;
|
||||||
import org.keycloak.provider.ProviderEventListener;
|
import org.keycloak.provider.ProviderEventListener;
|
||||||
|
import org.keycloak.provider.ServerInfoAwareProviderFactory;
|
||||||
import org.keycloak.spi.infinispan.CacheEmbeddedConfigProvider;
|
import org.keycloak.spi.infinispan.CacheEmbeddedConfigProvider;
|
||||||
import org.keycloak.spi.infinispan.CacheRemoteConfigProvider;
|
import org.keycloak.spi.infinispan.CacheRemoteConfigProvider;
|
||||||
import org.keycloak.spi.infinispan.impl.embedded.CacheConfigurator;
|
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>
|
* @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 ReadWriteLock READ_WRITE_LOCK = new ReentrantReadWriteLock();
|
||||||
private static final Logger logger = Logger.getLogger(DefaultInfinispanConnectionProviderFactory.class);
|
private static final Logger logger = Logger.getLogger(DefaultInfinispanConnectionProviderFactory.class);
|
||||||
@@ -278,4 +286,32 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
|
|||||||
KeycloakModelUtils.runJobInTransaction(pme.getFactory(), this::registerSystemWideListeners);
|
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