External configuration of Project parameters

Source: Internet
Author: User

To develop a project, parameters are essential, and the larger the scale the more parameters. Deploying in different test environments or relying on project information has changed, do you feel like jumping off the jumper? If so, congratulations, you're not developing a toy system at least.

This article attempts to enumerate some of the configuration parameters, which I hope will help you with your project. One, availability mode-external configuration

Quoting from the book Java Application Architecture design: Modular mode and OSGi 10.2

"Modules should be externally configurable"

When a module is deployed to a runtime environment, it is usually initialized before it is used. For example, to allow the module to access data in the database, initialize the module with the necessary user ID and password. However, we also want to avoid tightly coupling configuration information with modules. If you do this, the module will be coupled to a single context environment, which restricts the modules from being reused in other optional contexts.

External configuration allows modules to be configured across environment contexts. Shows the external configuration, where the client class uses an XML configuration file to configure the Client.jar module. It is important to note that the configuration information used to initialize the Client.jar is separate from the client class that represents the behavior of the module. Being able to configure modules into the context of the environment enhances the ability to reuse modules across environments.

The location of the configuration file, there are three ways to handle it:

1. The configuration information is included in the module, and the advantage is that it is easy to use in the default context of the module, and is insufficient in other contexts to not work properly.

2, the configuration information is not in the module, but at the time of initialization by the external supply to the module. The advantage is that it can be reused across environments, and it is not sufficient to configure all parameters for each environment.

3. A more flexible scenario is to provide a default profile in the module, but allows alternative configuration files to be available outside the module. is an example of a book.

In these three scenarios, the last one looks most seductive, enabling a more flexible configuration approach. Follow-up We use this scheme to design. Second, the default + alternative configuration scheme

Consider a relatively simple project in enterprise development, providing both a Web interface and an API interface. To make it easier for other systems to invoke the API, a client jar is provided for invocation. 1. System Design

A brief description of each module:

    • Base-util.jar: A generic base package that implements the basic tool class. Our custom Read Profile tool class (Propsutil) is in this package.
    • Business-core.jar: Basic packages of business systems, such as model definitions, etc.
    • Business-web.war: A Web project of a business system that implements basic business logic and provides API implementations.
    • Business-client.jar: A client package for a business system that is called by other systems.

The arrows in the diagram represent dependencies. Off-topic, when designing the module, it is important to note that there is no cyclic dependency. 2, the configuration parameters of the Convention

This article does not consider the configuration of special requirements, such as database connection information, and focuses on the type of parameters that can be read by the Configuration Tool class Propsutil. such as the size of the thread pool, the server address and URI that the client calls the API.

    • A profile conf.properties is placed in each module and the configuration information is written in this configuration file.
    • Parameters of the same name are loaded, and parameters in the module override those in the dependent module.
    • To read the configuration parameters, you must use the function of propsutil.getstring ()/getint ()/getboolean () to read.
3, the realization of propsutil

The implementation of the tool class, the core is the need to solve two problems:

    • How to load the conf.properties in each jar
    • How to handle the loading order of individual conf.properties

With Springframeworks's resourcepatternresolver, you can read multiple jar packages, specific files in a war package into resource objects, and load them into Apache Commons configuration The configuration. The following code explains the implementation. 3.1 Loading Resource List

String Filepattern = "Classpath*:conf.properties";

Read the resource list according to the file name and do the necessary sorting

public static list<resource> getresources (String filepattern) {

list<resource> resultresources = new arraylist<resource> ();

try {

Resourcepatternresolver resolver =

New Pathmatchingresourcepatternresolver ();

resource[] Resources = (resource[]) resolver.getresources (Filepattern);

list<resource> jarresources = new arraylist<resource> ();

list<resource> webresources = new arraylist<resource> ();

Put the conf.properties files found in each jar package in order to Jarresources

Put the conf.properties files found in the war package in order to WebResources

This part of the code is self-repairing

Eventually merged into Resultresources

for (Resource oneresource:jarresources) {

Resultresources.add (Oneresource);

}

for (Resource oneresource:webresources) {

Resultresources.add (Oneresource);

}

} catch (IOException E1) {

Logger.error ("Getresources", E1);

}

return resultresources;

} 3.2 loading content into the configuration

