目前项目中在克服JGroups初期使用的困难之后,已经使用比较稳定了。感觉比较烦琐和容易出错的还是JGroups配置。感觉中文的资源较少,现将自己总结的经验总结如下
Tim http://hi.baidu.com/jabber/blog/item/7e879852a23efd0f0cf3e3ea.html
JGroups 适合使用场合
服务器集群cluster、多服务器通讯、服务器replication(复制)等,分布式cache缓存
JGroups 简介
JGroups是一个基于Java语言的提供可靠多播(组播)的开发工具包。在IP Multicast基础上提供可靠服务,也可以构建在TCP或者WAN上。主要是由Bela Ban开发,属于JBoss.org,在JBoss的网站也有一些相关文档。目前在 SourceForge上还是比较活跃,经常保持更新。
JGroups 配置
PING: 发现初始成员
MERGE2: 将网络层切分的包重新合并。
FD_SOCK: Failure Dectection 错误检测,基于TCP
FD:Failure Dectection 错误检测,基于心跳
VERIFY_SUSPECT: 检查貌似失败的节点
pbcast.NAKACK: 应答,提供可靠传输
UNICAST: 可靠的UNICAST
pbcast.STABLE: 计算广播信息是否稳定
VIEW_SYNC: 定期广播view(成员名单)
pbcast.GMS: Group membership, 处理joins/leaves/crashes等
FC: 流量控制
FRAG2:Fragmentation layer,分包,将大的数据包分拆成适合网络层传输
以上一些是比较重要的配置,基本上不能少。如果要深入研究可以在 org.jgroups.protocols 里面查看源代码
JGroups使用例子, JGroups demo, Tim的hello world例子
Timreceiver.java
import org.jgroups.tests.perf.Receiver; import org.jgroups.tests.perf.Transport; import org.jgroups.util.Util; public class TimReceiver implements Receiver { private Transport transport = null; public static void main(String[] args) { TimReceiver t = new TimReceiver(); try { int sendMsgCount = 5000; int msgSize = 1000; t.start(); t.sendMessages(sendMsgCount, msgSize); System.out.println("########## Begin to recv..."); Thread.currentThread().join(); } catch (Exception e) { e.printStackTrace(); } finally { if (t != null) { t.stop(); } } } public void start() throws Exception { transport = (Transport) new TimTransport(); transport.create(null); transport.setReceiver(this); transport.start(); } public void stop() { if (transport != null) { transport.stop(); transport.destroy(); } } private int count = 0; public void receive(Object sender, byte[] data) { System.out.print("."); if (++count == 5000) { System.out.println("\r\nRECV DONE."); System.exit(0); } } private void sendMessages(int count, int msgSize) throws Exception { byte[] buf = new byte[msgSize]; for (int k = 0; k < msgSize; k++) buf[k] = 'T'; System.out.println("-- sending " + count + " " + Util.printBytes(msgSize) + " messages"); for (int i = 0; i < count; i++) { transport.send(null, buf); } System.out.println("######### send complete"); } }
TimTransport.java
import java.util.Map; import java.util.Properties; import org.jgroups.Address; import org.jgroups.JChannel; import org.jgroups.Message; import org.jgroups.ReceiverAdapter; import org.jgroups.tests.perf.Receiver; import org.jgroups.tests.perf.Transport; public class TimTransport extends ReceiverAdapter implements Transport{ private JChannel channel = null; private String groupName = "TimDemo"; private Receiver receiver = null; String PROTOCOL_STACK_UDP1 = "UDP(bind_addr=192.168.100.59"; String PROTOCOL_STACK_UDP2 = ";mcast_port=8888"; String PROTOCOL_STACK_UDP3 = ";mcast_addr=225.1.1.1"; String PROTOCOL_STACK_UDP4 = ";tos=8;loopback=false;max_bundle_size=64000;" + "use_incoming_packet_handler=true;use_outgoing_packet_handler=false;ip_ttl=2;enable_bundling=true):" + "PING:MERGE2:FD_SOCK:FD:VERIFY_SUSPECT:" +"pbcast.NAKACK(gc_lag=50;max_xmit_size=50000;use_mcast_xmit=false;" + "retransmit_timeout=300,600,1200,2400,4800;discard_delivered_msgs=true):" +"UNICAST:pbcast.STABLE:VIEW_SYNC:" +"pbcast.GMS(print_local_addr=false;join_timeout=3000;" + "join_retry_timeout=2000;" + "shun=true;view_bundling=true):" +"FC(max_credits=2000000;min_threshold=0.10):FRAG2(frag_size=50000)"; public Object getLocalAddress() { return channel != null ? channel.getLocalAddress() : null; } public void start() throws Exception { channel.connect(groupName); } public void stop() { if (channel != null) { channel.shutdown(); } } public void destroy() { if (channel != null) { channel.close(); channel = null; } } public void setReceiver(Receiver r) { this.receiver = r; } public Map dumpStats() { return channel != null ? channel.dumpStats() : null; } public void send(Object destination, byte[] payload) throws Exception { byte[] tmp = new byte[payload.length]; System.arraycopy(payload, 0, tmp, 0, payload.length); Message msg = null; msg = new Message((Address) destination, null, tmp); if (channel != null) { channel.send(msg); } } public void receive(Message msg) { Address sender = msg.getSrc(); byte[] payload = msg.getBuffer(); if (receiver != null) { try { receiver.receive(sender, payload); } catch (Throwable tt) { tt.printStackTrace(); } } } public void create(Properties config) throws Exception { String PROTOCOL_STACK = PROTOCOL_STACK_UDP1 + PROTOCOL_STACK_UDP2 + PROTOCOL_STACK_UDP3 + PROTOCOL_STACK_UDP4; channel = new JChannel(PROTOCOL_STACK); channel.setReceiver(this); } public void send(Object destination, byte[] payload, boolean oob) throws Exception { send(destination, payload); } }
JGroups 下载 download
http://www.jgroups.org/