Troubleshooting Guide
Troubleshooting Guide
Common issues and their solutions when using Morphium.
Connection Issues
Cannot Connect to MongoDB
Symptoms:
MorphiumDriverException: Could not get connection to [host] in time [timeout]ms- Application startup fails with connection timeout
Diagnosis:
<!-- Enable debug logging for driver in log4j2.xml -->
<Logger name="de.caluga.morphium.driver.wire.PooledDriver" level="DEBUG" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
Common Causes & Solutions:
-
Incorrect host/port configuration
// Check your host configuration cfg.clusterSettings().addHostToSeed("correct-hostname", 27017); -
Network connectivity issues
- Verify MongoDB is running:
mongosh --host hostname:port - Check firewall rules and network policies
- Test connectivity:
telnet hostname 27017
- Verify MongoDB is running:
-
Authentication failures
// Verify credentials cfg.authSettings().setMongoLogin("correct-username"); cfg.authSettings().setMongoPassword("correct-password"); -
Connection pool exhaustion
// Increase connection limits cfg.connectionSettings().setMaxConnectionsPerHost(200); cfg.connectionSettings().setMaxWaitTime(10000);
Replica Set Connection Issues
Symptoms:
MorphiumDriverException: No primary node defined - not connected yet?- Intermittent connection failures
Solutions:
-
Verify replica set configuration
// In MongoDB shell rs.status() rs.conf() -
Check replica set name
cfg.clusterSettings().setReplicaSetName("correct-replica-set-name"); -
Add all replica set members to seed list
cfg.clusterSettings().addHostToSeed("mongo1", 27017); cfg.clusterSettings().addHostToSeed("mongo2", 27017); cfg.clusterSettings().addHostToSeed("mongo3", 27017);
Performance Issues
Slow Query Performance
Symptoms:
- High response times
- CPU usage spikes
- Memory growth
Diagnosis:
<!-- Enable query logging in log4j2.xml -->
<Logger name="de.caluga.morphium" level="DEBUG" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
// Monitor driver statistics
Map<DriverStatsKey, Double> stats = morphium.getDriver().getDriverStats();
System.out.println("Connections in use: " + stats.get(DriverStatsKey.CONNECTIONS_IN_USE));
System.out.println("Connections in pool: " + stats.get(DriverStatsKey.CONNECTIONS_IN_POOL));
Solutions:
-
Add missing indexes
@Entity @Index({"fieldName", "composite,field"}) // Add compound indexes public class MyEntity { @Index private String frequentlyQueriedField; } // Create indexes manually morphium.ensureIndicesFor(MyEntity.class); -
Optimize query patterns
// Use projection to limit returned fields Query<MyEntity> q = morphium.createQueryFor(MyEntity.class) .f("status").eq("active") .project("name", "email"); // Only return specific fields // Use pagination for large result sets List<MyEntity> results = q.skip(offset).limit(pageSize).asList(); -
Review caching configuration
@Entity @Cache(timeout = 60000, maxEntries = 10000) // Adjust cache settings public class MyEntity { /* ... */ }
Memory Issues
Symptoms:
OutOfMemoryError- Gradual memory increase
- Long GC pauses
Diagnosis:
// Monitor connection pool stats
Map<DriverStatsKey, Double> stats = morphium.getDriver().getDriverStats();
Double connectionsInUse = stats.get(DriverStatsKey.CONNECTIONS_IN_USE);
Double connectionsInPool = stats.get(DriverStatsKey.CONNECTIONS_IN_POOL);
System.out.println("Memory usage - Connections: " + connectionsInUse + "/" + connectionsInPool);
Solutions:
-
Connection pool sizing
// Adjust pool size based on actual usage cfg.connectionSettings().setMaxConnectionsPerHost(50); // Reduce if too high cfg.connectionSettings().setMaxConnectionIdleTime(60000); // Close idle connections sooner cfg.connectionSettings().setMaxConnectionLifetime(300000); // Shorter connection lifetime -
Cache tuning
@Entity @Cache(maxEntries = 1000, timeout = 30000, strategy = Cache.ClearStrategy.LRU) public class MyEntity { /* ... */ } -
Large result set handling
// Use iterator for large datasets MorphiumIterator<MyEntity> iterator = query.asIterable(100); // Process in batches while (iterator.hasNext()) { MyEntity entity = iterator.next(); // Process entity }
Messaging Issues
Messages Not Being Processed
Symptoms:
- Messages accumulating in queue
- Listeners not receiving messages
- High message latency
Diagnosis:
// Check messaging statistics
MessagingStatsKey stats = messaging.getStats();
System.out.println("Messages processed: " + stats.getMessagesProcessed());
System.out.println("Messages failed: " + stats.getMessagesFailed());
Solutions:
-
Check listener registration
// Ensure listener is properly registered messaging.addListenerForTopic("mytopic", (morphiumMessaging, msg) -> { System.out.println("Processing: " + msg.getMsg()); return null; // or return response message }); // Verify messaging is started messaging.start(); -
Increase processing capacity
// Configure for higher throughput cfg.messagingSettings().setMessagingWindowSize(200); cfg.messagingSettings().setMessagingMultithreadded(true); cfg.messagingSettings().setPollPauseTime(100); // Reduce pause time -
Check for exceptions in listeners
messaging.addListenerForTopic("mytopic", (morphiumMessaging, msg) -> { try { // Your processing logic return processMessage(msg); } catch (Exception e) { log.error("Message processing failed", e); // Decide whether to return error response or null return null; } });
Message Ordering Issues
Symptoms:
- Messages processed out of order
- Race conditions in message processing
Solutions:
-
Use exclusive messaging for ordering
Msg msg = new Msg("ordered-topic", "content", "value"); msg.setExclusive(true); // Ensure only one listener processes at a time messaging.sendMessage(msg); -
Single-threaded processing for critical topics
// Configure single-threaded processing for specific topics cfg.messagingSettings().setMessagingMultithreadded(false);
Logging and Debugging
Enable Debug Logging
<!-- Configure logging in log4j2.xml -->
<Configuration>
<Appenders>
<Console name="Console">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="MorphiumLog" fileName="/var/log/morphium/app.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<!-- Global debug logging for all Morphium components -->
<Logger name="de.caluga.morphium" level="DEBUG" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="MorphiumLog"/>
</Logger>
<!-- Class-specific logging -->
<Logger name="de.caluga.morphium.driver.wire.PooledDriver" level="DEBUG" additivity="false">
<AppenderRef ref="MorphiumLog"/>
</Logger>
<Logger name="de.caluga.morphium.messaging.StdMessaging" level="DEBUG" additivity="false">
<AppenderRef ref="MorphiumLog"/>
</Logger>
<!-- Package-level logging -->
<Logger name="de.caluga.morphium.driver" level="DEBUG" additivity="false">
<AppenderRef ref="MorphiumLog"/>
</Logger>
</Loggers>
</Configuration>
Key Log Patterns to Watch
Connection Issues:
ERROR: Could not get connection to [host] in time [timeout]ms
WARN: Connection timeout
ERROR: Could not create connection to host [host]
Performance Issues:
WARN: Connection pool exhausted
DEBUG: Query took [time]ms
WARN: Cache hit ratio low: [ratio]
Messaging Issues:
ERROR: Message processing failed
WARN: Message queue size growing: [size]
DEBUG: Message processed in [time]ms
Monitoring Key Metrics
Connection Pool Metrics
Map<DriverStatsKey, Double> stats = morphium.getDriver().getDriverStats();
// Monitor these key metrics:
Double connectionsInUse = stats.get(DriverStatsKey.CONNECTIONS_IN_USE);
Double connectionsInPool = stats.get(DriverStatsKey.CONNECTIONS_IN_POOL);
Double connectionsOpened = stats.get(DriverStatsKey.CONNECTIONS_OPENED);
Double connectionsClosed = stats.get(DriverStatsKey.CONNECTIONS_CLOSED);
Double errors = stats.get(DriverStatsKey.ERRORS);
Double threadsWaiting = stats.get(DriverStatsKey.THREADS_WAITING_FOR_CONNECTION);
Performance Alerts
Set up monitoring for these conditions:
-
Connection pool exhaustion
connectionsInUse / maxConnectionsPerHost > 0.8
-
High error rate
errors / (connectionsOpened + errors) > 0.05
-
Thread starvation
threadsWaiting > 0for extended periods
-
Connection churn
- High
connectionsOpenedandconnectionsClosedrates
- High
Common Configuration Mistakes
1. Undersized Connection Pool
// Problem: Too few connections for load
cfg.connectionSettings().setMaxConnectionsPerHost(5); // Too small
// Solution: Size based on concurrent operations
cfg.connectionSettings().setMaxConnectionsPerHost(50);
2. Excessive Connection Timeout
// Problem: Long timeouts hide connection issues
cfg.connectionSettings().setMaxWaitTime(60000); // Too long
// Solution: Fail fast to detect issues
cfg.connectionSettings().setMaxWaitTime(5000);
3. Missing Indexes
// Problem: No indexes on frequently queried fields
@Entity
public class User {
private String email; // Frequently queried but not indexed
}
// Solution: Add appropriate indexes
@Entity
@Index({"email", "status,email"}) // Single and compound indexes
public class User {
@Index
private String email;
private String status;
}
4. Inefficient Cache Configuration
// Problem: Cache settings don't match usage patterns
@Cache(timeout = 1000, maxEntries = 100) // Too short timeout, too small cache
// Solution: Match cache to data access patterns
@Cache(timeout = 300000, maxEntries = 10000, strategy = Cache.ClearStrategy.LRU)
Getting Help
When reporting issues, include:
- Configuration details (sanitized)
- Error logs with timestamps
- Driver statistics output
- MongoDB version and topology
- Java version and JVM settings
- Morphium version
- Steps to reproduce the issue
// Collect diagnostic information
System.out.println("Morphium version: " + Morphium.getVersion());
System.out.println("Java version: " + System.getProperty("java.version"));
System.out.println("Driver stats: " + morphium.getDriver().getDriverStats());
System.out.println("Configuration: " + morphium.getConfig().toString());