Preface
The number of user visits to malls or web sites unexpectedly increased a lot, exceeding the load capacity of the system, and the system could not withstand it, which led to the bet.
All the books, orders, payments, etc. are stuck in circles, which leads to the loss of many users and orders in the company's business. .
1. Introduction
Faced with a large wave of unexpected influx of visits and exceeding the normal load range of the system, we can use downgrade to deal with it. What is downgrade? It means blocking unimportant services and functions, reducing real-time, delaying processing, etc., and the ultimate goal is to ensure that the core services are available.
2. What is downgrading, why downgrading, and the downgrading scenario?
The ultimate goal of downgrade is to ensure high availability of core services. The process is to lose the patriarch and protect the commander. Some services cannot be downgraded, such as payment.
When our servers increase dramatically, in order to ensure the availability of core functions, selectively reduce the availability of some functions, or directly turn off the function.
This is a typical example of losing a car to keep your handsome guy. For example, when the server cannot bear it, you can choose to turn off the posting function, turn off the registration function, change the password, and change the avatar. In order to ensure the core functions of login and browsing posts.
The principle of downgrade: it is to reduce the usability and practicality of secondary functions and increase the high availability of core functions.
The implementation principles of downgrade are diverse.Use a downgrade switch and use this switch as the basis for judgment to switch the data acquisition method. For example, when the load of mysql is high, you can switch from mysql to redis, such as from redis to static files, such as from new versions with frequent errors to old versions, etc. This switch is configured according to the current situation. For example, when new versions frequently occur, we can configure this switch to obtain data from the old version.
III. Types of downgrades
-
According to the downgraded switch position: divided into service code downgrading and switch pre-downgradingCode downgrade is to use code control, this method is lower than pre-degradation and is not recommended.
The pre-degradation is to place the downgrade switch upstream of the http request link layer to reduce link layer consumption. For example, it can be improved to nginx, or even to the front
When lifted to the front end, the access pressure of the back end is close to 0
Expand: [How to improve to the front end]
It can be controlled through a js script obtained from the server.
- According to read and write: it is divided into read downgrade and write downgrade.
Reading downgrades, for example, reading dynamic data, downgrades to reading static data. Write downgrade,
For example, writing to mysql is downgraded to writing to a message queue, and after the peak period, mys is written from the queue.
- According to the nature of the downgrade: it is divided into return content downgrade, current downgrade, and speed downgrade.
Return content downgrade, for example, return real-time data, downgrade to return bottom-line data, and downgrade,
For example, for 1000 requests, I only accept 500. Doing this is also a choice in desperation, otherwise the system will crash and no one can access it. Speed limit downgrades.
For example, speed limit is required for IPs that are accessing too frequently
Expand: [current limit and speed limit]
nginx comes with current and speed limits, such as ngx_http_limit_req_module and ngx_http_limit_conn_module. However, this type of module only provides simple parameter configuration in nginx configuration file. If you want to be more flexible and more functional, you can write your own Lua code for control instead of using ready-made modules to modify configuration files.
4.According to the maintenance characteristics of downgrade: divided into manual downgrade and automatic downgradeManual downgrade is to manually adjust the downgrade after seeing abnormal system load.
Automatic downgrade is the automatic downgrade after the system monitors an exception. Although automatic downgrade is more intelligent, sometimes automatic scripts may do something beyond expectations.
IV. Business Analysis
As we all know, the characteristics of the advertising recommendation module:
1. It is necessary to conduct a large amount of analysis of the data model and combine the user's browsing history just now to calculate what products the user likes and then call him what he calls
Advertising, the calculation volume is quite large.
2. It is an advertising recommendation module, not the core module of the mall. Without this module, buyers can still complete the purchase of products.
To summarize the above two points, we can downgrade the ad recommendation module when the mall is loading too high, so that it can only read data from cached or static files, or
The slightest nginx does not return any data to it.
V. Design Analysis
The first type: from the data
The second type: from microservices
The third type: from cache
The fourth type: from the file
The fifth type: Return from the front end
The sixth type: return to empty directly
The first five ways to obtain advertising recommendation data, from top to bottom, gradually reduce the performance loss to the system. The bottom fifth type has almost no loss to the system, but the real-time data is also gradually decrease from top to bottom. From a demand point of view, we prefer to read from the database in real time, but in order to reduce performance loss, when the system is loaded, we may have to downgrade to reading from files or from cache. This downgrade can be controlled by a switch.
6. Degraded circuit diagram
1 Downgrade configuration center, a downgrade switch for unified management of all microservices. The center is a separate server, and is separated from the microservice server cluster 2
Each microservice has a downgrade switch.
What is this downgrade switch and what is the structure?In fact, it is a piece of redis data, and each piece of data is a switch.
The structure of this switch data is designed like this:
key: the request address in the url link.
value: record where this request reads data, that is, where to configure the query data.
7. Degradation
1. Configuration Center
The configuration center is a backend, and everyone implements this configuration center according to their own needs. Here we use manual operation of redis, which is actually
Redis operated through the background.
2. nginx+lua+redis achieves downgrade
nginx configuration file /etc/nginx/
user nobody; worker_processes 1; events { luaDowngrade code:/etc/nginx/lua/goods_list_advert.lua worker_connections 1024; } http { lua_package_path "/usr/share/lua/5.1/lua-resty-redis/lib/?.lua;;/usr/share/lua/5.1/lua- resty-redis-cluster/lib/resty‘7/?.lua;;"; lua_package_cpath "/usr/share/lua/5.1/lua-resty-redis-cluster/lib/libredis_slot.so;;"; include ; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name 127.0.0.1; server_name 192.168.232.100; #Get ad recommendation data location /goods_list_advert { default_type 'application/x-javascript;charset=utf-8'; content_by_lua_file /etc/nginx/lua/goods_list_advert.lua; } #Get data from service layer + mysql location /goods_list_advert_from_data { default_type 'application/x-javascript;charset=utf-8'; content_by_lua ' ("Get data from service layer + mysql") '; } } }
lua downgrade code: /etc/nginx/lua/goods_list_advert.lua
--Getgetorpostparameter-------------------- local request_method = .request_method local args = nil local param = nil --Getparameter的值 if "GET" == request_method then args = .get_uri_args() elseif "POST" == request_method then .read_body() args = .get_post_args() end sku_id = args["sku_id"] --closureredisFunctions of-------------------- local function close_redis(redis_instance) if not redis_instance then return end local ok,err = redis_instance:close(); if not ok then ("close redis error : ",err); end end --connectredis-------------------- local redis = require(""); --local redis = require "redis" -- Create aredisObject instance。In failure,returnniland in the case of a string describing the error local redis_instance = redis:new(); --Set the timeout for subsequent operations(In milliseconds)Protect,includeconnectmethod redis_instance:set_timeout(1000) --建立connect local ip = '127.0.0.1' local port = 6379 --尝试connect到redisRemote host and port the server is listening on local ok,err = redis_instance:connect(ip,port) if not ok then ("connect redis error : ",err) return close_redis(redis_instance); end --fromredisRead switch inside-------------------- local key = "level_goods_list_advert" local switch, err = redis_instance:get(key) if not switch then ("get msg error : ", err) return close_redis(redis_instance) end --The resulting switch is empty-------------------- if switch == then switch = "FROM_DATA" --For example, the default value end --当开关是要from服务中Get数据时-------------------- if "FROM_DATA" == switch then ('/goods_list_advert_from_data'); --当开关是要from缓存中Get数据时-------------------- elseif "FROM_CACHE" == switch then local resp, err = redis_instance:get("nihao") (resp) --当开关是要from静态资源中Get数据时-------------------- elseif "FROM_STATIC" == switch then .content_type="application/x-javascript;charset=utf-8" local file = "/etc/nginx/html/goods_list_advert.json" local f = (file, "rb") local content = f:read("*all") f:close() (content) --当开关是要停掉数据Get时-------------------- elseif "SHUT_DOWN" == switch then ('no data') end
8. Verification downgrade
Verification 1 is set to read from the service and database
[root@101 redis-5.0.8]# redis-cli
127.0.0.1:6379> set level_goods_list_advert FROM_DATA
Send a request and find that the ad recommendation request has obtained the data provided by the microservice
Use postman: http://127.0.0.1:6379/get_goods_List
Return data: [{"name":["bingwoo"]}]
Verification 2 is set to read from cache
127.0.0.1:6379> set level_goods_list_advert FROM_CACHE
Send a request and find that the ad recommendation request has obtained the data provided by the microservice
Use postman: http://127.0.0.1:6379/get_goods_List
Return data: redis_data
Verification 3 Set to read from static files
127.0.0.1:6379> set level_goods_list_advert FROM_STATIC
Send a request and find that the ad recommendation request has obtained the data provided by the microservice
Use postman: http://127.0.0.1:6379/get_goods_List
Return data:
[ { “goods_id”:“1”, “goods_name”:“test1”, }, { “goods_id”:“2”, “goods_name”:“test2”, } ]
Verification 4 Set to read from cache
127.0.0.1:6379> set level_goods_list_advert FROM_CACHE
Send a request and find that the ad recommendation request has obtained the data provided by the microservice
Use postman: http://127.0.0.1:6379/get_goods_List
Return data: null
9. Automatic downgrade
principle:
Use nginx+lua+redis to count the error return. When the counted errors reach a certain value, lua will judge this value, and then add the following code to /etc/nginx/lua/goods_list_advert.lua:
--Response to the error,And count, You can refer to this value for downgrading in the future if tonumber() == 200 then () (,"upstream reponse status is " .. .. ",please notice it") local error_count, err = redis_instance:get("error_count_goods_list_advert") --The resulting data is processed empty if error_count == then error_count = 0 end error_count = error_count + 1 --The number of statistics errors has arrivederror_count_goods_list_advert local resp,err = redis_instance:set("error_count_goods_list_advert",error_count) if not resp then ("set msg error : ",err) return close_redis(redis_instance) end end
When we intentionally turn off some services so that the status code is not 200,
You can see that the value of error_count_goods_list_advert in redis is added by 1:
127.0.0.1:6379> get error_count_goods_list_advert “1”
Next, you can add judgment in lua, for example, set a threshold to 100. When the value of error_count_goods_list_advert reaches 100 (that is, when the error returns to reach 100), you can downgrade to request another version (old version of the program)
This is the article about the sample code for nginx+lua+redis downgrade. For more related nginx+lua+redis downgrade content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!