??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲欧洲日产国产综合网,国产欧美精品一区二区三区 ,999国产精品999久久久久久http://www.aygfsteel.com/mikechen/category/50936.html?sh)子商务技术架?/description>zh-cnFri, 30 Mar 2012 03:32:33 GMTFri, 30 Mar 2012 03:32:33 GMT60Hadoop-详解http://www.aygfsteel.com/mikechen/archive/2012/03/30/373028.html陈睿陈睿Fri, 30 Mar 2012 02:14:00 GMThttp://www.aygfsteel.com/mikechen/archive/2012/03/30/373028.htmlhttp://www.aygfsteel.com/mikechen/comments/373028.htmlhttp://www.aygfsteel.com/mikechen/archive/2012/03/30/373028.html#Feedback0http://www.aygfsteel.com/mikechen/comments/commentRss/373028.htmlhttp://www.aygfsteel.com/mikechen/services/trackbacks/373028.html打算后面在hadoop上花旉把里面的内容Q好好学学,q篇博客在后面陆箋更新hadoop学习(fn)W记?img src ="http://www.aygfsteel.com/mikechen/aggbug/373028.html" width = "1" height = "1" />

陈睿 2012-03-30 10:14 发表评论
]]>
底层架构-q程通讯-Minahttp://www.aygfsteel.com/mikechen/archive/2012/03/15/371938.html陈睿陈睿Thu, 15 Mar 2012 06:49:00 GMThttp://www.aygfsteel.com/mikechen/archive/2012/03/15/371938.htmlhttp://www.aygfsteel.com/mikechen/comments/371938.htmlhttp://www.aygfsteel.com/mikechen/archive/2012/03/15/371938.html#Feedback0http://www.aygfsteel.com/mikechen/comments/commentRss/371938.htmlhttp://www.aygfsteel.com/mikechen/services/trackbacks/371938.html一QMina概要
    Apache Mina是一个能够帮助用户开发高性能和高伸羃性网l应用程序的框架。它通过Java nio技术基于TCP/IP和UDP/IP协议提供了抽象的、事仉动的、异步的API?div>如下的特性:(x)
1? ZJava nio的TCP/IP和UDP/IP实现
ZRXTX的串口通信QRS232Q?/div>
VM 通道通信
2、通过filter接口实现扩展Q类gServlet filters
3、low-levelQ底层)和high-levelQ高U封装)的apiQ?/div>
       low-levelQ用ByteBuffers
       High-levelQ用自定义的消息对象和解码?/div>
4、Highly customizableQ易用的Q线E模式(MINA2.0 已经用U程模型了)Q?/div>
       单线E?/div>
       U程?/div>
       多个U程?/div>
5、基于java5 SSLEngine的SSL、TLS、StartTLS支持
6、负载^?/div>
7、用mockq行单元试
8、jmx整合
9、基于StreamIoHandler的流式I/O支持
10、IOC容器的整合:(x)Spring、PicoContainer
11、^滑迁UdNettyq_

二:(x)实践
    首先讲一下客L(fng)的通信q程Q?br />
