Don’t know how to do configuration management? Full marks engineering to teach you step by step!

Don’t know how to do configuration management yet? Full marks engineering to teach you step by step!

Follow me and I’ll teach you something useful

A while ago, I promised the kids in the front-end group that I would share some experiences related to enterprise-level front-end engineering. It has been delayed for almost two months. If I delay any longer, I will probably lose fans.

So let’s start talking about front-end engineering today. Let’s start with Configuration Management.

This part is very practical. If you can help your team do this well, everyone will look at you with admiration. Whether it is on your resume or in your promotion defense, it will be a good piece of content to talk about.

Without further ado, let’s get straight to the point.

Recall your project, is there any similar code:

php copy code // Create an S3 instance
const s3 = new S3({
  // Omit some parameters
  accessKeyId: 'xxxxx',
  secretAccessKey: 'xxxx',
})

There is no need to worry about what S3 is. It is not important. What is important is that, similar to the above, certain important parameters (such as keys, IPs, names, etc.) are written in clear text in the code. The way.

If your project has similar code, congratulations, your chance to become famous is here!

There’s a technical term for this ugly coding style: Hardcoding. As the name suggests, it is a coding method that makes people feel stiff after reading it.

image.png

Hahaha, just kidding, the hard-coded noun explanation is this:

Hard coding is the software development practice of embedding data directly into the source code of a program or other executable object, as opposed to obtaining data from outside or generating data at runtime.

What’s wrong with hard coding? There are probably several types:

  • Security issues. Sensitive information is placed in the code. Once the code is open sourced or the private code is reverse engineered, serious information leakage problems will occur.
  • Cost of change. Every time you need to adjust the configuration information, such as changing the key, changing IP/port and other parameters, you have to go through the release process again, which is extremely costly.
  • Code reuse. In the case of multiple deployments, it is almost impossible to reuse code, and it is also difficult to perform personalized deployment.

So what should a slightly more normal code look like? It probably looks like this:

arduino copy code // Create an S3 instance
const s3 = new S3({
  // Omit some parameters
  accessKeyId: process.env.AK,
  secretAccessKey: process.env.SK,
})

Corresponding server environment variables:

In this step, the hard-coded key is changed to read from the environment variable (process.env), which seems much more advanced. This is the simplest configuration stripping, which basically makes the code configurable.

Doesn’t it look better?

NO, NO, NO! Where is this? This slash-and-burn configuration management method has too many problems:

  • Low release stability. Each set of deployments needs to independently maintain its own environment variables. If you forget to modify a container during release, big problems will occur, so each release requires a long CheckList.
  • Low fault tolerance. It’s completely string editing. If there are multiple spaces, line breaks, etc., the entire configuration will be useless.
  • Missing permission. There is no permission management specifically for configuration. Anyone can make changes. There is no operation record after the change. If something goes wrong, you don’t know who to blame.
  • No version concept. Without version management, once a problem occurs, there is no way to quickly roll back.

People who have read my previous articles should know me to some extent. Musha prefers to sort out solutions to problems from a macro level, so as to solve problems more elegantly and completely.

You may be anxious: Teacher Mu, please stop being so pushy, Talk is Cheap, show me your code!

OK, without further ado, here’s the architecture diagram!

It’s okay if you don’t understand it right now. I’m just going to let you know for a while. I’ll explain it to you step by step later.

First, we focus on the upper right corner of the architecture diagram. There is a Remote Config here:

Remote Config (remote configuration), as the name suggests, abandons the slash-and-burn method of putting configurations into environment variables as mentioned above, and uses a relatively mature configuration management system for management, similar to so:

(This is Tencent’s internal configuration system: Colorful Stone)

A mature configuration system should look like this. It can very conveniently manage all configurations of the project, by environment, grouping, permission control, release approval, logs, version rollback and other functions.

This is a modern configuration management method!

If your company does not have a self-developed configuration center, you can also choose some mature products on the market, such as Nacos, Apollo, Spring Cloud Config, etc.

Of course, this is not the focus of this article, so we won’t talk more about it.

Then look down, and now move your eyes to the bottom of the architecture diagram (CI write configuration):

In order to ensure that the service can get the configuration file when it starts, we need to pull the configuration from the remote end in advance during CICD, write it to the file, and package it into the service image.

At this time you have to ask, it may take a long time to wait from CI to CD. In addition to the long build time, there may be some longer approval waiting links, or What should I do if the configuration changes during this period of delayed release? Our configuration files are packaged in advance!

Don’t worry, the solution is here! Return to the upper right side of the architecture diagram:

After the service is deployed and officially started, it first performs the configuration initialization operation (initConfig), pulls the latest configuration from the remote configuration center to the server, and integrates it with the old configuration (Combination ), doesn’t this solve the problem of outdated configuration that you were worried about just now?

At the same time, we need to have a good habit of saving this latest configuration as a file locally on the server:

This step may seem like a redundant backup operation, but in fact it is a backup operation for system stability. In case the remote configuration center is down (we have no control over whether others are down, we can only ensure it as much as possible). If you don’t die by yourself), then this back-up document is crucial at this time! The code implementation is similar to this:


javascript copy code const fetchRainbowConfig = async () => {
  try {
    //...omit part of the code
    // Pull the latest configuration from the remote configuration center
    const config = await rainbowInstance.getGroup();
    const configPath = path.join(__dirname, `../../.env/${RAINBOW_GROUP || 'dev'}`);
    //Write to local file
    fs.writeFileSync(configPath, JSON.stringify(config));
    return config;
  } catch (error) {
    console.error('fetch rainbow group config fail!Try to fetch from local');
    // Back-to-back operation, read from local configuration file
    return fetchConfigFromLocal();
  }
}

finished? Well, it’s actually a pretty good project to have reached this point, but I’m not satisfied yet! This is at best an 80-point project.

Let’s continue optimizing and move our attention to the lower right corner of the architecture diagram (Config Watcher):

We add a configuration listener (Config Watcher), what is it used for?

If you are smart, it should not be difficult to understand. This listener can monitor remote configuration updates in real time, thereby achieving configuration hot update. In some scenarios, configuration changes no longer require re-publishing the service. .

For example, one day an online logic bug occurs and an emergency announcement needs to be issued. At this time, there is no need to change the code or go through the long CICD process again. You only need to add an announcement field to the configuration system and modify the field when an announcement needs to be issued. The server The configuration listener on the system will detect the update and immediately hot update it into the memory.

Isn’t he so handsome? I’m willing to give it a hundred points!

That’s right, once you reach this point, the configuration management module of this system is quite mature, with both certain disaster recovery capabilities and considerable agile capabilities. And it is highly readable and very easy to maintain! Who doesn’t say hello after using it?

Well, Musha has given you a mature and excellent enterprise-level configuration management solution.

Are you a loser in school?

image.png