随笔-23  评论-58  文章-0  trackbacks-0
  2012年9月29日
     摘要: Reactor 模式的 JAVA NIO 多线程服务器,这是比较完善的一版了。Java 的 NIO 网络模型实在是不好用,还是使用现成的好。Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public class NIOServer...  阅读全文
posted @ 2013-05-14 16:31 nianzai 阅读(2710) | 评论 (1)编辑 收藏

    我学东西通常是通过动手的方式来学习,比如最近学习分布式服务协议paxos,自己就动手开发了一个该协议的实现版本。如果不动手实现只是靠学习理论是很难理解这个理论的本身。理解它最好的方式就是实践它。


    根据理论或者原理就来做实现确实很难,这需要很强的代码功底、极高的理解能力以及持久的耐心。


    扎实的功底是一切的开始,没有扎实的功底就无法下手。没有很好的悟性就很难保证事情的正确性。没有良好的耐心就很难保证事情的结果。一次性就能将事情做成做好的,这种人实在太少了。做成一件事情就是在无数的失败、错误中来接近成功,通过失败来纠正、从而一步一步的接近成功。这就注定了需要持久的耐心才能保证成功。

posted @ 2013-04-27 10:13 nianzai 阅读(1954) | 评论 (0)编辑 收藏
1、提出者向leader发出询问消息
2、leader向所有的QuorumPeer发出投票请求
3、QuorumPeer对该请求进行投票,如果消息的txid大于QuorumPeer的txid则通过该投票,否则反对该投票
4、leader根据所有的QuorumPeer投票结果进行计算,如果有一半以上的QuorumPeer通过则接受提出者的请求,否则拒绝提出者的请求
        switch (message.getType())
        
{
            
case QuorumCode.ask://询问类型
                
//询问该事务是否可操作
                Ask task=new Ask(message,sc);
                My.executor.execute(task);
                m.setCode(JuiceCode.OK);
                
break;
            
case QuorumCode.vote://投票类型
                if(My.txid>=message.getTxid())
                    
//拒绝
                    m.setCode(JuiceCode.ERROR);
                
else
                
{
                    
//通过
                    m.setCode(JuiceCode.OK);
                    My.updateMyTxid(message.getTxid());
                }

                
break;
            
case QuorumCode.ping://ping
                m.setCode(JuiceCode.OK);
                m.setMyid(message.getMyid());
                
break;
        }



    
public static boolean sendAndVote(Message m) throws IOException
    
{
        m.setType(QuorumCode.vote);
        Map
<Integer,Response> mp=new TreeMap<Integer,Response>();
        
for(Map.Entry<Integer,NIOClient> entry:voteClientMap.entrySet())
        
{
            NIOClient client
=entry.getValue();
            Response response
=client.send(ByteUtil.getBytes(m));
            mp.put(entry.getKey(), response);
        }


        Map
<Integer,Message> vote=new TreeMap<Integer,Message>();
        
for(Map.Entry<Integer,Response> entry:mp.entrySet())
            vote.put(entry.getKey(), (Message)ByteUtil.getObject(entry.getValue().getData()));

        
int ok=0;
        
for(Map.Entry<Integer,Message> entry:vote.entrySet())
        
{
            Message f
=entry.getValue();
            
if(f.getCode()==JuiceCode.OK)
                ok
++;
        }

        
if(ok/(vote.size()*1.0)>1/2.0)
            
return true;
        
return false;
    }


posted @ 2013-04-23 13:19 nianzai 阅读(1739) | 评论 (0)编辑 收藏

1、收集第一轮投票结果
2、统计投票数,计算出投票数最大的id
3、如果投票数超过1/2则选该id为leader
4、如果最大投票数id没有超过1/2,则推荐txid最大的id为leader
5、计算出最大的txid及其服务器id
6、计算出最大的txid有几个
7、如果最大txid超过一个,则比较服务器id,推荐服务id最大的为leader
8、发起第二轮投票

Java实现代码如下:
        /**
         * 选举leader
         * 
@param vote 投票信息
         * 
@return
         
*/

        
public int forLeader(Map<Integer,Notification> vote)
        
{
            
//统计leader投票数
            TreeMap<Integer,Integer> tmap=new TreeMap<Integer,Integer>();
            
for(Map.Entry<Integer,Notification> entry:vote.entrySet())
            
{
                Notification nf
=entry.getValue();
                
if(tmap.containsKey(nf.leader))
                    tmap.put(nf.leader, tmap.get(nf.leader)
+1);
                
else
                    tmap.put(nf.leader, 
1);
            }

            
//计算出投票数最大的id
            int a=0;
            
int l=0;
            
for(Map.Entry<Integer,Integer> entry:tmap.entrySet())
            
{
                
if(entry.getValue()>a)
                
{
                    a
=entry.getValue();
                    l
=entry.getKey();
                }

            }

            
//如果投票数超过1/2则选该id为leader
            if(a/(My.serverList.size()*1.0)>1/2.0)
            
{
                
//选出leader
                if(l==My.myid)
                    My.myServerState
=ServerState.LEADING;
                
else
                    My.myServerState
=ServerState.FLLOWING;
                My.leader
=l;
                
                
return -1;
            }

            
//如果最大投票数leader没有超过1/2,则推荐txid最大的id为leader
            
//计算出最大的txid及其服务器id
            long txid=0;
            
int leader=0;
            
for(Map.Entry<Integer,Notification> entry:vote.entrySet())
            
{
                
if(entry.getValue().txid>txid)
                
{
                    leader
=entry.getKey();
                    txid
=entry.getValue().txid;
                }

            }

            
//计算出最大的txid有几个
            Map<Integer,Notification> vte=new TreeMap<Integer,Notification>();
            
for(Map.Entry<Integer,Notification> entry:vote.entrySet())
            
{
                
if(entry.getValue().txid==txid)
                
{
                    vte.put(entry.getValue().id, entry.getValue());
                }

            }

            
//如果超过一个,则比较服务器id,推荐服务id最大的为leader
            if(vte.size()>1)
            
{
                
for(Map.Entry<Integer,Notification> entry:vte.entrySet())
                
{
                    
if(entry.getValue().id>leader)
                        leader
=entry.getKey();
                }

            }

            
return leader;
        }

    }

posted @ 2013-04-17 11:15 nianzai 阅读(1861) | 评论 (0)编辑 收藏
原理:通过浏览器去访问要抓取的Ajax、脚本网页地址,通过读取浏览器内存document来得到脚本执行以后的网页内容

在原有的基础上增加 自定义命令脚本 抓取功能。该功能能够通过用户自定义的脚本来实现与网页的交互,比如填写内容,点击网页上的提交按钮。
这样便能抓取需要提交的网页内容了,特别是需要提交的ajax网页。



Ajax、脚本网页内容抓取工具(第二版)  点这下载
posted @ 2012-09-29 14:26 nianzai 阅读(1821) | 评论 (1)编辑 收藏