Balancing algorithm of Dubbo weighted round robin load recommended products

  Dubbo weighted round robin load balancing algorithm core point: weight (constant weight), currentWeight (current weight, dynamic), arithmetic logic: Polling Service Provider (each service provider has a weight and currentWeight), currentWeight increased weight, taking the biggest currentWeight, then take the corresponding service provider, currentWeight service provider will take the final total to minus weight (weight of all the service providers sum). Examples are as follows:

  Server [A, B, C] corresponding weight [5, 1, 1], there are now seven requests sequentially into the load balancing logic selection process is as follows:

Request Number currentWeight array Select result currentWeight array after subtracting the sum of the weights
1 [5, 1, 1] A [-2, 1, 1]
2 [3, 2, 2] A [-4, 2, 2]
3 [1, 3, 3] B [1, -4, 3]
4 [6, -3, 4] A [-1, -3, 4]
5 [4, -2, 5] C [4, -2, -2]
6 [9, -1, -1] A [2, -1, -1]
7 [7, 0, 0] A [0, 0, 0]

  As above, after the smoothing treatment, as a server sequence obtained [A, A, B, A, C, A, A]. Initially currentWeight = [0, 0, 0], 7th After the request, currentWeight again becomes [0, 0, 0].

  Practices Application: Recommended product (the company has developed a variety of products of the same type, the docking of different partners, are now required by a certain percentage, partners recommend different products to different customers, to ensure the flow of each partner. For example, Partner a product a: Partner B product B: Partner C product C = 5: 1: 1, so if there are 7 customers want to know the type of product, recommend a to five of them, to one of them recommended B, including one to recommend C).

  WRR modeled Dubbo load balancing algorithm, the algorithm recommended products, as follows:

 1 public class ProductMessage {
 2     private String productName;
 3     private int weight;
 4 
 5     public ProductMessage(String productName, int weight) {
 6         this.productName = productName;
 7         this.weight = weight;
 8     }
 9 
10     public String getProductName() {
11         return productName;
12     }
13 
14     public void setProductName(String productName) {
15         this.productName = productName;
16     }
17 
18     public int getWeight() {
19         return weight;
20     }
21 
22     public void setWeight(int weight) {
23         this.weight = weight;
24     }
25 }
 1 import java.util.concurrent.atomic.AtomicLong;
 2 
 3 public class WeightedRoundRobin {
 4     private int weight;
 5     private AtomicLong current = new AtomicLong(0);
 6     private long lastUpdate;
 7     public int getWeight() {
 8         return weight;
 9     }
10     public void setWeight(int weight) {
11         this.weight = weight;
12         current.set(0);
13     }
14     public long increaseCurrent() {
15         return current.addAndGet(weight);
16     }
17     public void sel(int total) {
18         current.addAndGet(-1 * total);
19     }
20     public long getLastUpdate() {
21         return lastUpdate;
22     }
23     public void setLastUpdate(long lastUpdate) {
24         this.lastUpdate = lastUpdate;
25     }
26 }
. 1  Import a java.util.Map;
 2  Import java.util.List;
 . 3  Import the java.util.Iterator;
 . 4  Import java.util.concurrent.ConcurrentMap;
 . 5  Import a java.util.concurrent.ConcurrentHashMap;
 . 6  Import Classes in java.util. concurrent.atomic.AtomicBoolean;
 . 7  
. 8  / ** 
. 9  * business scenario
 10  * Recommendations polling, is recommended to ensure that each product specified weights
 . 11  *
 12 is   * / 