1.通过SocketConnector同服务器端徏立连?nbsp;
2.链接建立之后I/O的读写交l了I/O ProcessorU程QI/O Processor是多U程?nbsp;
3.通过I/O Processord的数据经qIoFilterChain里所有配|的IoFilterQIoFilterq行消息的过滤,格式的{换,在这个层面可以制定一些自定义的协?nbsp;
4.最后IoFilter数据交lHandlerq行业务处理Q完成了整个d的过E?nbsp;
5.写入q程也是cMQ只是刚好倒过来,通过IoSession.write写出数据Q然后Handlerq行写入的业务处理,处理完成后交lIoFilterChainQ进行消息过滤和协议的{换,最后通过I/O Processor数据写出到socket通道 
IoFilterChain作ؓ(f)消息qo(h)?nbsp;
1.d的时候是从低U协议到高协议的过E,一般来说从byte字节逐渐转换成业务对象的q程 
2.写入的时候一般是从业务对象到字节byte的过E?nbsp;
IoSession贯穿整个通信q程的始l?nbsp;
    客户端通信q程 

   
1.创徏服务?br />    package com.gewara.web.module.base;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

/**
 * Mina服务?br /> * 
 * 
@author mike
 *
 * 
@since 2012-3-15
 
*/
public class HelloServer {

        private static final int PORT = 8901;// 定义监听端口

        public static void main(String[] args) throws IOException{
            // 创徏服务端监控线E?/span>
            IoAcceptor acceptor = new NioSocketAcceptor();
            
            // 讄日志记录?/span>
            acceptor.getFilterChain().addLast("logger", new LoggingFilter());
            
            // 讄~码qo(h)?/span>
            acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
           
            // 指定业务逻辑处理?/span>
            acceptor.setHandler(new HelloServerHandler());
            
            // 讄端口?/span>
            acceptor.setDefaultLocalAddress(new InetSocketAddress(PORT));
            
            // 启动监听U程
            acceptor.bind();
        }
}
 
2.创徏服务器端业务逻辑
    
package com.gewara.web.module.base;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

/**
 * 服务器端业务逻辑
 * 
 * 
@author mike
 *
 * 
@since 2012-3-15
 
*/
public class HelloServerHandler extends IoHandlerAdapter {
         @Override
        /**
         * q接创徏事g
         
*/
        public void sessionCreated(IoSession session){
            // 昄客户端的ip和端?/span>
            System.out.println(session.getRemoteAddress().toString());
        }

        @Override
        /**
         * 消息接收事g
         
*/
        public void messageReceived(IoSession session, Object message) throws Exception{
            String str = message.toString();
            if (str.trim().equalsIgnoreCase("quit")){
                // l束?x)?/span>
                session.close(true);
                return;
            }
            
            // q回消息字符?/span>
            session.write("Hi Client!");
            // 打印客户端传来的消息内容
            System.out.println("Message written" + str);
        }
}

3.创徏客户?br />     package com.gewara.web.module.base;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

/**
 * Mina客户?br /> * 
 * 
@author mike
 *
 * 
@since 2012-3-15
 
*/
public class HelloClient {
       public static void main(String[] args){
            // 创徏客户端连接器.
            NioSocketConnector connector = new NioSocketConnector();
            
            // 讄日志记录?/span>
            connector.getFilterChain().addLast("logger", new LoggingFilter());
            
            // 讄~码qo(h)?/span>
            connector.getFilterChain().addLast("codec", 
                    new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); 
            
            // 讄q接时(g)查时?/span>
            connector.setConnectTimeoutCheckInterval(30);
            
            // 讄事g处理?/span>
            connector.setHandler(new HelloClientHandler());
            
            // 建立q接
            ConnectFuture cf = connector.connect(new InetSocketAddress("192.168.2.89", 8901));
            
            // {待q接创徏完成
            cf.awaitUninterruptibly();
            
            // 发送消?nbsp; 
            cf.getSession().write("Hi Server!");
           
            // 发送消?/span>
            cf.getSession().write("quit");
            
            // {待q接断开
            cf.getSession().getCloseFuture().awaitUninterruptibly();

            // 释放q接
            connector.dispose();
        }
}

4.客户端业务逻辑
package com.gewara.web.module.base;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

public class HelloClientHandler extends IoHandlerAdapter {
        @Override
        /**
         * 消息接收事g
         
*/
        public void messageReceived(IoSession session, Object message) throws Exception{
            //昄接收到的消息
            System.out.println("server message:"+message.toString());
        }
}

5.先启动服务器端,然后启动客户?br />
2012-03-15 14:45:41,456  INFO  logging.LoggingFilter - CREATED
/192.168.2.89:2691
2012-03-15 14:45:41,456  INFO  logging.LoggingFilter - OPENED
2012-03-15 14:45:41,487  INFO  logging.LoggingFilter - RECEIVED: HeapBuffer[pos=0 lim=11 cap=2048: 48 69 20 53 65 72 76 65 72 21 0A]
2012-03-15 14:45:41,487  DEBUG codec.ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1
Message writtenHi Server!
2012-03-15 14:45:41,487  INFO  logging.LoggingFilter - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty]
2012-03-15 14:45:41,487  INFO  logging.LoggingFilter - RECEIVED: HeapBuffer[pos=0 lim=5 cap=2048: 71 75 69 74 0A]
2012-03-15 14:45:41,487  DEBUG codec.ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1
2012-03-15 14:45:41,487  INFO  logging.LoggingFilter - CLOSED

?分析源码
1.首先看服务器
            // 创徏服务端监控线E?/span>
            IoAcceptor acceptor = new NioSocketAcceptor();
            
            // 讄日志记录?/span>
            acceptor.getFilterChain().addLast("logger", new LoggingFilter());
            
            // 讄~码qo(h)?/span>
            acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
           
            // 指定业务逻辑处理?/span>
            acceptor.setHandler(new HelloServerHandler());
            
            // 讄端口?/span>
            acceptor.setDefaultLocalAddress(new InetSocketAddress(PORT));
            
            // 启动监听U程
            acceptor.bind();

  1)先创?span style="font-size: 13px; background-color: #eeeeee; ">NioSocketAcceptor nio的接收器Q谈到Socketp说到Reactor模式 
    当前分布式计 Web Services盛行天下Q这些网l服务的底层都离不开对socket的操作。他们都有一个共同的l构Q?/span>
1. Read request
2. Decode request
3. Process service                                     
4. Encode reply
5. Send reply 

