HI! Hello, I’m Zane. ZanePerfor is a front-end performance monitoring platform developed by me. It now supports web browser side and wechat applet side.

I define it as a complete, high performance, high availability front-end performance monitoring system, which is the goal that will be achieved in the future. The current architecture also basically supports high availability, high performance deployment. In fact, it is not enough. There is still room for improvement in many places. I will continue to improve and upgrade.

Open source is not easy, if you also love technology, embrace open source, hope to give a small support to a star.

Github address of the project: github.com/wangweiange…

Project documentation: blog.seosiwei.com/performance…


ZanePerfor applications can theoretically support pv projects in the tens of millions, but the actual situation depends on the performance of the server and database. The following items can improve the performance of the application in various configurations as much as possible.

Note: The following is illustrated and illustrated by selecting the Redis message queue.


I. Description of related project configuration items

Config.default. js Configuration descriptionCopy the code

In servers cluster mode, servers mainly communicate with each other through the internal network. Therefore, hostname needs to be set to the internal IP address and the following changes can be made

Config. Cluster = {listen: {port: config.port, hostname: address.ip(), // replace 127.0.0.1 IP: address.ip(), }, };Copy the code


2. The time of real-time statistics task should be as long as possible under heavy traffic projects, which can not only reduce the pressure of database but also improve the accuracy of real-time statistics (the time interval of periodic task is recommended to be between 5-20 minutes).

// Interval for executing scheduled pvuVIP tasks By default, the interval for executing scheduled pvuVIp_task_minute_time = is once every minute'0 */1 * * * *'; // Change to config.pvuvip_task_minute_time ='0 */10 * * * *';Copy the code


3. Redis is used to report and consume data

// Use Redis, Kafka, or mongodb to store raw data config.report_data_type ='redis'; // redis  mongodb  kafkaCopy the code


4. Under the condition that the database performance is strong enough, the time of each scheduled task should be as short as possible, the data consumption should be as large as possible, and the message queue pool should be as unlimited as possible

Config. redis_consumption = {// Execution time of scheduled tasks task_time:'*/10 * * * * *', // Number of threads consumed per scheduled task (web) thread_wx: 2000, // Number of threads consumed per scheduled task (wX) thread_wx: 2000, // Number of message queue pool limits, 0: no limit number: Total_limit_web: 0, total_limit_wx: 0,};Copy the code
  • Task_time Interval between scheduled tasks to consume messages

  • Thread_wx Number of data items consumed at a time

  • Total_limit_wx Limits the total number of messages in the queue

The above configuration indicates that 2000 data items are consumed every 10 seconds. There is no limit on the number of data items reported. (If type: ‘all’ is set for a scheduled task, the number of data items consumed is multiplied.)


5. Use Redis to resolve user IP addresses and disable file cache (Note: In case of heavy traffic, data stored in local files is large and each load takes time)

Ip_redis_or_mongodb ='redis'; // redus mongodb // Location of the cache IP address (file name) config.ip_city_cache_file = {isuse:false, // Whether to enable local file caching (do not enable this function when the data volume is too large) Web:'web_ip_city_cache_file.txt',
    wx: 'wx_ip_city_cache_file.txt'};Copy the code


6. In mongodb cluster mode, the URL must be changed to the internal IP address, and the connection pool can be slightly larger

// mongodb service const dbclients = {db3: {//'mongo: / / 192.168.1.10:30000 / performance',
        options: {
            autoReconnect: true,
            poolSize: 50,
        },
    },
};Copy the code


Two: HTTP level description (the following content has been implemented in the program)

1. Set Connection and disable keep-alive

Why was it closed?

  • In high concurrency projects, TCP hold time should not be too long, so nginx keepalive_timeout should be set as short as possible
  • Keepalive_timeout should be set as low as possible to reduce the TCP connection time for HTTP links with low request frequency and few requests in the same domain

For this application, both of the above are met, so the keep-alive option is disabled.

// Node service implementation: ctx.set('Connection'.'close'); // nginx service implementation: HTTP {keepalive_timeout: 0; }Copy the code


2. Return empty body information

  • The reporting interface will return the status code as soon as possible after receiving the request, and the logical processing will be processed later
  • The body return should be short or empty
// Code implementation: asyncwxReport() {
    const { ctx } = this;
    ctx.set('Access-Control-Allow-Origin'.The '*');
    ctx.set('Connection'.'close'); ctx.status = 200; //... }Copy the code


Three: Node single-node cluster

Use the Cluster module of Node.js to start multi-process, drain server resources as much as possible, and take advantage of the concurrency advantage of multi-core CPU. At the same time, it also ensures the stability of single machine service.

Egg.js provides a multi-process model and interprocess communication.

Portal: eggjs.org/zh-cn/core/…

Opening mode:

// Apply package.json // In this case, two worker processes will be enabled, which will enable several worker processes in the server CPU core by default"scripts": {
    "start": "egg-scripts start --daemon --workers=2 --title=performance",}Copy the code