Private volatile static configuration[] configs = null;

private static void Initconfigarray () {

Configs = new configuration[] {};

try {

int index = 0;

list<resource> resourcelist = resourcefileutil.getresources (propfile);

for (Resource resource:resourcelist) {

InputStream InputStream = Resource.getinputstream ();

if (InputStream! = null) {

Fileconfiguration onefileconfig = new Propertiesconfiguration ();

Onefileconfig.setencoding (Stringpool.utf8);

Onefileconfig.load (InputStream);

index++;

Configs = Arrayutil.append (configs, onefileconfig);

}

Inputstream.close ();

}

} catch (IOException E1) {

}

} 3.3 Read Configuration parameters

public static string GetString (string key, string defaultvalue) {

String stringvalue = null;

for (Configuration oneconfig:configs) {

if (Oneconfig.containskey (key)) {

String Tempvalue = oneconfig.getstring (key);

if (Validator.isnotnull (Tempvalue)) {

StringValue = Tempvalue;

}

}

}

if (Validator.isnull (stringvalue) && Validator.isnotnull (defaultvalue)) {

StringValue = defaultvalue;

} else if (stringvalue = = null) {

StringValue = Stringpool.blank;

}

return stringvalue;

}

This only writes the configuration of the read string type, and if it is a different data format, make the necessary conversions from string itself.

At this point, when you need to read the configuration parameters, you only need to call propsutil.getstring (), you can take the corresponding parameter values. This method has implemented the "Default + override" scheme, which provides default settings in the Conf.properties of the base module and replaces it with the new parameter values in the Conf.properties of the dependent module.

When different Web projects call the same base module, the parameters are different, so you only need to reset the new parameter values in the Conf.properties of the web. Iii. using MAVEN profile to solve multi-environment deployment issues

Conf.properties is the source code of the project. If a set of systems needs to be deployed in multiple environments, and the parameter values are different in different environments. If you modify the Conf.properties file directly, it will bring tedious manual effort to the packaged deployment.

If your project is managed with MAVEN, you can easily manage the parameters with Maven profile.

1. Modify the parameter values in the Conf.properties

The following two parameters are used as examples,

# Number of data processing threads

disrupter.handler.threads=2

# Number of attempts to push messages to the portal

Notify.portal.try.times=5

The modified parameter value is

# Number of data processing threads

Disrupter.handler.threads=${param.disrupter.handler.threads}

# Number of attempts to push messages to the portal

Notify.portal.try.times=${param.notify.portal.try.times}

Note that the variable name in the parameter value cannot be the same as the previous parameter name, or Maven throws an exception. The simplest way to do this is to precede the variable name with Param. 2. Increase profiles in Pom.xml

Assume that the system is deployed with four sets of rings, respectively,

    • Dev: Development environment
    • Testa: First round Test
    • TESTB: Second round test
    • Product: Production environment

Then, modify the Pom.xml file, the relevant part of the code is:

<profiles>

<profile>

<id>dev</id>

<activation>

<activeByDefault>true</activeByDefault>

</activation>

<properties>

<param.disrupter.handler.threads>1</param.disrupter.handler.threads>

<param.notify.portal.try.times>1</param.notify.portal.try.times>

</properties>

<build>

<filters>

<filter>src/main/resources/conf.properties</filter>

</filters>

</build>

</profile>

<profile>

<id>testa</id>

<activation>

<activeByDefault>false</activeByDefault>

</activation>

<properties>

<param.disrupter.handler.threads>1</param.disrupter.handler.threads>

<param.notify.portal.try.times>2</param.notify.portal.try.times>

</properties>

<build>

<filters>

<filter>src/main/resources/conf.properties</filter>

</filters>

</build>

</profile>

<profile>

<id>testb</id>

<activation>

