(network learning) 3. Seckill system and stress test

Time:2020-9-26

Course: PHP seckill design https://www.imooc.com/video/19863

1. Environmental preparation

a. Install the pressure measuring tool ab

sudo apt-get install apache2-utils -y

Limit under nginx_ Super detailed analysis of burst parameter in req module

b. Nginx environment configuration

#Create rules: limit current with IP, apply for 10m memory to store access frequency information, and the rate is 1 per second
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
#Application rule location {}: with the rule, the burst traffic can burst (2) queued, and then exceed the drop
limit_req zone=mylimit burst=2 nodelay;

nodelay:

  • If set, the ability to process (burst + rate) requests is provided instantaneously, > request exceeded(burst + rate)You’ll go straight back to 503, foreverDo not save > when the request needs to wait。 (the unit of rate here is R / s)
  • If not set, all requests are queued in turn

c. PHP environment

to update

cd /home/wwwroot/cluster
sed -ri "s/root\/tmp\/dk/home\/wwwroot\/cluster/g" `grep -rl "root\/tmp\/dk" .`
vim rec.php.sh #%s/php7\:1.10/php7\:1.11/g 
#Restart N3 (nginx with firewall) service

d. Environmental testing

Failed requests / complete requests

ab -n1000 -c50 'http://192.168.1.111:8084/index.html' //0/1000
ab -n1000 -c50 'http://192.168.1.111:8084/a.php' //0/1000
ab -n1000 -c50 'http://192.168.1.111/phpinfo.php' //724/1000

2. Problem analysis

Scene:

1. The inventory of a commodity is 1000
2. Read 100W concurrently
3. Concurrent purchase of 100W

Concurrent request received:

Withholding inventory = > create order = > 
    Payment = > Data Warehousing
    No payment within 10 minutes to cancel order = > roll back withholding inventory

a. Demand point analysis

1. Check inventory
curl 'http://192.168.1.111:8080/seckill/api.php?act=getStock&product_id=1&user_id=1'
ab -n1000 -c50 'http://192.168.1.111:8080/seckill/api.php?act=getStock&product_id=1&user_id=1'
       ____ The query function will cope with the maximum request pressure. The request falls on the PHP cache (APCU), and queries the redis library when there is no cache.

2. Deduction of inventory
curl 'http://192.168.1.111:8080/seckill/api.php?act=buy&product_id=1&user_id=1'
ab -n1000 -c50 'http://192.168.1.111:8080/seckill/api.php?act=buy&product_id=1&user_id=1'
    ____ (single commodity) deduction of inventory should be submitted to the second order. Parameters include: total inventory, pre-sale limit of the machine, number of local orders:
1、 Local pre-sale cache (APC_ LOCAL_ Use) plus current request (+ 1) to compare local pre-sale Inventory (APCU)_ LOCAL_ If it exceeds the limit, it will be rejected,
2、 Go to redis database to report in and see the total number of pre-sale (redis)_ REMOTE_ USE_ Is count less than total inventory (redis)_ REMOTE_ TOTAL_ COUNT)、
If it is not less than, it will be rejected,
3、 Add user information to order queue (redis_ REMOTE_ QUEUE)。

3. Synchronize inventory to local cache
curl 'http://192.168.1.111:8080/seckill/api.php?act=sync&product_id=1&user_id=1'
    ____ Synchronize local cache with redis data: total inventory on redis (redis)_ REMOTE_ TOTAL_ COUNT)、
Total pre sales (redis)_ REMOTE_ USE_ Count) minus the local pre-sale cache (APC)_ LOCAL_ If successful, the local pre-sale cache will be used
(APC_ LOCAL_ Clear and update local pre-sale Inventory (APCU)_ LOCAL_ STOCK)。

4. Empty local cache
curl 'http://192.168.1.111:8080/seckill/api.php?act=clear&product_id=1&user_id=1'
    ____ Clean up local cache APCU_ clear_ cache()。

5. Reset data
curl 'http://192.168.1.111:8080/seckill/api.php'

b. Application knowledge points

Inventory deduction synchronization core code:

//Give total presale + 1
$script = <<<eof
    local key = KEYS[1]
    local field1 = KEYS[2]
    local field2 = KEYS[3]
    local field1_val = redis.call('hget', key, field1) + 0
    local field2_val = redis.call('hget', key, field2) + 0

    if(field1_val > field2_val) then
        return redis.call('HINCRBY', key, field2, 1)
    end
    return 0
eof;
        return self::conRedis()->eval($script, [
            self::$REDIS_REMOTE_HT_KEY,
            self::$REDIS_REMOTE_TOTAL_COUNT,
            self::$REDIS_REMOTE_USE_COUNT
        ], 3);

Cache correlation function: APCU_ add; apcu_ inc; apcu_ store; apcu_ Dec
Redis: using Eval to execute Lua script

3. Stress testing

When the inventory deduction interface is highly concurrent, it will be limited by the performance of redis

a. Test results

First, turn off the software firewall. There is no firewall in the first two ports of 8080 / 8082 / 8084 of the local computer. The test results of docker in the virtual machine are as follows:

Using VM environment deepin15.11:
    mysql8 + docker_ nginx*1 + docker_ Redis master slave + docker_ php*3
[note]
-R solution: Apr_ socket_ recv: Connection reset by peer (104)
-The maximum number of c20000 clients is 2W by default
Interface parameter Complete requests Failed requests Time per request(ms) qps
Query: getstock -n1000-c50
-r-n100000-c10000
-r-n1000000-c20000
1000
100000
1000000
0
102015
1002026
12
10
10890
4037
4583
1836
Stock deduction: buy -n1000-c50
-r-n100000-c10000
-r-n1000000-c20000
1000
100000
1000000
0
100668
1001635
13
1964
13040
3719
5090
1533
Timing synchronization: sync -n1000-c50 1000 998 632 790

b.Test results of swote upgrade

The virtual machine uses docker_ Nginx + PHP: container NGX proxy 9500 to local port 9501.

/**[note]
 * 1.  php.ini  APCU does not support cli operation by default
 *      apc.enable_cli=1
 *2. Note that $request - > server ['request_ uri'] == '/ favicon.ico 'is intercepted
 *3. Nginx configuration: proxy_ pass     http://192.168.1.111 : 9501; give to the swote agent
 */

API 2.php test results:

Interface parameter Complete requests Failed requests Time per request(ms) qps
Query: getstock -n1000-c50
-r-n100000-c10000
-r-n1000000-c20000
1000
100000
1000000
0
98016
98497
2
582
593
17902
17164
16854
Stock deduction: buy -n1000-c50
-r-n100000-c10000
-r-n1000000-c20000
1000
100000
1000000
0
95958
1000000
2
660
13354
19005
15149
1497【cpu 99%】
Timing synchronization: sync -n1000-c50 1000 0 3 15702

c. Project summary

There is a real improvement in the rewriting of swote version. There is a change of thinking, and some extensions need to be debugged.

[ideas]
  Deal with high concurrency < = give full play to CPU performance mining < = business logic (computing, IO) separation and decoupling

Example and database code upload:
https://github.com/cffycls/seckill

[description]

  • Ordinary PHP FPM static:Not moving, CLI tool startup:Execute PHP api2.php(routed)
  • Code composer:vendor The directory is swote ide helper

Recommended Today

On the theoretical basis of SRE

What is SRE? When I first got into contact with SRE, many people thought that it was a post with full stack capability in Google and could solve many problems independently. After in-depth exploration, it is found that SRE can solve many problems, but there are too many problems. It is difficult for a post […]