4. Build the Mongodb cluster

The construction of mongodb cluster is indispensable for high-traffic and high-concurrency projects. Please refer to the following two articles about the construction of mongodb cluster:

ZanePerfor high availability of Mongodb cluster sharding architecture for front-end performance monitoring platform

ZanePerfor a highly available read-write separation architecture for Mongodb replica sets for front-end performance monitoring platforms

Example: There are three servers with Intranet IP addresses: (10.1.0.86, 10.1.0.97, and 10.1.0.70). Now we set up a cluster consisting of three servers.

1. Create the following three files on each server

kdir -p /data/mongod/s0
mkdir -p /data/mongod/log
mkdir -p /data/mongod/c0Copy the code

2. Start the Shard Server on each Server

mongod --dbpath /data/mongod/s0 --logpath /data/mongod/log/s0.log --fork --smallfiles --port 27020 --bind_ip 10.1.0.86 --shardsvr
mongod --dbpath /data/mongod/s0 --logpath /data/mongod/log/s0.log --fork --smallfiles --port 27020 --bind_ip 10.1.0.97 --shardsvr
mongod --dbpath /data/mongod/s0 --logpath /data/mongod/log/s0.log --fork --smallfiles --port 27020 --bind_ip 10.1.0.70 --shardsvrCopy the code

3. Start Config Server on each Server

mongod --dbpath /data/mongod/c0 --logpath  /data/mongod/log/c0.log --fork --smallfiles --port 27100 --bind_ip 10.1.0.86 --replSet rs1 -- configSvr mongod --dbpath /data/mongod/c0 --logpath /data/mongod/log/c0.log --fork --smallfiles --port 27100 --bind_ip 10.1.0.97 --replSet rs1 -- configSvr mongod --dbpath /data/mongod/c0 --logpath /data/mongod/log/c0.log --fork --smallfiles --port 27100 -- bind_IP 10.1.0.70 --replSet rs1 -- configSvrCopy the code

4. Configure the replica set

// Enter mongo mongo --port 27100 --host 10.1.0.97 // Use admin to initialize replica set rs.initiate({_id:"rs1",members:[{_id:0,host:"10.1.0.97:27100"},{_id:1,host:"10.1.0.86:27100"},{_id:2,host:"10.1.0.70:27100"}]}) // Check the replica set status rs.status()Copy the code

5. Start the Route Process service

mongos  --logpath /data/mongod/log/ mongo. Log - port 30000 - bind_ip 10.1.0.97 - fork - configdb rs1/10.1.0.97:27100 ration. 0.86:27100 ration. 0.70:27100Copy the code

6. Configure Sharding fragments

Mongo --port 30000 --host 10.1.0.97 // Add sh.addshard ("10.1.0.97:27020")
sh.addShard("10.1.0.86:27020")
sh.addShard("10.1.0.70:27020"Sh.status ();Copy the code

7. Set the shard database and key

Sh.enablesharding ("performance") / / create indexes (need to build to create an index) the wx_ajaxs_wx3feeea844b1d03ffs. EnsureIndex ({"path":1}) // Set sharding (shards the performance database wx_ajaxs_wx3FeEEA844b1d03FFS table hx_ajaxs_wx3FeEEA844B1d03FFS table hx_ajaxs_wx3FeEEA844B1d03FFS table hashed according to the path field) sh.shardCollection("performance.wx_ajaxs_wx3feeea844b1d03ffs", { "path": "hashed"} sh.status()Copy the code

Repeat the above steps for other table fragments, and a simple 3-server cluster is set up.

Note: When sharding mongodb, bind the internal IP address; otherwise, requests cannot be connected.

Note: applications to the browser side | WeChat shard by default use _id field small program end, try not to change.





5: Servers load balancing

Servers load: Distributes all reported requests to different Servers for processing, reducing the stress on the individual Servers as well as the stress on the individual servers.

  • ZanePerfor implements a code multi-service deployment solution

  • An application ensures that tasks are not executed repeatedly when multiple services are running simultaneously

The servers load balancing scheme is nginx. The ng configuration is as follows:

Upstream ps-Servers {server 10.1.0.86:7001 weight=1 max_fails=4 fail_timeout=5; Server 10.1.0.97:7001 weight=1 max_fails=4 fail_timeout=5; Server 10.1.0.70:7001 weight=2 max_fails=4 fail_timeout=5; }Copy the code

Parameter Description:















Six: Redis cluster

Many applications rely on redis caching capabilities, so a high performance Redis or Redis cluster is necessary.

High performance – Redis can read 110,000 times /s and write 81,000 times /s, theoretically speaking, a single Redis can meet the majority of applications.

As for whether Redis needs cluster support, it needs to be decided according to the situation of each application. The single Redis used by the blogger temporarily has no performance problems within 500W PV.

IO /topics/clus…


ZanePerfor Architecture Configuration for High Traffic Projects recommended practice notes (End).