<activeByDefault>false</activeByDefault>

</activation>

<properties>

<param.disrupter.handler.threads>1</param.disrupter.handler.threads>

<param.notify.portal.try.times>2</param.notify.portal.try.times>

</properties>

<build>

<filters>

<filter>src/main/resources/conf.properties</filter>

</filters>

</build>

</profile>

<profile>

<id>product</id>

<activation>

<activeByDefault>false</activeByDefault>

</activation>

<properties>

<param.disrupter.handler.threads>2</param.disrupter.handler.threads>

<param.notify.portal.try.times>5</param.notify.portal.try.times>

</properties>

<build>

<filters>

<filter>src/main/resources/conf.properties</filter>

</filters>

</build>

</profile>

</profiles>

Where Activebydefault indicates whether it is the default profile. After setting up the parameters, it is the problem of applying different profile methods in different environments. 3. Apply profile when Maven launches Web project

This way, it is necessary to add tomcat7-maven-plugin to this plugin in Pom.xml.

If you are using MAVEN to start Tomcat at the command line, you can use the following command:

MVN tomcat7:run-p Testa

Among them,-P Testa, which represents the use of Testa this profile.

If you enable using run in Eclipse, the configuration interface is similar to the following:

Using MAVEN for Project packaging is also the same approach, where you can select Testa at the profile. 4. Using server startup in Eclipse

After you add the server Runtime environments in eclipse, you deploy the project to server. Right-click on the item, select "Properties" and select "Maven" in the pop-up window to enter the corresponding amount.

Iv. realization of real-time parameter updating

The previous implementation has been a good solution to the problem of multi-environment deployment. In consideration of the particularity of the production environment, the application cannot be restarted casually. If a key parameter needs to be modified, as previously described, it needs to be repackaged and deployed to the production environment, and the application will be restarted.

If the project is a critical business, customer requirements can not be stopped, you must implement real-time parameter modification, how to do? Multi-point Environment grayscale Publishing is a solution; OSGi modular development deployment should also be a solution. Just these two scenarios, difficult to implement in existing projects, we still consider a simple way of handling. 1. Provide parameter management function (DB)

Implement a parameter setting function in the system, where the administrator saves the most recent parameter values in the database. The system first reads the parameter values in the database and then reads them from the properties file if it is empty. When the system parameters need to be adjusted, the administrator enters the management interface to modify and save.

As can be seen, the system to implement this custom function, need to complete: parameter data table, parameter package service and maintenance interface. This kind of solution, is suitable for the product sale The independent operation system, can adapt to different customer's demand. 2, the use of disconf to achieve

If there is more than one project in an operational system, each project needs to develop a management function that is cumbersome. Disconf is the solution for this situation, do not introduce it carefully, please go to the website to learn https://github.com/knightliao/disconf.

There are two scenarios for the application of disconf: Annotated distributed configuration usage and XML-configurable distributed configuration. Using annotations, you need to define a specific Java class for the configuration information, and add or subtract parameters that need to be modified for this Java class, which is not appropriate for our previous configuration solution. Therefore, it is recommended to use the "XML configuration Distributed Configuration Method". 2.1 Disconf Distribution configuration file

To simplify the implementation, design a file conf-disconf.properties specifically for disconf updates in the project, in addition to the original Conf.properties file. The project structure becomes

Modification of 2.2 Propsutil

This is done on the basis of the previous propsutil, without elaborating, outlining what needs to be changed.

1. Add a Resource

The read resource file is defined as classpath*:conf-disconf.properties. This configuration file requires a record of the update time.

2. Add a configuration to load the contents of the new config file. This configuration requires checking the update time of the resource file and reloading the content if the time of discovery changes.

3, read the configuration parameters, first read the contents of the conf-disconf.properties, if not loaded in the original order to load the configuration information.

In this way, when the configuration information in the disconf server changes, the parameter values are loaded into the latest parameter values when the Disconf-client is automatically synchronized to the application system and the parameters are read in the project.

External configuration of Project parameters

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.