Static and Dynamic Configuration for Java Services in the Cloud

Two developers are configuring their cloud services.

Static and dynamic configurations are two approaches used to set up and modify the settings of cloud services.

Static configuration involves defining the configuration parameters before deploying the service. It includes specifying values in configuration files or through the service’s management console. The static configuration provides predictability and ease of deployment since we establish the settings upfront, and we can replicate them across environments. However, it may not be suitable for scenarios requiring frequent changes.

Dynamic configuration allows for on-the-fly modification of settings without redeployment or service interruption. It enables real-time adjustments to parameters while the service is running, offering flexibility and adaptability to changing conditions.

Dynamic configuration is achieved through mechanisms like configuration APIs or environment variables. It allows for quick response to requirements, workload variations, and fine-tuning of the service’s behavior. We often use a combination of static and dynamic configuration approaches to balance stability and responsiveness in cloud services.

Pros and cons of Static Configuration

Static configuration refers to the process of setting up and defining the configuration parameters of a system or application before it is deployed or executed. In static configuration, the configuration values are typically specified in configuration files or directly in the application’s source code.

Static configuration often establishes a system or application’s initial settings and behavior. These configuration parameters can include options such as database connection details, network settings, logging levels, feature toggles, and various other parameters that define the behavior and functionality of the system.

The advantages of static configuration include:

  1. Predictability: Since the configuration values are set before deployment, the system’s behavior is consistent and predictable across different environments.
  2. Ease of Deployment: Static configuration allows for easy system deployment since the configuration values are already defined and can be easily replicated across different instances or environments.
  3. Security: Configuration files can be secured and restricted to authorized users, preventing unauthorized access or modification of critical system settings.
  4. Version Control: Configuration files can be maintained in version control systems, allowing for easy tracking of changes and rollbacks to previous configurations if needed.

However, the static configuration has some limitations:

  1. Limited Flexibility: Static configuration may not be suitable for scenarios where dynamic or runtime changes to configuration values are required. For example, if a system needs to adapt to changing network conditions or load balancing requirements, static configuration may not be the best approach.
  2. Configuration Drift: In complex systems with multiple instances or environments, keeping the configuration consistent across all deployments can be challenging and may lead to configuration drift if not properly managed.

To overcome the limitations of static configuration, dynamic configuration approaches can be used, where configuration values can be modified and updated at runtime without redeployment. It allows for greater flexibility and adaptability in changing environments.

Example of static Configuration in Java

Let’s see a simple example of a static configuration using Spring that reads a YML configuration file and prints the values. Remember that we are only able to make the changes reflected when the deploy the application:

1 – Create the application.yml file
myapp:
  staticValue: Hello, World!
2 – To configure Spring to read the YML file, we need to create a configuration Java class
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyAppConfig {
}
3 – Using the static configuration with the annotation @Value from Spring
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyBean {
    @Value("${myapp.staticValue}")
    private String staticValue;

    public void printStaticValue() {
        System.out.println(staticValue);
    }
}
4 – Now, we can print the value of the static configuration
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyApp {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyAppConfig.class);
        MyBean myBean = context.getBean(MyBean.class);
        myBean.printStaticValue(); // Output: Hello, World!
    }
}
Pros and Cons of Dynamic Configuration

Dynamic configuration in software systems offers certain advantages and disadvantages. Let’s explore the pros and cons.

Pros of Dynamic Configuration:

Flexibility and Adaptability: Dynamic configuration allows for on-the-fly modifications to system settings without requiring a restart or redeployment. This flexibility enables the system to adapt to changing requirements or operational conditions more efficiently.

Real-time Configuration Updates: Dynamic configuration enables real-time updates to system settings, which can be advantageous in scenarios where immediate adjustments are necessary. It allows for fine-grained control over various aspects of the system without interrupting its operation.

Environment-specific Configuration: Dynamic configuration supports the ability to customize settings based on different environments (e.g., development, staging, production). This flexibility simplifies the deployment process and ensures that the system behaves optimally in each environment.

Centralized Configuration Management: Dynamic configuration often involves a centralized management system or tool. This centralized approach allows for easier management, versioning, and auditing of configuration settings, promoting better governance and control.

Cons of Dynamic Configuration:

Increased Complexity: Dynamic configuration introduces additional complexity to the system. Managing real-time updates, synchronization, and consistency across distributed systems can be challenging and may require careful design and implementation.

