When you have 200 concurrent users hitting a single-threaded service, you’ll see the connection pool exhaustion error: “java.sql.SQLException: Unable to acquire JDBC Connection”. This is because the default connection pool size is not sufficient for production workloads. To avoid this, you need to implement Terraform best practices for production infrastructure.
## Prerequisites To follow this tutorial, you need to have the following: * Java 17 or later * Spring Boot 2.7 or later * Maven 3.8 or later * Terraform 1.2 or later The following Maven dependency is required:
<dependency> <groupId>com.hashicorp</groupId> <artifactId>terraform</artifactId> <version>1.2.5</version> </dependency>
## Terraform Internals and Architecture To understand how Terraform works, you need to know about the state file, which stores the current state of your infrastructure. The state file is used to track changes and ensure that your infrastructure is consistent with your Terraform configuration. The following ASCII diagram shows the Terraform architecture:
+---------------+ | Terraform | +---------------+ | | v +---------------+ | State File | +---------------+ | | v +---------------+ | Infrastructure | +---------------+
The following table compares the different state file backends:
| Backend | Description |
|---|---|
| Local | Stores the state file locally on the machine running Terraform. |
| S3 | Stores the state file in an Amazon S3 bucket. |
| Azure Blob Storage | Stores the state file in an Azure Blob Storage container. |
## Step-by-Step Implementation To implement Terraform best practices for production infrastructure, follow these steps: ### Step 1: Configure the Connection Pool Configure the connection pool to ensure that it can handle the production workload. The following Java code shows how to configure the connection pool:
public class ConnectionPoolConfig { @Bean public DataSource dataSource() { // Configure the connection pool return DataSourceBuilder.create() .driverClassName("com.mysql.cj.jdbc.Driver") .url("jdbc:mysql://localhost:3306/mydb") .username("myuser") .password("mypassword") .build(); } }
Expected output:
2023-03-09 14:30:00.000 INFO 12345 --- [ main] com.example.ConnectionPoolConfig : Connection pool configured successfully
### Step 2: Manage State Files Manage the state files to ensure that they are stored securely and can be easily recovered in case of a disaster. The following Terraform code shows how to configure the state file backend:
terraform { backend "s3" { bucket = "my-bucket" key = "terraform.tfstate" region = "us-west-2" } }
## Complete Working Example The following is a complete working example of a Terraform configuration for a production environment:
# Configure the provider provider "aws" { region = "us-west-2" } # Configure the VPC resource "aws_vpc" "my_vpc" { cidr_block = "10.0.0.0/16" } # Configure the subnet resource "aws_subnet" "my_subnet" { vpc_id = aws_vpc.my_vpc.id cidr_block = "10.0.1.0/24" availability_zone = "us-west-2a" } # Configure the security group resource "aws_security_group" "my_sg" { name = "my_sg" description = "My security group" vpc_id = aws_vpc.my_vpc.id # Configure the ingress rule ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } }
The following curl command can be used to test the configuration:
curl -X GET http://localhost:8080 -H 'Content-Type: application/json'
Expected response:
{ "message": "Hello World!" }
## Common Mistakes and How to Fix Them The following are common mistakes and how to fix them: ### Mistake 1: Not Closing the Connection Pool The following Java code shows an example of not closing the connection pool:
public class ConnectionPoolConfig { @Bean public DataSource dataSource() { // Configure the connection pool return DataSourceBuilder.create() .driverClassName("com.mysql.cj.jdbc.Driver") .url("jdbc:mysql://localhost:3306/mydb") .username("myuser") .password("mypassword") .build(); } } // WRONG - causes resource leak
The following error message will be displayed:
2023-03-09 14:30:00.000 ERROR 12345 --- [ main] com.example.ConnectionPoolConfig : Connection pool not closed
To fix this, you need to close the connection pool:
public class ConnectionPoolConfig { @Bean public DataSource dataSource() { // Configure the connection pool return DataSourceBuilder.create() .driverClassName("com.mysql.cj.jdbc.Driver") .url("jdbc:mysql://localhost:3306/mydb") .username("myuser") .password("mypassword") .build(); } @PreDestroy public void closeDataSource() { // Close the connection pool dataSource().close(); } }
## Performance and Production Tips The following are performance and production tips:
Production tip: Set
hikari.maximum-pool-size=10for a 4-core server. Default is 10, but you may need to adjust this based on your specific workload.
Production tip: Use
spring.datasource.tomcat.max-active=50to set the maximum number of active connections.
For more information on Java Algorithms and Mastering SQL, please visit our website. This post is part of the ‘Terraform Tutorials Hub’ content cluster, which can be found at More Terraform Tutorials. ## Testing The following JUnit 5 test shows how to test the core logic:
@SpringBootTest public class ConnectionPoolConfigTest { @Autowired private ConnectionPoolConfig connectionPoolConfig; @Test public void testDataSource() { // Test the data source DataSource dataSource = connectionPoolConfig.dataSource(); assertNotNull(dataSource); } }
Expected output:
2023-03-09 14:30:00.000 INFO 12345 --- [ main] com.example.ConnectionPoolConfigTest : Data source test passed
## Key Takeaways The following are key takeaways: * Configure the connection pool to ensure that it can handle the production workload. * Manage the state files to ensure that they are stored securely and can be easily recovered in case of a disaster. * Use hikari.maximum-pool-size=10 for a 4-core server. * Use spring.datasource.tomcat.max-active=50 to set the maximum number of active connections. * Test the core logic using JUnit 5. * Use More Terraform Tutorials to learn more about Terraform.
terraform-examples — Clone, Star & Contribute

Leave a Reply