三分钟深入TT猫之故障转移 - 小柒2012

      2020-08-02 06:47      HTML5

结束了一周繁忙的工作,趁着周末,小编手中的键盘早已饥渴难耐了,想知道上期省略号中发生了什么有趣的故事么?且听小编娓娓道来,结尾有彩蛋。

目录

风月前场

春风再续,书接上回,春香园的老鸨妈妈,给这位血气方刚的骚年挑选了一位佳人A,于是乎骚年兴致勃勃的进入了闺房,宜言饮酒,与子同欢,琴瑟在御,莫不静好,谁知佳人A突然来月事了(这个事先老鸨是不知道的)

我了个擦,春宵一刻值千金啊,赶召唤系老鸨儿,老鸨先是把A从侍客名单中剔除,随后赶紧给这位骚年换了一位佳人B,歌管楼台声细细,秋千院落夜沉沉,哈哈哈,又是一个难忘的夜晚......

梦回现实

哎,少年,醒醒,别做梦了,快起来搬砖了

其实在实际生产中,我们的负载均衡器可能要更加温柔体贴智能,不能让用户有一丝感觉到服务器也来大姨妈。

模拟老鸨

在讲如何体贴之前,先给大家传授几种老鸨经常使用的分配手法,为了让大家更加形象直观的了解老鸨的内心,小编决定带大家扒开来看,当然了鸨妈的内心也是一坨代码而已。

首先我们定义一个OldBird,接着安排四个smallBirds值班。

OldBird {Map<String, Integer> smallBirds = new ConcurrentHashMap<String, Integer>();static {smallBirds.put("野鸡", 1);smallBirds.put("幺二", 2);smallBirds.put("长三", 3);smallBirds.put("书寓", 4);}}

开张了,开张了,显然第一位客人并没有入的了鸨儿的法眼,随机了一个后继续嗑她的瓜子。

Random {public static String getServer() {// 获取值班名单Set<String> keySet = ServerMap.servers.keySet();ArrayList<String> keyList = new ArrayList<String>();keyList.addAll(keySet);// 老鸨看人办事 精打细算了一下、随即了一个java.util.Random random = new java.util.Random();int randomPos = random.nextInt(keyList.size());// 程序员小明获取了一个smallBirdreturn keyList.get(randomPos);}}

可能是鸨妈的随机有点看心情,导致后院有些人有点不高兴了,于是乎赶紧采取了另一种策略。

RoundRobin {private static Integer pos = 0;public static String getServer() {//获取今日值班名单Set<String> keySet = ServerMap.servers.keySet();ArrayList<String> keyList = new ArrayList<String>();keyList.addAll(keySet);//有些人 活太少 可能会不高兴 还是排号来吧String server = null;synchronized (pos) {if (pos >= keySet.size())pos = 0;server = keyList.get(pos);pos++;}// 程序员小明获取了一个smallBirdreturn server;}}

这时候大茶壶急急忙忙的赶到老鸨身边,哎,别嗑了,韦爷点名要书寓,赶紧给安排安排,老鸨一想常客啊,不行,我得好好编排一下,省的老被打扰。

Hash {public static String getServer(){//获取今日值班名单Set<String> keySet = ServerMap.servers.keySet();ArrayList<String> keyList = new ArrayList<String>();keyList.addAll(keySet);//韦爷 悠哉的进来的 点名要书寓String remoteGuest = "韦爷";//老鸨给韦爷 设置固定编号int hashCode = remoteGuest.hashCode();int serverListSize = keyList.size();int serverPos = hashCode % serverListSize;//韦爷获取到了指定服务return keyList.get(serverPos);}}

读到最后,小伙伴们可能要问了,那个Map中的Value并没有起作用啊,让老鸨吃了么?其实,只是感觉用在这里不妥而已,有些事,你懂我懂大家都懂。

具体到生产架构中,应该是这个样子的

ServerMap {Map<String, Integer> servers = new ConcurrentHashMap<String, Integer>();static {//这里有四个服务 权重分别是1234servers.put("1核1G-服务器", 1);servers.put("2核2G-服务器", 2);servers.put("3核3G-服务器", 3);servers.put("4核4G-服务器", 4);}}

能者多劳,权重视服务器的性能而定,下面的算法,服务器4每次有百分之四十的几率被获取到。

WeightRoundRobin {private static Integer pos = 0;public static String getServer(){//取得服务器List Set<String> keySet = ServerMap.servers.keySet();Iterator<String> iterator = keySet.iterator();//计算权重总数 累加 比如 4核4G-服务器 权重为4 上述10个服务器中存在4个4核4G-服务器服务 增加随机或者轮询几率List<String> serverList = new ArrayList<String>();while (iterator.hasNext()){String server = iterator.next();int weight = ServerMap.servers.get(server);for (int i = 0; i < weight; i++)serverList.add(server);}String server = null;synchronized (pos){if (pos >= keySet.size())pos = 0;server = serverList.get(pos);pos ++;}return server;} }

说了这么多,以上只是几种简单的负载均衡算法,在 记一次JavaWeb网站技术架构总结 中有提到十种负载均衡策略以及其优缺点,有兴趣的同学可以一看。

会话机制

各位看官莫急,要想弄明白故障转移是怎么回事,必须要弄明白客户端-服务端的会话认证机制。

由于HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,那么小马哥是怎么知道那些用户买了那些东西的呢?