Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the method of implementing Nginx weighted polling algorithm by Go?

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article is about Go to achieve Nginx weighted polling algorithm is what, the editor thinks it is very practical, so share it with you to learn, I hope you can get something after reading this article, say no more, follow the editor to have a look.

First, polling of Nginx load balancer (round-robin)

Before we talk about weighted polling, let's talk about polling briefly.

1. The configuration upstream cluster in nginx {server 192.168.0.14; server 192.168.0.15;} location / {proxy_set_header X-Real-IP $remote_addr; / / returns the real IP proxy_pass http://cluster; / / proxy points to cluster} 2. A brief introduction

Polling is a basic algorithm in load balancing, and its implementation does not need to configure additional parameters. Simple understanding: a total of N servers are configured in the configuration file, and the polling algorithm traverses the list of nodes for the service, and selects one server for each round according to the order of the nodes to process the request. When all the nodes are traversed, start again.

3. Characteristics

In the polling algorithm, it is not difficult to see that the number of requests processed by each server is basically the same, and it is allocated one by one according to the request time, so it can only be applied to the situation where the performance of cluster servers is similar, and the average distribution makes the carrying capacity of each server basically the same. However, if the performance of the cluster server is uneven, such an algorithm will lead to unreasonable resource allocation, blocking some requests and wasting some server resources. In order to solve the above problems, we upgrade the polling algorithm and introduce the weighted polling algorithm, so that the servers with different performance in the cluster can allocate resources reasonably. To maximize the rational use of resources

4. Implement (here using golang simulation) type RoundRobinBalance struct {curIndex int rss [] string} / * * @ Author: yang * @ Description: add service * @ Date: 15:36 on 2021-4-7 * / func (r * RoundRobinBalance) Add (params... string) error {if len (params) = 0 {return errors.New ("params len 1 at least")} addr: = params [0] r.rss = append (r.rss) Addr) return nil} / * @ Author: yang * @ Description: polling for obtaining service * @ Date: 15:36 on 2021-4-7 * / func (r * RoundRobinBalance) Next () string {if len (r.rss) = = 0 {return ""} lens: = len (r.rss) if r.curIndex > = lens {r.curIndex = 0} curAdd: = r.rss [r. CurIndex] r.curIndex = (r.curIndex + 1)% lens return curAdd} 5. test

Simply call the method to see the result

/ * * @ Author: yang * @ Description: test * @ Date: 15:36 on 2021-4-7 * / func main () {rb: = new (RoundRobinBalance) rb.Add ("127.0.0.1Description") rb.Add ("127.0.0.1Description 81") rb.Add ("127.0.0.1Ze82") rb.Add ("127.0.0.1Ze83") Fmt.Println (rb.Next ())} go run main.go 127.0.0.1 fmt.Println (rb.Next)} go run main.go 127.0.0.1 Weighted polling (weighted-round-robin) for Nginx load balancing

Get to the topic

