Dubbo
Dubbo是什么
本质:一个jar包,一个分布式框架,一个远程服务调用的分布式框架
Dubbo的好处
- 透明化的远程方法调用,就像调用本地方法一样远程调用方法,只需简单配置,没有任何API侵入
- 软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点
- 服务自动注册与发现,不再需要写死服务 提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者
Dubbo构架
节点角色说明:
Provider(生产者): 暴露服务的服务提供方。
Consumer(消费者): 调用远程服务的服务消费方。
Container:Dubbo容器,依赖于Spring容器
Registry:注册中心,当Container启动时,把所有可以提供的服务列表上Registry中进行注册
Monitor:监听器
如图,我们可以简单理解为web1234需要调用service1234的服务,所以web1234是消费者,service1234是生产者。
如果是消费者直接调用生产者的服务,会产生
Regustry(注册中心):服务注册与发现的注册中心。dubbo推荐的是zookeeper,zookeeper是用于分布式中一致性处理的框架。
简单的讲,zookeeper就是个中介,卖楼的(生产者)把楼盘信息放在中介(注册中心)那里,想买楼的(消费者)去中介那里获得楼盘资源清单。
虚线为异步访问,实线为同步访问
蓝色虚线:都是在启动的时候完成的功能
红色线:都是在运行过程中执行的功能
- 服务容器负责启动,加载,运行服务提供者
- 服务提供者(生产者) 在启动时,向注册中心注册自己提供的服务
- 服务消费者在启动时,向注册中心订阅自己所需的服务
- 注册中心返回提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者机型调用,如果调用失败,再选另一台调用
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
Zookeeper
zookeeper是什么
他是一个分布式服务框架,是Apache Hadoop的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等
简单来说 zookeeper=文件系统+监听通知机制
文件系统
zookeeper维护一个类似文件系统的数据结构
每个子目录项如NameService都被称作为znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的
有四种类型的znode
- Persistent - 持久化顺序编号目录节点客户端与zookeeper断开连接后,该节点依旧存在
- PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
- EPHEMERAL-临时目录节点客户端与zookeeper断开连接后,该节点被删除
- EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
监听通知机制
客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。
zookeeper能做什么
zookeeper功能非常强大,可以实现诸如分布式应用配置管理、统一命名服务、状态同步服务、集群管理等功能,我们这里拿比较简单的分布式应用配置管理为例来说明。
假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦,现在把这些配置全部放到zookeeper上去,保存在 zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。
Netty
有了Netty,你可以实现自己的HTTP服务器,FTP服务器,UDP服务器,RPC服务器,WebSocket服务器,Redis的Proxy服务器,MySQL的Proxy服务器等等。
回顾HTTP服务器的原理
- 创建一个ServerSocket,监听并绑定一个端口
- 一系列客户端来请求这个端口
- 服务器使用Accept,获得一个来自客户端的Socket连接对象
- 启动一个新线程处理链接- 读Socket,得到字节流- 解码协议,得到Http请求对象- 处理Http请求,得到一个结果,封装成一个HttpResponse对象- 编码协议,将结果序列化字节流 写Socket ,将字节流发给客户端
- 继续循环步骤3
HTTP服务器之所以被称为HTTP服务器,是因为编码解码协议是HTTP协议,如果协议是Redis协议,那它就成了Redis服务器
如果协议是WebSocket,那它就成了WebSocket服务器,等等。 使用Netty你就可以定制编解码协议,实现自己的特定协议的服务器。
NIO
上面是一个传统处理http的服务器,但是在高并发的环境下,线程数量会比较多,System load也会比较高,于是就有了NIO。
NIO代表的一个词汇叫做IO多路复用。它是由操作系统提供的系统调用早期这个操作系统调用的名字是select,但是性能低下,后来渐渐演化成了Linux下的epoll和Mac里的kqueue。我们一般就是说epoll,因为没有人拿苹果电脑作为服务器使用对外提供服务。
Netty就是基于java NIO技术封装的一套框架,因为原生的Java NIO使用起来没那么方便,而且还有臭名昭著的bug,Netty把它封装之后,提供了一个易于操作的使用模式和接口,用户使用起来也就便捷多了。
NIO的三大核心部分:Channel(通道),Buffer(缓冲区),Selector。传统IO基于字节流和字符流就行操作,而NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道
NIO和传统IO之间的一个最大区别是,IO是面向流的,NIO是面向缓冲区的。Java IO面向流意味着每次从流中读取一个或多个字节,直至读取所有字节,他们没有被缓存在任何地方。此外,他不能前后移动流中的数据。如果需要前后移动从流中获取的数据,需要先将他缓存到一个缓冲区。NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需要确保更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据
IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。 NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变得可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。
BIO(Blocking IO)
- 客户端监听时,Accept是阻塞的,只有新连接来了,Accept才会返回,主线程才能继续
- 读写socket时,Read是阻塞的,只有请求消息来了,Read才能返回,子线程才能继续处理
- 读写socket时,Write是阻塞的,只有客户端把消息收了,Write才能返回,子线程才能继续读取下一个请求
传统的BIO模式下,从头到尾的所有线程都是阻塞的,这些线程就干等着,占用系统的资源,什么事也不干
NIO使用事件机制,可以用一个线程把Accept,读写操作,请求处理的逻辑全干了。如果什么事都没得做,它也不会死循环,它会将线程休眠起来,直到下一个事件来了再继续干活,这样的一个线程称之为NIO线程。用伪代码表示:
Reactor线程模型
- Reactor单线程模型一个NIO线程+一个accept线程
- Reactor多线程模型
- Reactor主从模型主从Reactor多线程:多个acceptor的NIO线程池用于接受客户端的连接Netty可以基于如上三种模型进行灵活的配置Netty是建立在NIO基础之上,Netty在NIO之上又提供了更高层次的抽象
版权归原作者 若雨叶 所有, 如有侵权,请联系我们删除。