With the increasing complexity of program functions, the configuration of the program is increasing: switches of various functions, parameter configuration, server address...
The expectations for program configuration are also getting higher and higher: real-time effective after configuration modification, grayscale release, sub-environment, sub-cluster management configuration, perfect authority, audit mechanism...
In such a large environment, traditional methods such as configuration files and databases have become increasingly unable to meet developers' needs for configuration management.
Apollo Configuration Center came into being!
Apollo (Apollo) is a reliable distributed configuration management center, which was born in the Ctrip framework R&D department. It can centrally manage the configuration of different environments and different clusters of applications. After the configuration is modified, it can be pushed to the application side in real time, and it has standardized Features such as permissions and process governance are suitable for microservice configuration management scenarios.
Apollo supports 4 dimensions to manage the configuration in Key-Value format:
At the same time, Apollo is developed based on the open source model, open source address: https://github.com/ctripcorp/apollo
Since Apollo is positioned in the configuration center, it is necessary to briefly introduce what configuration is here.
According to our understanding, the configuration has the following properties:
Configuration is a read-only variable independent of the program
Configuration accompanies the entire life cycle of the application
Configuration can be loaded in multiple ways
Configuration requires governance
It is precisely based on the particularity of configuration that Apollo has been determined to become a configuration publishing platform with governance capabilities from the beginning of its design. Currently, it provides the following features:
Unified management of the configuration of different environments and different clusters
Configuration changes take effect in real time (hot release)
Version release management
Greyscale Release
Support configured grayscale publishing. For example, after clicking publish, it will only take effect on some application instances. After observing for a period of time, there is no problem before pushing to all application instances.
Permission management, release audit, operation audit
Client configuration information monitoring
Java and .Net native clients available
Provide open platform API
Easy to deploy
The following is the basic model of Apollo:
The picture above is the configuration home page of a project in the Apollo Configuration Center
Users can easily add/modify configuration items through the configuration center interface. For more usage instructions, please refer to Application Access Guide
Enter configuration information:
Publish the configuration through the configuration center:
Fill in the release information:
After the configuration is released, it can be obtained on the client side. Taking Java as an example, the sample code for obtaining the configuration is as follows. Apollo client also supports integration with Spring. For more client usage instructions, please refer to Java Client Usage Guide and .Net Client Usage Guide.
Config config = ConfigService.getAppConfig();
Integer defaultRequestTimeout = 200;
Integer requestTimeout = config.getIntProperty("requestTimeout", defaultRequestTimeout);
By obtaining the configuration code above, the application can obtain the latest configuration in real time.
However, in some scenarios, the application also needs to be notified when the configuration changes, such as the switching of database connections, so Apollo also provides the function of monitoring configuration changes. The Java example is as follows:
Config config = ConfigService.getAppConfig();
config.addChangeListener(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format(
"Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
change.getPropertyName(), change.getOldValue(),
change.getNewValue(), change.getChangeType()));
}
}
});
Apollo and Spring can also be easily integrated. You only need to mark @EnableApolloConfig
to get configuration information through @Value
:
@Configuration
@EnableApolloConfig
public class AppConfig {}
@Component
public class SomeBean {
//The value of timeout will be updated automatically
@Value("${request.timeout:200}")
private int timeout;
}
Through the above introduction, I believe you have a preliminary understanding of Apollo, and I believe that most of the usage scenarios have been covered.
The next section will mainly introduce Apollo's cluster management, namespace management and the corresponding configuration acquisition rules.
Before introducing advanced features, we need to understand a few core concepts in Apollo.
application (application)
environment (environment)
cluster (cluster)
namespace (namespace)
This section is only required if the application needs to apply different configurations to different clusters, if there is no relevant need, you can skip this section]
For example, if we have applications deployed in both data center A and data center B, then if we want the configuration of the two data centers to be different, we can solve it by creating a new cluster.
Only the project administrator has access to the new Cluster. The administrator can see the "Add Cluster" button on the left side of the page.
When you click it, you will enter the Add Cluster page. Generally, you can divide the clusters by data center, such as SHAJQ, SHAOY, etc. However, custom clusters are also supported.
However, custom clusters are also supported, for example, you can create a cluster for a machine in room A and a machine in room B, using one set of configurations.
After the cluster is successfully added, you can add configuration to the cluster. First, you need to switch to SHAJQ cluster as shown in the figure below, and then the configuration addition process is the same as 3.3 Adding/Modifying Configuration Items, so we won't go over it here.
Apollo will use the data center where the application instance is located as the cluster by default, so no additional configuration is needed if the two are the same.
If the cluster and data center are not the same, then you need to specify the runtime cluster by using System Property.
apollo.cluster
is all lowercase[This section is only required for public component configuration or shared configuration of multiple applications, you can skip this section if you don't have any relevant requirements]
If the application has public components (such as hermes-producer, cat-client, etc.) for other applications to use, you need to implement the configuration of public components through custom namespace.
Take hermes-producer as an example, you need to create a new namespace first, only the project administrator has permission to create namespace, the administrator can see the "Add Namespace" button on the left side of the page.
Apollo will prefix the namespace with the department the application belongs to, such as FX.
After the namespace is created, you need to select which environments and clusters to use it under
Next, add a configuration item under this new namespace
Once added, you can see the configuration in the FX.Hermes.Producer namespace.
Apollo client also supports integration with Spring, see Java Client User Guide and Net Client Net client.
Config config = ConfigService.getConfig("FX.Hermes.Producer");
Integer defaultSenderBatchSize = 200;
Integer senderBatchSize = config.getIntProperty("sender.batchsize", defaultSenderBatchSize);
Config config = ConfigService.getConfig("FX.Hermes.Producer");
config.addChangeListener(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
System.out.println("Changes for namespace " + changeEvent.getNamespace());
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format(
"Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
change.getPropertyName(), change.getOldValue(),
change.getNewValue(), change.getChangeType()));
}
}
});
@Configuration
@EnableApolloConfig("FX.Hermes.Producer")
public class AppConfig {}
@Component
public class SomeBean {
//the value of timeout will be updated automatically
@Value("${request.timeout:200}")
private int timeout;
}
[This section is only needed if the application is customized with a cluster or namespace, if there is no related need, you can skip this section]
After the concept of cluster, the rules of configuration become important.
For example, if the application is deployed in server room A, but no new cluster is created in Apollo, what is the behavior of Apollo at this time?
Or if cluster=SomeCluster is specified at runtime, but no new cluster is created in Apollo, what is the behavior of Apollo at this time?
The next step is to introduce the rules for configuration acquisition.
When the application uses the following statement to get the configuration, we call it getting the application's own configuration, that is, the configuration of the application namespace of the application itself.
Config config = ConfigService.getAppConfig();
The rules for getting the configuration for this case, in short, are as follows.
The diagram is as follows.
So if the application is deployed in datacenter A, but the user has not created a cluster in Apollo, then the configuration obtained is that of the default cluster (default).
If the application is deployed in data center A, and SomeCluster is specified at runtime, but no cluster is created in Apollo, then the configuration obtained is that of data center A cluster, and if data center A cluster is not configured, then the configuration obtained is that of default cluster (default).
Take FX.Hermes.Producer
as an example, hermes producer is a public component published by hermes. When the following statement is used to get the configuration, we call it getting the configuration of the public component.
Config config = ConfigService.getConfig("FX.Hermes.Producer");
The rules for getting the configuration for this case, in short, are as follows.
FX.Hermes.Producer
namespace under the current application
Then get the configuration of FX.Hermes.Producer
namespace under the hermes applicationThe diagram is as follows.
In this way, the configuration management of the framework class components is achieved. The framework component provider provides the default values for the configuration, and the application can override them if it has special needs.
The above diagram briefly describes the overall design of Apollo, which we can see from bottom to top.
Why do we use Eureka as a service registry instead of the traditional zk, etcd? I roughly summarized the following reasons.
The above diagram briefly describes how the Apollo client is implemented.
apollo.refreshInterval
at runtime, in minutes.As mentioned earlier, Apollo client and server maintain a long connection to get the first push of configuration updates.
The long connection is actually implemented through Http Long Polling, specifically.
Considering that there will be tens of thousands of clients initiating long connections to the server, on the server side we use async servlet (Spring DeferredResult) to serve Http Long Polling requests.
The following table describes the availability of Apollo under different scenarios.
Scenario | Impact | Downgrade | Reason |
---|---|---|---|
One of config services goes offline | No effect | The Config service is stateless, and the client reconnects to other config services | |
All config services are offline | The client cannot read the latest configuration, and Portal has no effect | When the client restarts, the local cache configuration file can be read | |
One of admin services goes offline | No effect | The Admin service has no status, and Portal reconnects to other admin services | |
All admin services are offline | The client is not affected, and the portal cannot update the configuration | ||
One of portals goes offline | No effect | The portal domain name is bound to multiple servers through slb, and points to an available server after retrying | |
All portals are offline | The client is not affected, and the portal cannot update the configuration | ||
One of data center goes offline | No effect | Multi-data center deployment, data is fully synchronized, Meta Server/Portal domain name is automatically switched to other surviving data centers through slb |
Apollo is developed in open source mode from the beginning of development, so you are also very welcome to join in the interest and spare capacity of friends.
The server-side development is in Java, based on Spring Cloud and Spring Boot framework. The client side currently provides both Java and .
GitHub address: https://github.com/ctripcorp/apollo
Welcome to submit a Pull Request!