1.分布式系统的基础知识
网络IO实现方式:
1)BIO
BIO即Blocking IO,采用阻塞的方式实现。也就是一个套接字需要使用一个线程来处理。
不管是磁盘I/O还是网络I/O,数据在写入OutputStream或者从InputStream读取时都有可能会阻塞,一旦有阻塞,线程将会失去CPU的使用权,这在当前的大规模访问量和有性能要求的情况下是不能被接受的。虽然当前的网络I/O有一些解决办法,如一个客户端对应一个处理线程,出现阻塞时只是一个线程阻塞而不会影响其他线程工作,还有为了减少系统线程的开销,采用线程池的办法来减少线程创建和回收的成本,但是在一些使用场景下仍然是无法解决的。如当前一些需要大量HTTP长连接的情况,像淘宝现在使用的Web旺旺,服务端需要同时保持几百万的HTTP连接,但并不是每时每刻这些连接都在传输数据,在这种情况下不可能同时创建这么多线程来保持连接。如果要设置线程的优先级高低就更难了。
2)NIO
NIO即NonBlocking IO,基于事件驱动思想,采用的是Reactor模式。相对于BIO,明显的好处是不需要为每个套接字分配一个线程,而可以在一个线程中处理多个Socket套接字相关的工作。
React不是用单个线程去应对单个Socket套接字,而是统一通过Reactor对所有客户端的Socket套接字的事件做处理,然后派发到不同的线程中。这样就解决了BIO中为支撑更多的Socket套接字而需要打开更多线程的问题。
相关文档:https://www.jianshu.com/p/415325c263b2
NIO作出的改进就是“一个请求一个线程”,在连接到服务端的众多socket中,只有需要进行IO操作的才能获取服务端的处理线程进行IO。这样就不会因为线程不够用而限制了socket的接入。客户端的socket连接到服务端时,就会在事件分离器注册一个 IO请求事件 和 IO 事件处理器。在该连接发生IO请求时,IO事件处理器就会启动一个线程来处理这个IO请求,不断尝试获取系统的IO的使用权限,一旦成功(即:可以进行IO),则通知这个socket进行IO数据传输。
3)AIO
AIO就是AsynchronousIO,就是异步IO。AIO和NIO的区别是,AIO采用Proactor模式,AIO在进行读/写操作时,只需要调用相应的read/write方法,并且传入CompletionHandler(动作完成的处理器);动作完成后,会调用CompletionHandler(动作完成的处理器)。NIO的通知是发生在动作之前,是在可读、可写的时候,Selector发现这些事件后调用Handler处理。
分布式应用
1)请求发起者与请求处理者中间有一个硬件复杂均衡设备,所有的请求都要走这个设备来完成转发的控制。
2)第二种与第一种差别不大,差别仅在于中间的硬件负载均衡设备更换成了LVS,这种方式的主要的特点是代价低,而且可控性较强,即你可以相对自由地按照自己的需要去增加负载均衡的策略。
我们称这种方式为透明代理,这种方式对于请求发起者和请求处理者都是透明的。但是问题是一增加了流量的转发和网络的时延,二是一旦透明代理出了问题,所有的请求都不可达了。
下面是基于LVS的负载均衡文档:https://blog.csdn.net/weixin_40470303/article/details/80541639
3)第三种方式,在请求发起方和请求处理方这两个集群中间没有代理服务器这样的设备存在,而是请求发起方和请求处理方式的直接连接。在请求发起方和请求处理方的直接连接外部,有一个"名称服务"的角色,它的作用主要有两个,一个是收集提供请求处理的服务器的地址信息;另外一个是供这些地址信息给请求发起方。当然,名称服务只是起到了一个地址交换的作用,在发起请求的机器上,需要根据从名称服务得到的地址进行负载均衡的工作。也就是说,原来在透明代理上做的工作被拆分到了名称服务和发起请求的机器上了。
4)第四种方式,增加规则服务器&#x