分布式架构底层基础入门---NIO、BIO对比(中)脑图分析

一、初学者,刚刚开始学习socket通信的代码的时候,写的代码结构,基本就是下图的这种方式:

       这种结构,服务端支持的并发,大家可以尝试想一下,是多少呢???

       因为连接阻塞的存在,当没有客户端连接的时候,服务端就阻塞在accept方法这里,当有客户端连接进来的时候,Socket主进程,继续向下执行,在执行read方法之前,需要判断连接是否就绪。一旦进入read方法,Socket主进程会进入IO阻塞。

       这个时候Client2请求连接,SocketServer由于阻塞在read()方法,没有办法响应后续进来的请求;

       这样看,我们服务端的能够支持的并发数是多少呢???毋庸置疑了,肯定是1啦。。。

分布式架构底层基础入门---NIO、BIO对比(中)脑图分析_第1张图片

 二、不引入NIO,我们如何将服务端改造成支持超并发呢,继续上图:

我们引入线程池后,看一下图示,下图中,服务端,由一个守护线程,负责轮询,等待客户端连接,一旦监听到连接,则将当前的Socket连接,作为构建任务的入参,新建任务,并将任务提交到连接池。

这样,我们看,服务的并发数,不在是1 了,而是由线程池并发执行。性能提升很大。

分布式架构底层基础入门---NIO、BIO对比(中)脑图分析_第2张图片

 

三、技术日新月异,我们还是需要不断地接纳新事物,自己才能有成长,接下来,我们聊一下NIO:

    我们引入java.nio工具包,nio是指new io,接下来,我们演示一下NIO,先上图,后代码分析:

     分布式架构底层基础入门---NIO、BIO对比(中)脑图分析_第3张图片

代码示例:

package com.jason.thread.socket.nio;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jason.thread.socket.body.ServiceRequest;
import com.jason.thread.socket.nio.step2.MyNIoThread;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.net.SocketOption;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import static java.lang.Thread.sleep;

/**
 * @program: JasonSpringMybatis
 * @description
 * @author: 大龄程序猿
 * @create: 2020-06-10 21:27
 **/
public class NewIoServer {
    private static Executor executor= Executors.newFixedThreadPool(10);
    public static void main(String[] args) {
        try {
            ServerSocketChannel   serverSocketChannel=ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);//设置连接非阻塞
            serverSocketChannel.bind(new InetSocketAddress(8080));
            while(true)
            {
                SocketChannel socketChannel=serverSocketChannel.accept();//通过上面的参数,设置连接非阻塞
                if(socketChannel!=null)
                {
                    executor.execute(new MyNIoThread(socketChannel));
                }else
                {
                    System.out.println("没有连接");
                    sleep(1000);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

package com.jason.thread.socket.nio.step2;

import com.alibaba.fastjson.JSONObject;
import com.jason.thread.socket.body.ServiceRequest;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

import static java.lang.Thread.sleep;

/**
 * @program: JasonSpringMybatis
 * @description
 * @author: 大龄程序猿
 * @create: 2020-06-11 22:25
 **/
public class MyNIoThread  implements Runnable {
    private SocketChannel  socketChannel;

    public MyNIoThread(SocketChannel socketChannel) {
        this.socketChannel = socketChannel;
    }

    @Override
    public void run() {
        try {
            ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
            socketChannel.read(byteBuffer);
            byteBuffer.flip();
            ServiceRequest serviceRequest= JSONObject.parseObject(new String(byteBuffer.array()),ServiceRequest.class);
            ServiceRequest.RequestData  requestData=serviceRequest.getData();
            System.out.println("收到来自:["+serviceRequest.getFromTalker()+"] 的消息;消息标题:["+requestData.getTitle()+"]"
                    +";消息内容:["+requestData.getContent()+"]");
            requestData.setTitle("互联网架构师内容");
            requestData.setContent("努力学习,成为一流的架构师");
            serviceRequest.setFromTalker("Tom");
            serviceRequest.setToTalker("Jerry");
            serviceRequest.setData(requestData);
            String response=JSONObject.toJSONString(serviceRequest);
            byteBuffer.clear();
            byteBuffer.put(response.getBytes());
            byteBuffer.flip();
            socketChannel.write(byteBuffer);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

package com.jason.thread.socket.nio;

import com.alibaba.fastjson.JSONObject;
import com.jason.thread.socket.body.ServiceRequest;
import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

/**
 * @program: JasonSpringMybatis
 * @description
 * @author: 大龄程序猿
 * @create: 2020-06-10 21:51
 **/
public class NewIoClient {
    public static void main(String[] args) {
        try {
            SocketChannel   socketChannel=SocketChannel.open(new InetSocketAddress(8080));
            //并不意味着连接已经建立好
            if(socketChannel.isConnectionPending())
            {
                socketChannel.finishConnect();
            }
            //socketChannel.configureBlocking(false);
            ByteBuffer   buffer=ByteBuffer.allocate(1024);
            buffer.put(initRequest().getBytes());
            buffer.flip();
            socketChannel.write(buffer);
            buffer.clear();

            int i=socketChannel.read(buffer);
            if(i>0)
            {
                System.out.println("收到服务端的数据"+new String(buffer.array()));
            }else
            {
                System.out.println("没有收到数据");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    @Test
    public static String initRequest()
    {
        ServiceRequest   request=new ServiceRequest(true,"jerry","Jaosn");
        ServiceRequest.RequestData   requestData= request.new RequestData("AA","CC");
        request.setData(requestData);
        String jason=JSONObject.toJSONString(request);
        System.out.println(jason);
        return jason;
    }
}

 

   

 

 

你可能感兴趣的:(分布式架构底层基础入门---NIO、BIO对比(中)脑图分析)