命名服务

选举

集群管理

分布式队列

分布式锁

复制代码

1.分布式队列的应用场景

① 业务解耦

实现应用之间的解耦,这时所有的下游系统都订阅队列,从而获得一份实时完整的数据

解耦的应用非常广泛,比如我们常见的发货系统和订单系统,以前业务串行的时候,发货系统一定要等订单系统生成完对应的订单才会进行发货。这样如果订单系统崩溃,那发货系统也无法正常运作,引入消息队列后,发货系统是正常处理掉发货的请求,再把已发货的消息存入消息队列,等待订单系统去更新并生成订单,但是此时,订单系统就算崩溃掉,我们也不会一直不发货。

② 异步处理

可以看到在此场景中队列被用于实现服务的异步处理,这样做的好处在于我们可以更快地返回结果和减少等待,实现步骤之间的并发,提升了系统的总体性能等

② 流量削峰

2.zk的分布式队列

① 逻辑分析

顺序节点的应用,类似于我们在用实现分布式锁的时候如何去处理惊群效应的做法。 且根据队列的特点:FIFO(先进先出),入队时我们创建顺序节点(ps:为什么上面我们是用了顺序节点而不是说是临时顺序节点,是因为我们根本不考虑客户端挂掉的情况)并把元素传入队列,出队时我们取出最小的节点。使用watch机制来监听队列的状态,在队列满时进行阻塞,在队列空时进行写入即可。

入队操作

如上图,我们生产者需要对资源进行访问时,会申请获取一个分布式锁,如果未成功抢占锁,就会进行阻塞,抢到锁的生产者会尝试把任务提交到消息队列,此时又会进行判断,如果队列满了,就监听队列中的消费事件,当有消费队列存在空位时进行入队,未消费时阻塞。入队时它会进行释放锁的操作,唤醒之前抢占锁的请求,并让之后的生产者来获取。

出队操作

出队和入队的机制是十分相似的。

② JDK阻塞队列操作

阻塞队列:—线程安全的阻塞队列

它以4种形式出现,对于不能立即满足但是在将来某一时刻可能满足的操作,4种形式的处理方式皆不同

1.抛出一个异常

2.返回一个特殊值,true or false

3.在操作可以成功前,无限阻塞当前线程

4.放弃前只在给定的最大时间限制内阻塞

复制代码

我们将会实现这个阻塞队列接口来实现我们的分布式队列JAVA高级架构圈子

内容三:分布式队列的代码实现

class , java.io.

继承了,可以省略部分基础实现

① 基本的配置信息及使用到的参数

首先我们需要一个的客户端,然后是分布式队列的存放元素的位置,指定了一个默认的根目录e,把队列中的元素存放于/下,写锁节点代表往队列中存放元素,读锁节点代表从队列中去取元素,这个设计简单点来说就是,作为最大的目录,其下有3个子目录,分别是,和,其他的就是一些需要使用到的配置信息

应用程序的后端_后端程序员chatgpt应用场景_后端场景题

② 构造器

提供两个构造方法,一个为使用默认参数实现,另外一个是自定义实现

此时在我们分布式锁的构造器中,()的参数true是指如果我父目录并没有事先创建完成,这个方法会自动创建出父目录,这样就不怕我们在跑程序之前遗漏掉一些创建文件结构的工作

③ 初始化队列信息的init()方法

重新定义好读锁写写锁和任务存放路径,然后把连接上,创建作为任务元素目录,参数true上文作用已经提到了

④ 使用put()方法进行队列元素入队操作

()方法是一个简单的参数检查,我们也可以定义有关于znode的命名规范的一些检查,不过一般情况下只要是类型的参数都是没有问题的

size()方法也很简单,就是先取得父目录然后调用自带的()方法得出结果返回即可

主要就是通过s()监听子节点的数据变化,在size() = ,就会判断队列已经被填满,从而进行阻塞

在()方法执行后,我们的等待线程被唤醒,这时重新执行put(e),尝试重新入队

入队操作由(e)来完成,就是创建顺序节点的步骤

⑤ 消费操作take

附:生产者和消费者的模拟

① 生产者

模拟了两台服务器,两个并发,每睡3秒钟就往消息队列put

② 消费者

执行结果

① 先执行生产者

此时没有消费者去进行消费,所以队列没一下子就满了,我们需要注意,阻塞的不仅仅是队列,分布式锁也被阻塞了。

② 启动消费者

基本上是生产者放入一个消费者就消费一个的状态。从而证明该分布式队列已经正常工作了

粉丝福利

以上技术可以加入JAVA高级架构: 圈子里面有阿里,百度,点评,架构师直播指导,针对工作1–5的Java程序员提升自己,还有架构学习资料,jvm,手写,分布式,高可用,高性能,数据结构,, 获取。

以上技术可以加入JAVA高级架构圈子 里面有阿里,百度,点评,架构师直播指导,针对工作1–5的Java程序员提升自己,还有架构学习资料,jvm,手写,分布式,高可用,高性能,数据结构,, 获取。