負載均衡zookpeer之輪詢演算法
知識
07-08
1 Ngix 和 dubbo的負載均衡的區別?
Ngix負責前端的負載均衡,zookeeper負責後台的dubbo的rpc的集群的負載均衡
2 代碼實現
監聽者
- import java.io.IOException;
- import org.apache.log4j.Logger;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.KeeperException;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.ZooDefs.Ids;
- import org.apache.zookeeper.ZooKeeper;
- import org.apache.zookeeper.data.Stat;
- public class WatchMore
- {
- /**
- * Logger for this class
- */
- private static final Logger logger = Logger.getLogger(WatchMore.class);
- // 定義常量
- private static final String CONNECTSTRING = "192.168.10.167:2181";
- private static final int SESSION_TIMEOUT = 50 * 1000;
- private static final String PATH = "/atguigu";
- // 定義實例變數
- private ZooKeeper zk = null;
- private String oldValue = "";
- public ZooKeeper startZK() throws IOException
- {
- return new ZooKeeper(CONNECTSTRING, SESSION_TIMEOUT, new Watcher() {
- @Override
- public void process(WatchedEvent event)
- {
- }
- });
- }
- public void createZNode(String nodePath, String nodeValue) throws KeeperException, InterruptedException
- {
- zk.create(nodePath, nodeValue.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- }
- public String getZNode(String nodePath) throws KeeperException, InterruptedException
- {
- String result = "";
- byte[] byteArray = zk.getData(nodePath, new Watcher() {
- @Override
- public void process(WatchedEvent event)
- {
- try {
- triggerValue(nodePath);
- }
- catch (KeeperException | InterruptedException e) {
- e.printStackTrace();
- }
- }
- }, new Stat());
- result = new String(byteArray);
- oldValue = result;
- return result;
- }
- public boolean triggerValue(String nodePath) throws KeeperException, InterruptedException
- {
- String result = "";
- byte[] byteArray = zk.getData(nodePath, new Watcher() {
- @Override
- public void process(WatchedEvent event)
- {
- try {
- triggerValue(nodePath);
- }
- catch (KeeperException | InterruptedException e) {
- e.printStackTrace();
- }
- }
- }, new Stat());
- result = new String(byteArray);
- String newValue = result;
- if (oldValue.equals(newValue)) {
- logger.info("**************no change****************");
- return false;
- }
- else {
- logger.info("**************oldValue:" + oldValue + " newValue: " + newValue);
- oldValue = newValue;
- return true;
- }
- }
- public static void main(String[] args) throws IOException, KeeperException, InterruptedException
- {
- WatchMore myWatch = new WatchMore();
- // 1 獲得zk實例
- myWatch.setZk(myWatch.startZK());
- if (myWatch.getZk().exists(PATH, false) == null)
- {
- String initValue = "AAA";
- myWatch.createZNode(PATH, initValue);
- logger.info("***************main: " + myWatch.getZNode(PATH));
- Thread.sleep(Long.MAX_VALUE);
- }else {
- logger.info("***************have node*******");
- }
- }
- // setter------getter
- public ZooKeeper getZk()
- {
- return zk;
- }
- public void setZk(ZooKeeper zk)
- {
- this.zk = zk;
- }
- public String getOldValue()
- {
- return oldValue;
- }
- public void setOldValue(String oldValue)
- {
- this.oldValue = oldValue;
- }
- }
3 實現負載均衡的服務
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.log4j.Logger;
- import org.apache.zookeeper.KeeperException;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.ZooKeeper;
- import org.apache.zookeeper.data.Stat;
- import com.atguigu.zk.watch.WatchMore;
- public class BalanceTest
- {
- /**
- * Logger for this class
- */
- private static final Logger logger = Logger.getLogger(WatchMore.class);
- // 定義常量
- private static final String CONNECTSTRING = "192.168.31.167:2181";
- private static final int SESSION_TIMEOUT = 50 * 1000;
- private static final String PATH = "/atcunzi";
- private static final String SUB_PREFIX = "sub";
- // 定義實例變數
- private ZooKeeper zk = null;
- private List<String> serviceLists = new ArrayList<String>(); // sub1,.....sub5 // 用來收集可用服務的
- private int subCount = 5; // 可用服務個數
- private int currentServiceNum = 0; // 當前請求序號
// 初始化zookeepr,並獲取服務的集合
- public ZooKeeper startZK() throws IOException
- {
- return new ZooKeeper(CONNECTSTRING, SESSION_TIMEOUT,new Watcher() {
- @Override
- public void process(WatchedEvent event)
- {
- try
- {
- serviceLists = zk.getChildren(PATH,true);
- }catch (KeeperException | InterruptedException e) {
- e.printStackTrace();
- }
- }
- });
- }
- // 處理輪詢演算法邏輯 重要的是怎麼能讓服務 輪詢
- public String dealRquest() throws KeeperException, InterruptedException
- {
- currentServiceNum = currentServiceNum + 1;
- for (int i = currentServiceNum; i <=subCount; i++)
- {
- if(serviceLists.contains(SUB_PREFIX+currentServiceNum))
- {
- return new String(zk.getData(PATH+"/"+SUB_PREFIX+currentServiceNum,false,new Stat()));
- }else{
- currentServiceNum = currentServiceNum + 1;
- }
- }
- //重要的是怎麼能讓服務 輪詢 1 3 5 currentServiceNum = 6
- for (int i = 1; i <=subCount; i++)
- {
- if(serviceLists.contains(SUB_PREFIX+i))
- {
- currentServiceNum = i;
- return new String(zk.getData(PATH+"/"+SUB_PREFIX+currentServiceNum,false,new Stat()));
- }
- }
- return "no subNode~~~~~";
- }
- public static void main(String[] args) throws IOException, InterruptedException
- {
- BalanceTest test = new BalanceTest();
- test.setZk(test.startZK());
- Thread.sleep(3000);
- String result = null;
- for (int i = 1; i <=15; i++)
- {
- try
- {
- result = test.dealRquest();
- logger.info("*********customerID: "+i+" currentWindows:"+test.currentServiceNum+" "+result);
- Thread.sleep(2000);
- }
- catch (KeeperException | InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- ///----setter=-=getter
- public ZooKeeper getZk()
- {
- return zk;
- }
- public void setZk(ZooKeeper zk)
- {
- this.zk = zk;
- }
- }
4 總結
負載均衡可以看成一個銀行,請求看成是顧客,後台服務看成是銀行櫃檯,大堂經理可以看成zookeeper
服務啟動的時候,需要先準備各個銀行櫃檯都準備好,當顧客來到時候,可以 通過大堂經理的指引,去到相應的櫃檯進行櫃檯處理。
難點:當一個櫃檯暫停服務時候,大唐經理怎麼知道的,並且怎麼分發處理,並且服務怎麼輪詢的?
5 maven配置
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.atguigu.zk1014</groupId>
- <artifactId>zk1014</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>zk1014</name>
- <url>http://maven.apache.org</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
- <dependencies>
- <!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
- <dependency>
- <groupId>com.101tec</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.10</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
- <dependency>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- <version>3.4.9</version>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.9</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- </project>


※SQL Server服務遠程過程調用失敗解決
※HTTP協議又冷又實用的技能大全
TAG:程序員小新人學習 |