13 is  public  class ProductRoundRobin {
 14      Private  static  int RECYCLE_PERIOD = 300000;
15     private AtomicBoolean updateLock = new AtomicBoolean();
16 
17     private ConcurrentMap<String, WeightedRoundRobin> productMap = new ConcurrentHashMap<String, WeightedRoundRobin>();
18 
19     public ProductMessage selectProduct(List<ProductMessage> productMessageList) {
20         int totalWeight = 0;
21         long maxCurrent = Long.MIN_VALUE;
22         long now = System.currentTimeMillis();
23         ProductMessage selectedProduct = null;
24         WeightedRoundRobin selectedWRR = null;
25         for (ProductMessage productMessage : productMessageList) {
26             String identifyString = productMessage.toString();
27             WeightedRoundRobin weightedRoundRobin = productMap.get(identifyString);
28             int weight = productMessage.getWeight();
29             if (weight < 0) {
30                 weight = 0;
31             }
32             if (weightedRoundRobin == null) {
33                 weightedRoundRobin = new WeightedRoundRobin();
34                 weightedRoundRobin.setWeight(weight);
35                 productMap.putIfAbsent(identifyString, weightedRoundRobin);
36                 weightedRoundRobin = productMap.get(identifyString);
37             }
38             if (weight != weightedRoundRobin.getWeight()) {
39                 weightedRoundRobin.setWeight(weight);
40             }
41             long cur = weightedRoundRobin.increaseCurrent();
42             weightedRoundRobin.setLastUpdate(now);
43             if (cur > maxCurrent) {
44                 maxCurrent = cur;
45                 selectedProduct = productMessage;
46                 selectedWRR = weightedRoundRobin;
47             }
48             totalWeight += weight;
49         }
50 
51         if (!updateLock.get() && productMessageList.size() != productMap.size()) {
52             if (updateLock.compareAndSet(false, true)) {
53                 try {
54                     // copy -> modify -> update reference
55                     ConcurrentMap<String, WeightedRoundRobin> newMap = new ConcurrentHashMap<String, WeightedRoundRobin>();
56                     newMap.putAll(productMap);
57                     Iterator<Map.Entry<String, WeightedRoundRobin>> it = newMap.entrySet().iterator();
58                     while (it.hasNext()) {
59                         Map.Entry<String, WeightedRoundRobin> item = it.next();
60                         if (now - item.getValue().getLastUpdate() > RECYCLE_PERIOD) {
61                             it.remove();
62                         }
63                     }
64                 } finally {
65                     updateLock.set(false);
66                 }
67             }
68         }
69 
70         if (selectedProduct != null) {
71             selectedWRR.sel(totalWeight);
72             return selectedProduct;
73         }
74         return productMessageList.get(0);
75     }
76 }
. 1  Import a java.util.Map;
 2  Import java.util.List;
 . 3  Import the java.util.HashMap;
 . 4  Import of java.util.ArrayList;
 . 5  
. 6  public  class ProductRoundRobinTest {
 . 7      public  static  void main (String [] args) {
 8          / ** 
9           * setting:
 10           * product A, weight counterweight 5
 . 11           * product B, a weight of 1
 12 is           * product C, weight 1
 13 is           * / 
14          ProductMessage Product1 = new new ProductMessage ( "product A",. 5 );
15         ProductMessage product2 = new ProductMessage("产品B", 1);
16         ProductMessage product3 = new ProductMessage("产品C", 1);
17         List<ProductMessage> productMessageList = new ArrayList<ProductMessage>() {{
18             add(product1);
19             add(product2);
20             add(product3);
21         }};
22 
23         ProductRoundRobin productRoundRobin = new ProductRoundRobin();
24 
25         // 进行7次推荐
26         for (int i = 0; i < 7; i++) {
27             ProductMessage selectedProduct = productRoundRobin.selectProduct(productMessageList);
28             System.out.println("productName:" + selectedProduct.getProductName());
29         }
30 
31         Map<String, Long> countMap = new HashMap<>();
32         for (int i = 0; i < 1000000; i++) {
33             ProductMessage selectedProduct = productRoundRobin.selectProduct(productMessageList);
34             Long count = countMap.get(selectedProduct.getProductName());
35             countMap.put(selectedProduct.getProductName(), count == null ? 1 : ++count);
36         }
37 
38         for (Map.Entry<String, Long> entry : countMap.entrySet()) {
39             System.out.println("introduce productName:" + entry.getKey() + "; introduce count:" + entry.getValue());
40         }
41     }
42 }

  Results are as follows:

productName: Product A 
productName: Product A 
productName: Product B 
productName: Product A 
productName: Product C 
productName: Product A 
productName: Product A 
introduce productName: product A; introduce COUNT: 714 286 
introduce productName: Product C; introduce COUNT: 142857 
introduce productName : product B; introduce COUNT: 142857

 

  Summary: technical services in business, the arithmetic logic applied to the actual business, make business more intelligent. The so-called enabling technology.

Guess you like

Origin www.cnblogs.com/dushenzi/p/12289814.html