但这U模式在用户负蝲增加Ӟ性能下降非常的快。我们需要重新寻找一个新的方案,保持数据处理的流畅,很显Ӟ事g触发机制是最好的解决办法Q当有事件发生时Q会(x)触动handler,然后开始数据的处理?br />Reactor模式cM于AWT中的Event处理?/p>

Reactor模式参与?/strong>

1.Reactor 负责响应IO事gQ一旦发生,q播发送给相应的Handlerd?q类gAWT的thread
2.Handler 是负责非堵塞行ؓ(f)Q类gAWT ActionListenersQ同时负责将handlers与event事gl定Q类gAWT addActionListener


q发pȝ帔R用reactor模式Q简U观察者模式,代替常用的多U程处理方式Q?strong>利用有限的系l的资源Q提高系l的吞吐?/strong>?br />

可以看一下这文章,讲解的很生动具体Q一看就明白reactor模式的好?a >http://daimojingdeyu.iteye.com/blog/828696 
Reactor模式是编写高性能|络服务器的必备技术之一Q它h如下的优点:(x)
    1Q响应快Q不必ؓ(f)单个同步旉所dQ虽然Reactor本n依然是同步的Q?/span>
    2Q编E相对简单,可以最大程度的避免复杂的多U程?qing)同步问题,q且避免了多U程/q程的切换开销Q?/span>
    3Q可扩展性,可以方便的通过增加Reactor实例个数来充分利用CPU资源Q?/span>
    4Q可复用性,reactor框架本n与具体事件处理逻辑无关Q具有很高的复用性; 

2)其次Q再说说NIO的基本原理和使用
    NIO 有一个主要的cSelector,q个cM一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事g发生Ӟ他会(x)通知我们Q传回一l?SelectionKey,我们dq些Key,׃(x)获得我们刚刚注册q的socketchannel,然后Q我们从q个Channel中读取数据,攑ֿQ包准能够读刎ͼ接着我们可以处理q些数据?div>  Selector内部原理实际是在做一个对所注册的channel的轮询访问,不断的轮?目前p一个算?Q一旦轮询到一个channel有所注册的事情发生,比如数据来了Q他׃(x)站v来报告,交出一把钥匙,让我们通过q把钥匙(SelectionKey表示 SelectableChannel ?Selector 中的注册的标记?)来读取这个channel的内宏V?/div>











































陈睿 2012-03-15 14:49 发表评论
]]>底层架构-q程通讯http://www.aygfsteel.com/mikechen/archive/2012/03/12/371703.html陈睿陈睿Mon, 12 Mar 2012 01:57:00 GMThttp://www.aygfsteel.com/mikechen/archive/2012/03/12/371703.htmlhttp://www.aygfsteel.com/mikechen/comments/371703.htmlhttp://www.aygfsteel.com/mikechen/archive/2012/03/12/371703.html#Feedback2http://www.aygfsteel.com/mikechen/comments/commentRss/371703.htmlhttp://www.aygfsteel.com/mikechen/services/trackbacks/371703.html一Q基本原?/strong>
    主要是要实现|络之间的通讯Q?span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">|络通信需要做的就是将从一台计机传输到另外一台计机Q基于传输协议和|络IO来实玎ͼ其中传输协议比较出名的有http?tcp、udp{等Qhttp、tcp、udp都是在基于Socket概念上ؓ(f)某类应用场景而扩展出的传输协议,|络IOQ主要有bio、nio、aio 三种方式Q所有的分布式应用通讯都基于这个原理而实现?br />
二:(x)实践
在分布式服务框架中,一个最基础的问题就是远E服务是怎么通讯的,在Java领域中有很多可实现远E通讯的技?RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS
既然引入Zq么多技术,那我们就道深入挖掘下去Q了解每个技术框架背后的东西Q?br />1.首先看RMI
     RMI主要包含如下内容Q?nbsp;
     q程服务的接口定?nbsp;
      ·q程服务接口的具体实?nbsp;
      ·桩(StubQ和框架QSkeletonQ?/span>文g 
      ·一个运行远E服务的服务?nbsp;
      ·一个RMI命名服务Q它允许客户?/a>d现这个远E服?nbsp;
      ·
c?/a>文g的提供者(一个HTTP或者FTP服务器) 
      ·一个需要这个远E服务的客户端程?/span> 
    
    来看下基于RMI的一ơ完整的q程通信q程的原理:(x)
    1)客户端发赯求,h转交至RMI客户端的stubc;
    2)stubcdh的接口、方法、参数等信息q行序列化;
    3)Ztcp/ip序列化后的传输至服务器端Q?/div>
    4)服务器端接收到流后{发至相应的skeltonc;
    5)skeltoncdh的信息反序列化后调用实际的处理类Q?/div>
    6)处理cd理完毕后结果返回给skeltonc;
    7)Skeltoncdl果序列化,通过tcp/ip流传送给客户端的stubQ?/div>
    8)stub在接收到后反序列化Q将反序列化后的Java Objectq回l调用者?br />
     RMI应用U协议内容:(x)