1. Nginx configuration http {upstream cluster {server 192.168.1.2 weight=5; server 192.168.1.3 weight=3; server 192.168.1.4 weight=1;} location / {proxy_set_header X-Real-IP $remote_addr; / / returns the real IP proxy_pass http://cluster; / / Agent points to cluster} 2. Introduction to weighting algorithm-Featur

The configuration of different servers, the number of applications deployed, the status of the network and so on will lead to different processing capacity of the server, so the simple polling algorithm will no longer be applicable, but the weighted polling algorithm is introduced: according to the different processing capacity of the server, assign different weights to each server, and assign different servers to the corresponding servers according to different weights.

When the number of requests is large, the ratio of the number of requests processed by each service tends to the ratio of weight.

3. Algorithm description

In Nginx weighted polling algorithm, each node has three weighted variables.

Weight: configured weight, initializing the weight of each server node according to the configuration file

CurrentWeight: the current weight of the node, which is the configured weight when initialized, and then changes all the time.

EffectiveWeight: valid weight. The initial value is weight. If an exception is found in the node during communication,-1 is found, and then the node is selected again. After a successful call, the node is + 1 until it is restored to weight. This parameter can be used to make descending weights. Or the permission correction of your settings.

Logical implementation of Nginx weighted polling algorithm

Poll all nodes and calculate the sum of the effectiveWeight of all nodes in the current state as totalWeight

Update the currentWeight of each node, currentWeight = currentWeight + effectiveWeight; select the largest node of all nodes currentWeight as the selected node

The selected node updates currentWeight again, currentWeight = currentWeight-totalWeight

4. A simple example

Note: health check is not considered in the implementation, that is, all nodes are 100% available, so effectiveWeight equals weight

Suppose: there are 3 nodes {A, B, C} with weights of {4, 2, 1}; 7 requests.

Before the Nth request, currentWeight selected nodes currentWeight1 [serverA=4, serverB=2, serverC=1] serverA [serverA=1, serverB=4, serverC=2] 2 [serverA=1, serverB=4, serverC=2] serverB [serverA=5, serverB=-1, serverC=3] 3 [serverA=5, serverB=-1, serverC=3] serverA [serverA=2, serverB=1, serverC=4] 4 [serverA=2, serverB=1, serverC=4] serverA [serverA=2, serverB=1, serverC=5] 5 [serverA=-1, serverB=3, serverC=5] serverC [serverA=3, serverB=5, serverC=-1] 6 [serverA=3, serverA=3, serverB=5] serverB=5 [serverC=-1, serverC=-1, serverC=-1] 7 [serverC=-1 ServerC=0] serverB [serverA=4, serverB=2, serverC=1]

TotaoWeight = 4 + 2 + 1 = 7

The first request: serverA= 4 + 4 = 8, serverB= 2 + 2 = 4, serverC= 1 + 1 = 2; the largest is serverA; so select serverA; then serverA= 8-7 = 1; finally, serverA=1, serverB=4, serverC=2

The second request: serverA= 1 + 4 = 5; serverB= 4 + 2 = 6; serverC= 2 + 1 = 3; the largest is serverB; so select serverB; then serverB= 6-7 =-1; finally, serverA=5, serverB=-1, serverC=3

And so on.

5. Code implementation

Implement the above logic with golang:

The weight of type WeightRoundRobinBalance struct {curIndex int rss [] * WeightNode} type WeightNode struct {weight int / / configuration, that is, the weight of each node agreed upon in the configuration file or initialization currentWeight int / / the current weight of each node, will always change the effectiveWeight int / / effective weight. The initial value is weight. If a node exception is found during communication,-1 is found, and then the node is selected again. After a successful call, + 1 is returned to weight. Used for health check, deal with abnormal nodes, and reduce their weight. Addr string / / server addr} / * * @ Author: yang * @ Description: add service * @ Date: 15:36 on 2021-4-7 * / func (r * WeightRoundRobinBalance) Add (params... string) error {if len (params)! = 2 {return errors.New ("params len need 2")} / / @ Todo get the value addr: = params [0] parInt, err: = strconv.ParseInt (params [1], 10 64) if err! = nil {return err} node: & WeightNode {weight: int (parInt), effectiveWeight: int (parInt), / / effective weight on initialization = configuration weight value currentWeight: int (parInt), / current weight = configuration weight value addr: addr,} r.rss = append (r.rss) Node) return nil} / * * @ Author: yang * @ Description: polling for obtaining service * @ Date: 15:36 on 2021-4-7 * / func (r * WeightRoundRobinBalance) Next () string {/ / @ Todo has no service if len (r.rss) = 0 {return ""} totalWeight: = 0 var maxWeightNode * WeightNode for key Node: = range r.rss {/ / @ Todo calculates the sum of effectiveWeight of all nodes in the current state totalWeight totalWeight + = node.effectiveWeight / / @ Todo calculates currentWeight node.currentWeight + = node.effectiveWeight / / @ Todo to find the most weighted if maxWeightNode = = nil | | maxWeightNode.currentWeight < node.currentWeight {maxWeightNode = node r.curIndex = key }} / / @ Todo updates the currentWeight maxWeightNode.currentWeight of the selected node-= totalWeight / / @ Todo returns addr return maxWeightNode.addr} 6. Test Verification / * * @ Author: yang * @ Description: test * @ Date: 2021-4-7 15:36 * / func main () {rb: = new (WeightRoundRobinBalance) rb.Add ("127.0.0.1 rb.Add 80", "4") rb.Add ("127.0.0.1 Description 81", "2") rb.Add ("127.0.0.1 rb.Add 82" "1") fmt.Println (rb.Next ()) fmt.Println (rb.Next ())

Take a look at the results under execution:

Run main.go

127.0.0.1:80

127.0.0.1:81

127.0.0.1:80

127.0.0.1:80

127.0.0.1:82

127.0.0.1:80

127.0.0.1:81

This is how Go implements the Nginx weighted polling algorithm. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report