background
We have some services, switching from JAVA to Node.js, so we need a good configuration center, Ctrip Apollo is great, JAVA language has official maintenance Client, great. There are several open source implementations for switching to Node.js, but it’s not perfect for us. Simple requirements:
- Hot updates are supported, and I don’t want to restart the server every time I change the configuration
- Preferably like Java @value(“mysql.port:3306”) a simple decorator can inject configuration
- Fault tolerance capability. For example, when the configuration center is down, the service can still be started normally. In the case that the configuration center is unavailable, the service can proactively recover the latest configuration startup project.
- Support the Typescript
Hence the birth of this project,
Introduction
-
This project is the Node.js version client provided by Ctrip configuration center Framework Apollo.
-
After the client connects successfully, it will pull a copy of all configurations to the local storage, which is mainly used for fault tolerance and degradation in the case of Apollo service unavailable.
-
Http long polling mechanism is used to achieve hot update, and the client will automatically modify the injected attribute value to achieve the configuration modification without restart.
-
You can get the latest configuration using the getConfigs() function;
-
Fault tolerance mechanism, Apollo service is not available in the case of the client will automatically resume the last configuration started.
Apollo server test environment:
- Host: http://106.54.227.205
- Account:
apollo
- Password:
admin
Features
- Configuring hot Update
- Support decorator @value(“mysql.port:3306”)
- The cache is configured locally
- Gray released
- Support the TypeScript
Install
npm i ctrip-apollo-client
Copy the code
Usage
- This demo has created a project apolloclient in the test environment, you can directly test locally;
- After the user. Name value is changed in the configuration center, the latest value is automatically obtained without restart.
- The demo source code.
import { CtripApplloClient, value, hotValue } from 'ctrip-apollo-client';
import Koa from 'koa';
const apollo = new CtripApplloClient({
configServerUrl: 'http://106.54.227.205:8080',
appId: 'apolloclient',
configPath: './config/apolloConfig.json',
namespaceList: ['application'.'development.qa']});const app = new Koa();
const run = async() = > {// Initialize the configuration
await apollo.init();
// The obtained configuration is not hot updated
const port = apollo.getValue('app.port:3000');
// To obtain the configuration, support hot update, need to obtain the final value through appname. value
const appName = hotValue('app.name:apollo-demo');
class User {
// Support hot update via decorator injection
// Only class attributes can be injected
@value("user.name:liuwei")
public name: string
}
const user = new User();
app.use(async (ctx, next) => {
ctx.body = {
appName: appName.value,
userName: user.name
}
await next();
})
app.listen(port);
console.log('listening on port:', port);
console.info(`curl --location --request GET \'http://localhost:${port}\' `);
}
run();
Copy the code
Javascript Demo please click the link
API
ApolloClient(Options) constructor
- returns:
apolloClient
- options
- configServerUrl
string
required
Apollo Specifies the address of the configuration service - appId
string
required
Application of the appId - clusterName
string
Cluster name, default:default
- namespaceList
array
The name of the Namespace. Default:[application]
- configPath
string
Default value of the local configuration file path./config/apolloConfig.json
- logger
object
Logging classes must be implementedlogger.info()
.logger.error()
Two methods
- configServerUrl
Init (timeoutMs) Initializes the configuration center, pulls the remote configuration to the end, and caches the configuration to a file. At the same time, the configuration change listener is enabled to synchronize the configuration in real time. If the pull exceeds the timeoutMs or an exception occurs, the local cache configuration file is read. If there is no cache configuration file locally, an exception is thrown.
- return: Promise
- TimeoutMs Specifies the timeout period
GetConfigs () gets the latest configuration file
- returns:
object
const config = apollo.getConfigs();
Copy the code
GetValue (Namespace = ‘application’) Gets the specific configuration field
- returns:
string
- Namespace Default value:
application
- field
string
eg:mysql.port:3306
If 3306 is not configured as the default value
class User {
get userName () {
return apollo.getValue({ field: 'user.name:liuwei'}); }}Copy the code
HotValue (Namespace = ‘application’) gets the specific configuration field, encapsulates the getter(hot update)
- returns:
{value}
- Namespace Default value:
application
- field
string
Attribute location eg:mysql.port:3306
If 3306 is not configured as the default value
const userName = apollo.hotValue({ field: 'user.name:liuwei' });
console.log(userName.value);
Copy the code
withValue(target, key, field, namespace)
- returns:
void
- Target Target object
- Key requires the properties of the object to be injected
- field
string
Attribute location eg:mysql.port:3306
If 3306 is not configured as the default value - namespace
string
Default value:application
class User {
constructor () {
withValue(this, 'userId', { field: 'user.id:10071'}); }} // The userId property is updated with the configuration new User().useridCopy the code
OnChange (callback(object)) Configuration change callback notification
- returns:
void
Value (Field, namespace) injector that can only inject class attributes
- field
string
The field properties - namespace
string
import { value } from 'ctrip-apollo-client';
class User {
@value("user.name:liuwei")
public name: string
}
Copy the code
Benchmark
[localValue] x 736,896,802 ops/ SEC ±1.49% (82 runs time)
Support hot update [hotValue] x 2021,310 OPS/SEC ±1.28% (87 runs time)
[hotValue default] x 1,581,645 OPS/SEC ±0.89% (87 runs sampled)
[decorator] x 2,161,312 ops/ SEC ±0.96 percent (87 runs sampled)
[dot] x 704,644,395 ops/ SEC ±1.45% (82 runs sampled)
Fastest is [localValue]
License
MIT
Program source code
Github.com/lvgithub/ct…