1、传输的标准格式是什么?
      是Java ObjectStream?/div>
2、怎么样将h转化Z输的?
      ZJava串行化机制将h的java object信息转化为流?/div>
3、怎么接收和处理流Q?/div>
      Ҏ(gu)采用的协议启动相应的监听端口Q当有流q入后基于Java串行化机制将进行反序列化,q根据RMI协议获取到相应的处理对象信息Q进行调用ƈ处理Q处理完毕后的结果同样基于java串行化机制进行返回?/div>
4、传输协议是Q?/div>
      tcp/ip?br />
原理讲了Q开始实践:(x)
创徏RMIE序?个步骤:(x) 
1、定义一个远E接口的接口Q该接口中的每一个方法必d明它?yu)生一个RemoteException异常?nbsp;
2、定义一个实现该接口的类?nbsp;
3、用RMICE序生成q程实现所需的残根和框架?nbsp;
4、创Z个服务器Q用于发?中写好的cR?nbsp;
5. 创徏一个客L(fng)序进行RMI调用?nbsp;
6、启动rmiRegistryq运行自qq程服务器和客户E序     
    
 
1Q首先创E接口:(x)
 /**
 * q程接口
 * 
 * @author mike
 *
 * 
@since 2012-3-14
 
*/
public interface Hello extends Remote {
    /**
     * 试r(sh)mi 
     * 
     * 
@return   hello
     * 
@throws RemoteException
     
*/
    public String hello()throws RemoteException;
}
       
     2Q创建接口实?br />        package com.gewara.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 * q程接口实现
 * 
 * 
@author mike
 *
 * 
@since 2012-3-14
 
*/
public class HelloImpl extends UnicastRemoteObject implements Hello {

    /**
     * seria id
     
*/
    private static final long serialVersionUID = -7931720891757437009L;

    protected HelloImpl() throws RemoteException {
        super();
    }

    /**
     * hello实现
     * 
     * 
@return hello world
     * 
@throws RemoteException
     
*/
    public String hello() throws RemoteException {
        return "hello world";
    }

}

       3)创徏服务器端
        package com.gewara.rmi;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class Server {
    
    private static final String RMI_URL="rmi://192.168.2.89:10009/server";
    
    /**
     * RMI Server
     
*/
    public Server() {  
        try {  
            //创徏q程对象
            Hello hello=new HelloImpl();
            
            //启动注册?/span>
            LocateRegistry.createRegistry(10009);
            
            //名U绑定到对象
            Naming.bind(RMI_URL, hello);
            
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
    
    /**
     * 
@param args
     
*/
    public static void main(String[] args) {
        new Server();

    }

}

        4)创徏客服?br />        package com.gewara.rmi;

import java.rmi.Naming;

public class Client {

    private static final String RMI_URL="rmi://192.168.2.89:10009/server";
    /**
     * 
@param args
     
*/
    public static void main(String[] args) {
         try {  
                   String result=((Hello)Naming.lookup(RMI_URL)).hello();
                System.out.println(result);  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
    }

}

    5)先启动服务器端,然后再启动客L(fng)
       昄l果Qhello world

׃涉及(qing)到的内容比较多,打算每一里讲一个远E通讯框架Ql详解RMI
    
三:(x)详解RMI内部原理
1. RMI基本l构Q包含两个独立的E序Q服务器和客L(fng)Q服务器创徏多个q程对象Q让q程对象能够被引用,{待客户端调用这些远E对象的Ҏ(gu)。客L(fng)从服务器获取C个或则多个远E对象的引用Q然后调用远E对象方法,主要涉及(qing)到RMI接口、回调等技术?br />
2.RMI回调Q服务器提供q程对象引用供客L(fng)调用Q客L(fng)d调用服务器,如果服务器主动打调用客L(fng)Q这叫回调?br />
3.命名q程对象Q客L(fng)通过一个命名或则一个查找服务找到远E服务,q程服务包含Java的命名和查找接口(Java Naming and Directory Interface)JNDI
RMI提供了一U服?RMI注册rmiregistry,默认端口Q?099Q主机提供远E服务,接受服务Q启动注册服务的命o(h)Qstart rmiregistry
客户端用一个静态类Naming到达RMI注册处,通过Ҏ(gu)lookup()Ҏ(gu)Q客h询问注册?/div>


陈睿 2012-03-12 09:57 发表评论
]]> վ֩ģ壺 Դ| | Ӫ| | | Դ| | | ľ| | | | | | | | | | Ǹ| ַ| ¬| | ˶| | | ӽ| ڳ| ½| | ƽȪ| ɽ| ֿ| | ͨ| ߰| | ̷| | | | ͷ|