一個新的功能上線都會走灰度的過程,萬一新功能有問題,則會導致線上的大量的報錯,甚至不可用的嚴重情況。比如我們現在本來接入了2個短信渠道去發送短信,現在接入好了第三個渠道,如果我們直接把代碼上了,那麼萬一這個第三個渠道的代碼寫的有問題,那麼意味着我們有三分之一的短信發送不出去,後果非常嚴重。
解決辦法
我們可以爲每個渠道設置一個權重值,短信發送時,按照權重比例隨機選擇短信渠道。初次上線第三個渠道時,可以將這個渠道的權重設置的比較低,比如1%, 這樣即使有問題 ,也就只有1%的受到影響。那如何實現一個帶權重的隨機選擇算法呢?前面都是廢話,直接上code:
import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import com.google.common.collect.Maps; /** * @Author: liuzhijian on 2018/6/11 */ public class WeigherTest { public static void main(String[] args) { Map<User, Integer> result = Maps.newHashMap(); // 初始化權重配置 Map<User, Integer> weigh = Maps.newLinkedHashMap(); weigh.put(new User("1"), 10); weigh.put(new User("2"), 10); weigh.put(new User("3"), 10); for (int i=0;i<100000;i++) { User user = getWeighedInstance(weigh); //記錄隨機選擇的結果 if(result.get(user) == null) { result.put(user, 1); } else { result.put(user, result.get(user)+1); // 這裏不考慮線程安全,因爲只在一個線程裏運行 } } System.out.println(result); //將結果打印出來,看看是不是真的按照權重選擇的 } static final class User { String id; public User(String id) { this.id = id; } public String getId() { return id; } public void setId(String id) { this.id = id; } @Override public String toString() { return "User{" + "id='" + id + '\'' + '}'; } } // 先計算總的權重值,判斷隨機數在哪個對象的範圍內,返回對象 static <T> T getWeighedInstance(Map<T, Integer> weighMap) { int totalWeight = 0; for (Map.Entry<T, Integer> entry : weighMap.entrySet()) { totalWeight += entry.getValue(); } int num = ThreadLocalRandom.current().nextInt(totalWeight); for (Map.Entry<T, Integer> entry : weighMap.entrySet()) { num -= entry.getValue(); if(num<0){ return entry.getKey(); } } return null; } }
我們可以修改3個User對象的權重值,然後運行一下看看結果是否正確。
歡迎關注我的個人的博客www.zhijianliu.cn, 虛心求教,有錯誤還請指正輕拍,謝謝
版權聲明:本文出自志健的原創文章,未經博主允許不得轉載