Potential for Configuration Errors: With dynamic configuration, there is a higher risk of introducing configuration errors or inconsistencies. Frequent updates and modifications increase the chances of misconfigurations, leading to system instability or unexpected behavior.

Runtime Dependencies: Dynamic configuration may introduce dependencies on external systems or services responsible for managing and distributing configuration settings. If these dependencies fail or experience downtime, it can impact the availability and stability of the system.

Security Concerns: Dynamic configuration systems can be potential targets for security breaches. Unauthorized access to configuration settings or tampering with them can have severe consequences. Therefore, robust security measures must be implemented to safeguard sensitive configuration data.

It’s important to carefully evaluate the specific requirements and constraints of a system before deciding to adopt a dynamic configuration. While it offers benefits like flexibility and real-time updates, it also introduces complexities and potential risks that must be managed effectively.

Example of Dynamic Configuration with Java

An example that is widely used in the market for dynamic configuration is the Spring config server. Spring config server is a lib that allows Microservices to retrieve configurations dynamically from the Spring config server. It means that we have all the configurations in a separate service, enabling us to change those configurations dynamically without impacting other Microservices.

Let’s see a code example to configure the config server.

Set up the Spring Config Server

1 – Create a new Spring Boot project and include the necessary dependencies in your pom.xml file
<!-- For Spring Config Server -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
2 – Annotate your main application class with @EnableConfigServer to enable the Config Server functionality
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
3 – Configure the server’s properties in application.properties
server.port=8888

spring.cloud.config.server.git.uri=https://github.com/your-username/your-config-repo.git
Spring.cloud.config.server.git.search-paths=configs/{application}
4 – Create a configuration file in the Git repository

Assuming you have a Git repository with the URL https://github.com/your-username/your-config-repo.git, create a configuration file named myapp.properties in the repository.

greeting.message=Hello from Config Server!
5 – Create a client application

Create a new Spring Boot project for the client application and include the necessary dependencies in your pom.xml file:

<!-- For Spring Config Client -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
6 – Configure the client application’s properties in bootstrap.properties
spring.application.name=myapp
Spring.cloud.config.uri=http://localhost:8888
7 – Create a simple service that uses the configuration property
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class GreetingService {

    @Value("${greeting.message}")
    private String greetingMessage;

    public String getGreetingMessage() {
        return greetingMessage;
    }
}
8 – Start the Config Server and the client application

Start the Config Server application first. Then, start the client application. The client application will connect to the Config Server and retrieve the configuration dynamically.

Access the configuration property in the client application:

9 – Use the GreetingService bean to access the configuration property in a controller or any other Spring bean
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private final GreetingService greetingService;

    public GreetingController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    @GetMapping("/greeting")
    public String getGreeting() {
        return greetingService.getGreetingMessage();
    }
}

When you access the /greeting endpoint of the client application (e.g., http://localhost:8080/greeting), it will fetch the greeting.message property from the Config Server dynamically and return the corresponding value (“Hello from Config Server!”).

That’s a basic example showcasing the usage of Spring Config Server with a client application. The Config Server retrieves configuration from a Git repository, and the client application fetches the configuration dynamically from the Config Server without requiring redeployment.

Summary of Static and Dynamic Configuration

One key point to remember when designing systems is that there is no one-size-fits-all solution. Static configuration is not better than dynamic configuration or vice-versa. It will depend on the use case. If the configuration changes very often or there is a specific requirement where configurations must be changed without the need for a redeploy, then dynamic configuration is better. But if the configuration doesn’t change very often, static configuration works fine, and it’s less complex to maintain.

To remember the key points, let’s recap:

Static Configuration:

  • Configuration settings are defined and set during deployment or startup.
  • Settings remain unchanged until the next deployment or restart.
  • Provides stability and consistency to the application.
  • Suitable for scenarios where configuration changes are infrequent.
  • May require manual intervention and downtime to update settings.

Dynamic Configuration:

  • Configuration settings can be modified during runtime without redeployment or restart.
  • Enables real-time adjustments to application behavior.
  • Offers flexibility and adaptability to changing requirements or dynamic environments.
  • Useful for scenarios that require frequent updates or immediate changes.
  • Can be achieved through mechanisms like configuration servers or live reloading.
Written by
Rafael del Nero
Join the discussion