本帖最后由 renxiao2003 于 2020-04-29 22:00 编辑
(1)大家可以谈谈自己对“分布式中间件”的认识和理解,可以说一说自己所知晓的目前市面上比较流行、应用比较广泛的中间件有哪些。
(2)对于分布式系统架构的整体演进历程以及中间件的落地实施,读者朋友们认为中间件起到的主要作用是什么?还能承担起哪些职责?(1)通信支持 中间件为其所支持的应用软件提供平台化的运行环境,该环境屏蔽底层通信之间的接口差异,实现互操作,所以通信支持是中间件一个最基本的功能。早期应用与分布式的中间件交互主要的通信方式为远程调用和消息两种方式。 通信模块中,远程调用通过网络进行通信,通过支持数据的转换和通信服务,从而屏蔽不同的操作系统和网络协议。远程调用是提供给予过程的服务访问,为上层系统只提供非常简单的编程接口或过程调用模型。消息提供异步交互的机制。 (2)应用支e79fa5e98193e59b9ee7ad9431333431363665持 中间件的目的就是服务上层应用,提供应用层不同服务之间的互操作机制。它为上层应用开发提供统一的平台和运行环境,并封装不同操作系统提供API接口,向应用提供统一的标准接口,使应用的开发和运行与操作系统无关,实现其独立性。 中间件松耦合的结构,标准的封装服务和接口,有效的互操作机制,从而给应用结构化和开发方法提供有力的支持。 (3)公共服务 公共服务是对应用软件**性功能或约束的提取。将这些共性的功能或者约束分类实现,并支持复用,作为公共服务,提供给应用程序使用。通过提供标准、统一的公共服务,可减少上层应用的开发工作量,缩短应用的开发时间,并有助于提供应用软件的质量。
(3)本书着重介绍了几款目前应用比较广泛的中间件:Redis、RabbitMQ、ZooKeeper和Redisson及其丰富的应用场景,大家可以分享还有哪些典型的应用场景?一、Redis
1)、Redis高并发与快速响应原因
redis纯内存,读写速度特别块
redis单线程,避免线程切换和静态消耗
redis使用IO多路复用技术,可以处理并发连接
2)、IO多路技术
单个线程通过跟踪记录每一个I/O流的状态来同时管理多个I/O流。主要实现技术有三种select、poll、epoll。epoll中有三个方法:
当执行epoll_create时,创建了红黑树和就绪列表;
当执行epoll_ctl时,若增加socket包炳,则检查红黑树是否存在,存在则立即返回,不存在添加红黑树。然后向内核注册回调函数,用于中断事件来临时向准备就绪列表中插入数据;
当执行epoll_wait时,立即返回准备就绪列表中的数据。
二、RabbitMQ
消息生产者生产的消息通过交换器被绑定到对应的队列中去,消息消费者通过信道消费消息队列中的消息。
1)、交换器有四种类型:
Direct键:如果路由键完全匹配,消息就被投递到相应的队列
Fanout广播分发:如果交换器收到消息,将会广播到所有绑定的队列上
topic模式匹配:可以使来自不同源头的消息通过匹配规则能够到达同一个队列
headers:不常用,与Direct一致,匹配AMQP消息的header。
2)、消息生产者如何确认消息被正确发送到队列
将信道设置为confirm模式,所有发送到信道的消息都会生成一个唯一确定的ID
一旦消息被发送到目的队列或者消息被持久化,那么就会给消息生产者发送一个确认
若RabbitMQ内部错误导致消息丢失,会发送一条未确认通知给消息生成者
3)、消息消费者如何确认接收了消息
消费者没接收一条消息,都必须进行确认。只有消费者确认了消息,RabbitMQ才会从队列中删除消息。
4)、如何避免消息重复投递或重复消费
消息生产时,MQ针对每一条消息都会生成一个唯一确定的ID,作为去重和幂等性依据
消息消费时,每一个消息体都必须要有一个全局业务唯一ID,作为去重和幂等性依据
三、Zookeeper
Zookeeper集群是一个基于主从复制的高可用集群,有三种角色:
leader:所有写操作必须通过leader完成再由leader将写操作广播给其他服务器。只要有超过半数节点写入成功,该写请求就会被提交
follower:follower可直接处理并返回客户端的读请求。同时会将写请求转发给leader处理。并且负责在leader处理写请求时对请求进行投票。
observer:不参与投票,可接收客户端的连接,并将写请求转发给leader节点
1)、工作原理(原子广播)
Zookeeper的核心是原子广播,这个机制保证了各个server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在leader崩溃后,Zab就进入了恢复模式,当leader被选举出来,且大多数server完成了和leader的状态同步之后,恢复模式就结束了。状态同步保证了leader和server具有相同的系统状态。
为了保证事务一致性,zk采取了递增的事务id号(zxid)标识事务。所有提议都被加上了zxid。zxid由64位组成,高32位用来标识leader变化,低32位用来递增。
2)、投票机制
每个server启动以后都询问其他server投票给谁,对于其他server的询问,server会根据自身状态回复自己推荐的leader的id和上一次处理事务的zxid。(系统启动时,每个server都会推荐自己)
收到所有server后,计算出zxid最大的那个server,并将下一次投票server信息设置为它
计算获得票数最多的server为获胜者。超过半数,则被选为leader。否则,继续这个过程。
leader开始等待server连接。
follower连接leader,将最大的zxid发送给leader。
leader根据follerer的zxid确定同步点,至此选举结束。
选举阶段完成leader同步后通知folloer已经称为update状态。
follower收到update消息后,可以重新连接client的请求进行服务。
(4)本书花了大篇幅的笔墨介绍了Redis的应用场景——抢红包系统的设计与开发,谈谈你对整体实现流程的理解以及还有哪些可以改进的地方?
1、修改stop-writes-on-bgsave-error为no
当前配置为yes,分别修改redis.conf和当前实例
#redis.conf
stop-writes-on-bgsave-error no #登陆redis执行
config set stop-writes-on-bgsave-error no
查看
config get stop-writes-on-bgsave-error 此参数设置为no,可以避免MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk。 2、开启appendonly
当前配置为appendonly no,即禁用了appendonly功能,这样的风险是一旦redis实例crash,重启后只能恢复到最近1次快照(即bgsave产生的rdb文件),可能会丢失很长时间的数据。
appendonly可以实现准实时刷盘,默认每1s将数据追加到磁盘文件,也可以配置成每次修改都刷盘,当redis crash时最大限度的保证数据完整性。 修改redis.conf和当前实例
#redis.conf
appendonly yes
appendfsync everysec #登陆redis执行
config set appendonly yes
config get appendonly
同时需要设置no-appendfsync-on-rewrite yes
这两个参数可以确保redis每1分钟刷盘一次,也可以设置appendfsync always,即每次写都实时刷盘,避免redis crash造成数据丢失
3、添加最大内存阈值maxmemory
此参数限制redis可以占有的最大内存,一旦超出便淘汰过期key,可以避免因内存不足触发OOM。
这个参数和实际部署环境有关,要根据实际情况指定参数值,比如3G或者4G。
参考配置
maxmemory 3G
maxmemory-policy volatile-lru
maxmemory-samples 5 此参数可以避免redis过度占用机器内存,避免因内存不足导致的各种错误
|