- 浏览: 111938 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
ron.luo:
干货,必须得顶。
JAXB使用经验总结 -
csdn_zuoqiang:
能否看下DWR的配置情况?谢谢
结合webservice实现dwr推送 -
友友水:
。。。。不好意思,无心之失,删不掉前一条评论
JAXB使用经验总结 -
友友水:
[/flash][/flash][/flash][/flash ...
JAXB使用经验总结 -
lihong11:
大哥,加加注释好不?看不懂唉
小玩dwr实现服务器推送
因为用memcached集群缓存数据,所以增删服务器节点 对缓存key的影响需要考虑一种策略来实现 数据缓存key所映射的节点变动至最小值(这句话好长啊,就是缓存服务器的增减,对在已经缓存了的数据影响降到最小,比如“test”这个数据之前存在a1节点服务器上,那么增加删除了服务器节点,‘test’依然在 a1上(有可能不在,这个原因可以看以下代码),用10个数据来说明吧,感觉有点只可意会不可言传,10个数据,在节点变化时,尽量只有2个数据发生变动,ok)
下面代码示例:
在测试类中,有几组数据对一致性的测试,当每个真实的服务器节点只有一个虚拟节点时,去掉一台机器,那么这台机器的负荷只会倾倒性的转移到一台服务器上,其他节点数据和负荷不发生变化, 这个验证了: 一致性hash在某个节点变化时,其他节点上的原来的数据依然保持
当每个节点的虚拟节点数增加至200个时, 这时去掉一台服务器节点,这个节点的访问量变为0, 其负载均衡的分摊至每个还存在的服务器节点上,这个验证了:一致性hash还能达到负载均衡,而不会导致某台负荷过重而导致 多米诺(相继挂掉)的效应
下面代码示例:
package com.xll; //服务器对象 public class Server { private String name; private String password; private String ip; private String port; public Server() { } public Server(String name, String password, String ip, String port) { super(); this.name = name; this.password = password; this.ip = ip; this.port = port; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getPort() { return port; } public void setPort(String port) { this.port = port; } @Override public String toString() { return "name:" + name + "ip:" + ip + "port:" + port; } }
package com.xll; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; //server注册,算法生成 public class ServerLoadBalance { private TreeMap<Long, Server> nodes; private List<Server> servers; private final int NODE_NUM = 200; public ServerLoadBalance(List<Server> servers) { super(); this.servers = servers; init(); } private void init() { // 初始化一致性hash环 nodes = new TreeMap<Long, Server>(); for (int i = 0; i != servers.size(); ++i) { // 每个真实机器节点都需要关联虚拟节点 final Server shardInfo = servers.get(i); for (int n = 0; n < NODE_NUM; n++){ // 一个真实机器节点关联NODE_NUM个虚拟节点 Long hash_value = hash("SHARD-" + shardInfo.getIp() + "-NODE-" + n); //System.out.println("第"+i+"个server的hash 散列值="+hash_value); nodes.put(hash_value, shardInfo); } } System.out.println("Finish inited virtual node...."); } /** * 通过key的一致性hash值 得到 相应的 Server对象 * @param key * @return */ public Server getShardInfo(String key) { Long hash_value = hash(key); //System.out.println("key="+key+"的hash值="+hash_value); SortedMap<Long, Server> tail = nodes.tailMap(hash_value); // 沿环的顺时针找到一个虚拟节点 if (tail.size() == 0) { return nodes.get(nodes.firstKey()); } return tail.get(tail.firstKey()); // 返回该虚拟节点对应的真实机器节点的信息 } /** * 一致性hash算法 * @param key * @return */ private Long hash(String key) { ByteBuffer buf = ByteBuffer.wrap(key.getBytes()); int seed = 0x1234ABCD; ByteOrder byteOrder = buf.order(); buf.order(ByteOrder.LITTLE_ENDIAN); long m = 0xc6a4a7935bd1e995L; int r = 47; long h = seed ^ (buf.remaining() * m); long k; while (buf.remaining() >= 8) { k = buf.getLong(); k *= m; k ^= k >>> r; k *= m; h ^= k; h *= m; } if (buf.remaining() > 0) { ByteBuffer finish = ByteBuffer.allocate(8).order( ByteOrder.LITTLE_ENDIAN); // for big-endian version, do this first: // finish.position(8-buf.remaining()); finish.put(buf).rewind(); h ^= finish.getLong(); h *= m; } h ^= h >>> r; h *= m; h ^= h >>> r; buf.order(byteOrder); return h; } }
package com.xll; import java.util.ArrayList; import java.util.List; //主要的测试类 public class TestConsistenHash { public static Server s1 = new Server("ser1", "123", "192.168.216.1", "1"); public static Server s2 = new Server("ser2", "123", "192.168.216.2", "2"); public static Server s3 = new Server("ser3", "123", "192.168.216.3", "3"); public static Server s4 = new Server("ser4", "123", "192.168.216.4", "4"); public static Server s5 = new Server("ser5", "123", "192.168.216.5", "5"); public static List<Server> list = new ArrayList<Server>(); public static int count1 = 0; public static int count2 = 0; public static int count3 = 0; public static int count4 = 0; public static int count5 = 0; public static void main(String[] args) { /** * 可以通过 增加 / 剔除 server来测试 被点击量 的变化 */ list.add(s1); list.add(s2); list.add(s3); list.add(s4); list.add(s5); /** * key的数量为1000个 * * * * 在ServerLoadBalance 的 virtual node 数量NODE_NUM 为200时(这个值能达到负载均衡了,100或更小时还没达到) * 测试的两组数据(5台server和剔除server3时的4台server) * * * server1 hit count = 197 * server2 hit count = 193 * server3 hit count = 210 * server4 hit count = 170 * server5 hit count = 230 * * * server1 hit count = 265 * server2 hit count = 248 * server3 hit count = 0 * server4 hit count = 214 * server5 hit count = 273 * * * * * 在ServerLoadBalance 的 virtual node 数量NODE_NUM 为1时(负载均衡在100或更小时还没达到) * 测试的两组数据(5台server和剔除server3时的4台server) * server1 hit count = 359 * server2 hit count = 94 * server3 hit count = 387 * server4 hit count = 67 * server5 hit count = 93 * * * server1 hit count = 359 * server2 hit count = 481 * server3 hit count = 0 * server4 hit count = 67 * server5 hit count = 93 * * * * */ ServerLoadBalance server = new ServerLoadBalance(list); for (int i = 0; i < 1000; i++) { String key = ""+(i+20); Server s = (Server)server.getShardInfo(key); if(s.toString().equals(s1.toString())) count1 ++; else if(s.toString().equals(s2.toString())) count2 ++; else if(s.toString().equals(s3.toString())) count3 ++; else if(s.toString().equals(s4.toString())) count4 ++; else count5 ++; //System.out.println("key" + i + ", server=" + s); } //得到各server的命中 情况 System.out.println("#############"); System.out.println("server1 hit count = "+TestConsistenHash.count1); System.out.println("server2 hit count = "+TestConsistenHash.count2); System.out.println("server3 hit count = "+TestConsistenHash.count3); System.out.println("server4 hit count = "+TestConsistenHash.count4); System.out.println("server5 hit count = "+TestConsistenHash.count5); System.out.println("#############"); // String key = "test"; // TestThread tt = new TestThread(shard, key); // // new Thread(tt, "0").start(); // new Thread(tt, "10001").start(); // new Thread(tt, "20001").start(); // new Thread(tt, "30001").start(); // new Thread(tt, "40001").start(); // new Thread(tt, "50001").start(); } }
package com.xll; //用于跑大量数据 public class TestThread extends Thread{ ServerLoadBalance shard; String key; public TestThread(ServerLoadBalance shard,String key){ this.shard = shard; this.key = key; } @Override public void run() { runHash(); printCountValue(); } public void runHash(){ String name = currentThread().getName(); int start = Integer.parseInt(name); for (int i = start; i < start+10000; i++) { Server s = (Server)shard.getShardInfo(key+i); increaseCount(s); } } public void increaseCount(Server s){ if(s.toString().equals(TestConsistenHash.s1.toString())) increase(1); else if(s.toString().equals(TestConsistenHash.s2.toString())) increase(2); else if(s.toString().equals(TestConsistenHash.s3.toString())) increase(3); else if(s.toString().equals(TestConsistenHash.s4.toString())) increase(4); else increase(5); } static synchronized void increase(int i){ switch (i) { case 1: TestConsistenHash.count1 ++; break; case 2: TestConsistenHash.count2 ++; break; case 3: TestConsistenHash.count3 ++; break; case 4: TestConsistenHash.count4 ++; break; default: TestConsistenHash.count5 ++; break; } } void printCountValue(){ System.out.println("#############"); System.out.println("server1 hit count = "+TestConsistenHash.count1); System.out.println("server2 hit count = "+TestConsistenHash.count2); System.out.println("server3 hit count = "+TestConsistenHash.count3); System.out.println("server4 hit count = "+TestConsistenHash.count4); System.out.println("server5 hit count = "+TestConsistenHash.count5); System.out.println("#############"); } }
在测试类中,有几组数据对一致性的测试,当每个真实的服务器节点只有一个虚拟节点时,去掉一台机器,那么这台机器的负荷只会倾倒性的转移到一台服务器上,其他节点数据和负荷不发生变化, 这个验证了: 一致性hash在某个节点变化时,其他节点上的原来的数据依然保持
当每个节点的虚拟节点数增加至200个时, 这时去掉一台服务器节点,这个节点的访问量变为0, 其负载均衡的分摊至每个还存在的服务器节点上,这个验证了:一致性hash还能达到负载均衡,而不会导致某台负荷过重而导致 多米诺(相继挂掉)的效应
发表评论
-
动态多数据源实现
2019-12-18 12:58 391背景: 目前基于连接了mobile库 从库的 项目(sprin ... -
RPC调用之微博 motan
2018-02-23 16:42 1439这边文章将偏实战, 至于motan,可以去了解如何实现、比普通 ... -
java快速读取大文件
2018-02-08 11:19 318public static String readCon ... -
微信JSSDK 使用
2016-05-26 11:49 1906获取微信JSAPI_TICKET package com ... -
Netty服务构建实践
2016-05-26 11:40 684用main的形式在服务器上启动了一个netty服务,有端口有地 ... -
安全性,加密
2016-03-07 15:55 611/** * 随机字符串集 */ pri ... -
redis实现并发资源控制--如抢红包、抢优惠券机制
2016-02-20 17:41 8795场景: 如 抢红包、 抢优惠券,都是先到先得 抢红包是把发 ... -
并发队列
2015-12-03 15:26 598import java.util.concurrent ... -
ant脚本编译部署java工程到tomcat服务器
2013-06-28 15:35 1060<?xml version="1.0& ... -
hibernate延迟加载 与 web应用 独立缓存架构的冲突
2013-04-26 11:03 1087延迟加载(Lazy Loading)是 ... -
Myeclipse反向生成pojo及hibernate映射文件(由数据库表)
2013-03-18 14:38 1052在这之前请创建一个web工程,然后右键选择myeclipse- ... -
结合webservice实现dwr推送
2012-08-22 13:26 5270情景: 客户端需要实时提醒服务,比如某个日程已过期的提醒, ... -
手写比较器comparator
2012-07-12 15:47 1255项目中需要对一些数据进行排序,应用到了个比较强大的比较器,感觉 ... -
copy到粘贴板
2012-05-22 11:39 1141直接上代码,实现了IE和火狐下的copy content ... -
取两个集合的交集数据
2011-08-30 11:13 1234List<String> a = new A ... -
常用正则表达式收藏
2011-04-26 12:26 6911。^\d+$ //匹配非负整数(正整数 + 0) 2。 ... -
对日期类型与String类型之间转换方法的小结
2011-03-07 19:25 1220关于日期的方法举例程序如下: package c ... -
线程同步
2011-02-26 10:47 798转自http://www.iteye.com/topic/16 ... -
java多线程
2011-02-26 08:15 879本文转载自 http://www.iteye.com/topi ... -
对java中反射的整理
2011-02-24 20:04 857什么是Java中的类反射: ...
相关推荐
如果没有找到,则取整个环的第个节点。测试结果测试代码是整理的,主体法没有变分布平均性测试:测试随机成的众多key是否会平均分布到各个结点上测试结果如下:最上是参
一致性Hash算法,易于扩容;添加了 单元测试,使用Spring提供的RestTemplate调用RestFul风格的API接口;整合了 quartz 定时任务框架 ,并进行了封装,只需在构建完定时任务Job类后,在 application-quartz....
此提交使用一致性敏感散列 (CSH) 提供图像修复。 为了使用它,您需要来自http://www.eng.tau.ac.il/~simonk/CSH/index.html的 CSH 工具箱 包括一个测试脚本和几个测试图像。
MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特...
基于go语言实现的分布式缓存系统源码+项目说明(以键值对的形式存储数据,一致性hash算法选择存储节点,Protobuf通信协议编解码。用户输入查询请求后,会优先在缓存系统查询,查不到则使用回调函数去源数据库查询,...
本文实例讲述了Python基于hashlib模块的文件MD5一致性加密验证。分享给大家供大家参考,具体如下: 使用hashlib模块,可对文件MD5一致性加密验证: #python 检测文件MD5值 #python version 2.6 import hashlib import...
ConsistentHash 一致性Hash WordCount Map-Reduce算法例子 Retrive 文件下载 IP 获得IP地址示例 ip QQ纯真数据库示例 HtmlParser 网页内容提取库HtmlParser的源码项目 nekohtml-1.9.7 nekohtml的源码项目 RhinoTest ...
一致性hash 消峰 分库分表 锁 悲观锁 乐观锁 行级锁 分布式锁 分区排队 一致性 一致性算法 paxos zab nwr raft gossip 柔性事务(TCC) 一致性原理 CAP BASE 中间件 数据库 mysql 存储引擎 ...
一致性hash算法,支持可配置虚拟节点数 #### 支持可插拔的注册中心 orion-register-zk-starter cp orion-register-etcd-starter cp orion-register-nacos-starter ap ...
分布式缓存的一致性hash算法 数据存储服务器集群的伸缩性设计 关系数据库集群的伸缩性设计 nosql数据库的伸缩性设计 随需应变:网站的可扩展性 构建可扩展的网站架构 利用分布式消息队列降低系统耦合性 ...
跳跃一致哈希计算 甚至服务器之间的数据分布也非常重要:另一个重要方面是能够... 关于一致性哈希,使用的算法是谷歌的论文“A Fast, Minimal Memory, Consistent Hash Algorithm”中提出的Jump Consistent Hashing。
MD5碰撞测试程序并提供源代码. 利用该程序可伪造出有相同MD5的不同程序. MD5是目前最热门的加密算法,我们通常用MD5值来验证文件的完整性。例如在一些比较正规的下载网站,通常会提供软件的MD5值,这样我们就可以对...
之所以称为“会话”,是因为它封装了您在创建和使用Hash-Tree时希望具有一致性的内容,例如使用的哈希算法,TreeBuilder的种类(目前仅在内存中)以及可能共享的实例(例如MessageDigest)。 可以将一个实例(使用...
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。 12、final, finally, finalize的区别。 final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 ...
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。 15、final, finally, finalize的区别。 final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 ...
Oracle9i初始化参数中文说明 Blank_trimming: 说明: 如果值为TRUE, 即使源长度比目标长度 (SQL92 兼容) 更长, 也允许分配数据。 值范围: TRUE | FALSE 默认值: FALSE serializable: 说明: 确定查询是否获取表级...