加入收藏 | 设为首页 | 会员中心 | 我要投稿 三明站长网 (https://www.0598zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

聊聊高性能服务器Server之Reactor模型

发布时间:2019-02-05 18:12:08 所属栏目:外闻 来源:正经地扯淡
导读:副标题#e# 在这个充斥着云的时代,我们使用的软件可以说99%都是C/S架构的! 你发邮件用的Outlook,Foxmail等 你看视频用的优酷,土豆等 你写文档用的Office365,googleDoc,Evernote等 你浏览网页用的IE,Chrome等(B/S是特殊的C/S) C/S架构的软件带来的一个明显

优缺点很明显。这里主要说下缺点:主要瓶颈在线程上。每个连接都会建立一个线程。虽然线程消耗比进程小,但是一台机器实际上能建立的有效线程有限,以Java来说,1.5以后,一个线程大致消耗1M内存!且随着线程数量的增加,CPU切换线程上下文的消耗也随之增加,在高过某个阀值后,继续增加线程,性能不增反降!而同样因为一个连接就新建一个线程,所以编码模型很简单!

就性能瓶颈这一点,就确定了BIO并不适合进行高性能服务器的开发!像Tomcat这样的Web服务器,从7开始就从BIO改成了NIO,来提高服务器性能!

NIO

  • NIO客户端代码(连接)
  1. //获取socket通道 
  2. SocketChannel channel = SocketChannel.open();         
  3. channel.configureBlocking(false); 
  4. //获得通道管理器 
  5. selector=Selector.open();         
  6. channel.connect(new InetSocketAddress(serverIp, port)); 
  7. //为该通道注册SelectionKey.OP_CONNECT事件 
  8. channel.register(selector, SelectionKey.OP_CONNECT); 
  • NIO客户端代码(监听)
  1. while(true){ 
  2.     //选择注册过的io操作的事件(第一次为SelectionKey.OP_CONNECT) 
  3.    selector.select(); 
  4.    while(SelectionKey key : selector.selectedKeys()){ 
  5.        if(key.isConnectable()){ 
  6.            SocketChannel channel=(SocketChannel)key.channel(); 
  7.            if(channel.isConnectionPending()){ 
  8.                channel.finishConnect();//如果正在连接,则完成连接 
  9.            } 
  10.            channel.register(selector, SelectionKey.OP_READ); 
  11.        }else if(key.isReadable()){ //有可读数据事件。 
  12.            SocketChannel channel = (SocketChannel)key.channel(); 
  13.            ByteBuffer buffer = ByteBuffer.allocate(10); 
  14.            channel.read(buffer); 
  15.            byte[] data = buffer.array(); 
  16.            String message = new String(data); 
  17.            System.out.println("recevie message from server:, size:" 
  18.                + buffer.position() + " msg: " + message); 
  19.        } 
  20.    } 
  • NIO服务端代码(连接)
  1. //获取一个ServerSocket通道 
  2. ServerSocketChannel serverChannel = ServerSocketChannel.open(); 
  3. serverChannel.configureBlocking(false); 
  4. serverChannel.socket().bind(new InetSocketAddress(port)); 
  5. //获取通道管理器 
  6. selector = Selector.open(); 
  7. //将通道管理器与通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件, 
  8. serverChannel.register(selector, SelectionKey.OP_ACCEPT); 
  • NIO服务端代码(监听)
  1. while(true){ 
  2.     //当有注册的事件到达时,方法返回,否则阻塞。 
  3.    selector.select(); 
  4.    for(SelectionKey key : selector.selectedKeys()){ 
  5.        if(key.isAcceptable()){ 
  6.            ServerSocketChannel server = 
  7.                 (ServerSocketChannel)key.channel(); 
  8.            SocketChannel channel = server.accept(); 
  9.            channel.write(ByteBuffer.wrap( 
  10.             new String("send message to client").getBytes())); 
  11.            //在与客户端连接成功后,为客户端通道注册SelectionKey.OP_READ事件。 
  12.            channel.register(selector, SelectionKey.OP_READ); 
  13.        }else if(key.isReadable()){//有可读数据事件 
  14.            SocketChannel channel = (SocketChannel)key.channel(); 
  15.            ByteBuffer buffer = ByteBuffer.allocate(10); 
  16.            int read = channel.read(buffer); 
  17.            byte[] data = buffer.array(); 
  18.            String message = new String(data); 
  19.            System.out.println("receive message from client, size:" 
  20.                + buffer.position() + " msg: " + message); 
  21.        } 
  22.    } 

(编辑:三明站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读