世界快播:设计模式之订阅发布模式 - 行业资讯 -

当前位置:首页  >  行业资讯  > 正文

世界快播:设计模式之订阅发布模式

世界快播:设计模式之订阅发布模式
2023-05-27 06:45:17 来源:博客园
一、简介

订阅发布模式(Publish-Subscribe Pattern)是一种行之有效的解耦框架与业务逻辑的方式,也是一种常见的观察者设计模式,它被广泛应用于事件驱动架构中。

在这个模式中,发布者(或者说是主题)并不直接发送消息给订阅者,而是通过调度中心(或者叫消息代理)来传递消息。 发布者(或者说是主题)并不知道订阅者的存在,而订阅者也不知道发布者的存在。他们彼此唯一的关系就是在调度中心注册成为订阅者或者发布者。


【资料图】

当一个发布者有新消息时,就将这个消息发布到调度中心。调度中心就会将这个消息通知给所有订阅者。这就实现了发布者和订阅者之间的解耦,发布者和订阅者不再直接依赖于彼此,他们可以独立地扩展自己。

在具体的实现中,可以通过消息队列、事件总线等机制来实现调度中心,不同语言和平台都有实现的库和框架,例如 Java 中的 ActiveMQ、RabbitMQ、Kafka等。

订阅发布模式有以下优点:

性能好,发布者发送消息后直接返回不需要等待消费者处理完毕。解耦性较强,发布者和订阅者之间不存在直接依赖,满足高内聚低耦合的设计思想。可以支持一对多、多对多的消息通信模型,提供了更加灵活的消息传递方式。可以动态地增加或删除发布者和订阅者,扩展性较好。二、Java实现发布订阅模式创建订阅者接口,用于接受消息通知。
interface Subscriber {    void update(String message);}
创建发布者,用于发布消息。实现了增加、删除和发布的功能,并且维护了一个订阅列表,
class Publisher {    private Map> subscribers = new HashMap<>();    public void subscribe(String topic, Subscriber subscriber) {        List subscriberList = subscribers.get(topic);        if (subscriberList == null) {            subscriberList = new ArrayList<>();            subscribers.put(topic, subscriberList);        }        subscriberList.add(subscriber);    }    public void unsubscribe(String topic, Subscriber subscriber) {        List subscriberList = subscribers.get(topic);        if (subscriberList != null) {            subscriberList.remove(subscriber);        }    }    public void publish(String topic, String message) {        List subscriberList = subscribers.get(topic);        if (subscriberList != null) {            for (Subscriber subscriber : subscriberList) {                subscriber.update(message);            }        }    }}
我们还实现了两个不同的 Subscriber 实现,一个是 EmailSubscriber,另一个是 SMSSubscriber,用于接受发布者的消息并将其分别发送到邮箱和手机上。
class EmailSubscriber implements Subscriber {    private String email;    public EmailSubscriber(String email) {        this.email = email;    }    public void update(String message) {        System.out.println("Send email to " + email + ": " + message);    }}class SMSSubscriber implements Subscriber {    private String phoneNumber;    public SMSSubscriber(String phoneNumber) {        this.phoneNumber = phoneNumber;    }    public void update(String message) {        System.out.println("Send SMS to " + phoneNumber + ": " + message);    }}
在 Main 类中,我们创建了一个 Publisher 对象,并添加了两个 EmailSubscriber 和两个 SMSSubscriber,分别订阅了 news 主题的更新。我们先给这个主题发送一条消息,然后取消 news 主题的其中一个订阅者,最后我们再次给 news 主题发送一条消息。
public class Main {    public static void main(String[] args) {        Publisher publisher = new Publisher();        Subscriber emailSubscriber1 = new EmailSubscriber("foo@example.com");        Subscriber smsSubscriber1 = new SMSSubscriber("1234567890");        publisher.subscribe("news", emailSubscriber1);        publisher.subscribe("news", smsSubscriber1);        publisher.publish("news", "发布新消息1");        publisher.unsubscribe("news", smsSubscriber1);        publisher.publish("news", "发布新消息2");    }}

打印输出如下:

Send email to foo@example.com: 发布新消息1Send SMS to 1234567890: 发布新消息1Send email to foo@example.com: 发布新消息2
三、Spring中自带的订阅发布模式

Spring的订阅发布模式是通过发布事件、事件监听器和事件发布器3个部分来完成的

这里我们通过 newbee-mall-pro项目中已经实现订阅发布模式的下单流程给大家讲解,项目地址:https://github.com/wayn111/newbee-mall-pro

自定义订单发布事件,继承 ApplicationEvent
public class OrderEvent extends ApplicationEvent {  void onApplicationEvent(Object event) {    ...  }}
定义订单监听器,实现 ApplicationListener
@Componentpublic class OrderListener implements ApplicationListener {    @Override    public void onApplicationEvent(OrderEvent event) {    // 生成订单、删除购物车、扣减库存    ...    }}
下单流程,通过事件发布器 applicationEventPublisher 发布订单事件,然后再订单监听器中处理订单保存逻辑。
@Resourceprivate ApplicationEventPublisher applicationEventPublisher;private void saveOrder(MallUserVO mallUserVO, Long couponUserId, List shopcatVOList, String orderNo) {    // 订单检查    ...    // 生成订单号    String orderNo = NumberUtil.genOrderNo();    // 发布订单事件,在事件监听中处理下单逻辑    applicationEventPublisher.publishEvent(new OrderEvent(orderNo, mallUserVO, couponUserId, shopcatVOList));    // 所有操作成功后,将订单号返回    return orderNo;    ...}

通过事件监听机制,我们将下单逻辑拆分成如下步骤:

订单检查生成订单号发布订单事件,在事件监听中处理订单保存逻辑所有操作成功后,将订单号返回每个步骤都是各自独立不互相影响

如上的代码已经实现了订阅发布模式,成功解耦了下单逻辑。但是在性能上还没有得到优化,因为 Spring Boot 项目中,默认情况下事件监听器是同步处理的,也就是说这里下单流程会等待事件监听器处理完毕才返回,最终影响接口响应时长。

四、使用异步的事件监听发布类

Spring Boot 项目中事件监听发布类是由 SimpleApplicationEventMulticaster这个类实现的,源码中通知订阅者代码如下:可以看到,代码里是有判断 getTaskExecutor()方法返回不为空的话,就交由 executor 执行,负责同步执行。这个时候大家就要问了,这里不是有线程池在异步通知订阅者吗?

不急,博主带大家继续查看源码。可以看到 getTaskExecutor()方法返回一个成员属性,这个成员属性在 SimpleApplicationEventMulticaster类中是通过 setTaskExecutor(@Nullable Executor taskExecutor)方法设置的。我们通过 ctrl + f7查一下 setTaskExecutor(...)方法在哪里被调用过,Ok,到此水落石出,SimpleApplicationEventMulticaster类的 taskExecutor 成员属性一直为 null,所以在通过订阅者的时候一直是同步处理,等待订阅者处理完毕。

对于异步处理,我们可以从2个方面入手:

事件监听器入手,将事件监听器的事件触发方法改为异步执行,例如将生成订单、删除购物车、扣减库存逻辑放入线程池异步执行,或者是在订阅者的通知方法 onApplicationEvent上加上@Async注解,表示该方法异步执行。事件监听发布类入手,设置默认事件监听发布类的taskExecutor属性,通过源码可知,也可以解决。

这里博主给大家介绍下怎么修改事件监听发布类来解决。

/** * 系统启动时執行 */@Componentpublic class SpringBeanStartupRunner implements ApplicationRunner {    @Override    public void run(ApplicationArguments args) throws Exception {        // 设置spring默认的事件监听为异步执行        SimpleApplicationEventMulticaster multicaster = SpringContextUtil.getBean(SimpleApplicationEventMulticaster.class);        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(                5,                10,                60L, TimeUnit.MILLISECONDS,                new LinkedBlockingQueue<>(500),                new CustomizableThreadFactory("newbee—event-task"),                new ThreadPoolExecutor.CallerRunsPolicy()        );        multicaster.setTaskExecutor(threadPoolExecutor);    }}

在系统启动时反射修改SimpleApplicationEventMulticaster类的taskExecutor属性,从而让SimpleApplicationEventMulticaster类支持异步事件通知。

总结

建议大家在日常开发中多加思考哪些业务流程可以适用,例如微服务项目中订单支付成功后需要通知用户、商品、活动等多个服务时,可以考虑使用订阅发布模式。解耦发布者和订阅者,发布者只管发布消息,不需要知道有哪些订阅者,也不需要知道订阅者的具体实现。订阅者只需要关注自己感兴趣的消息即可。这种松耦合的设计使得系统更容易扩展和维护。

关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!

标签:

(责任编辑:news01)
要闻:5月24日国内增塑剂产业链相关产品价格汇总

要闻:5月24日国内增塑剂产业链相关产品价格汇总

产品名规格类别产地 品牌5月23日报价5月24日报价涨跌涨跌幅%单位异辛醇优等品山东9675 009683 338 330 09元
05-25 00:25:36
省招办发布高考相关通知   今年继续采取网上填报志愿方式

省招办发布高考相关通知 今年继续采取网上填报志愿方式

省招办发布高考相关通知今年继续采取网上填报志愿方式---今年我省高考考生继续采取网上填报志愿的方式,分
05-24 23:30:32
新动态:对网络传销要露头就打

新动态:对网络传销要露头就打

北京警方日前通报打击新型传销团伙有关情况,违法犯罪团伙搭建网络平台销售所谓收藏品,通过招募会员、区分
05-24 22:45:59
一种筛选分泌蛋白质的微生物菌株的高通量方法

一种筛选分泌蛋白质的微生物菌株的高通量方法

导读东京工业大学的研究人员最近开发了一种独特的方法来筛选大型文库中的工业上有用的细菌菌株。这种简单的
05-24 21:29:27
自贸试验区开封片区:深耕谋发展 出彩“十四五”

自贸试验区开封片区:深耕谋发展 出彩“十四五”

自贸试验区开封片区建设六年来,大胆试、大胆闯、自主改,切实发挥“为国家试制度、为开放搭平台、为地...
05-24 20:38:29
省司法厅“党建+巡察”深度融合  助推新时代巡察工作高质量发展 天天观天下

省司法厅“党建+巡察”深度融合 助推新时代巡察工作高质量发展 天天观天下

河北法制网讯 (记者 张世杰 通讯员 王群牛)为深入学习贯彻党的二十大关于“发挥政治巡视利剑作用...
05-24 20:09:03
《漂亮的战斗》发布主题曲MV “漂亮团”自信登场释放女性魅力

《漂亮的战斗》发布主题曲MV “漂亮团”自信登场释放女性魅力

“只要出手就是超漂亮,爆发我们就是超漂亮”5月23日,由爱奇艺出品、绮炫冠名的聚焦新女性力量的全女阵...
05-24 19:24:41
腾讯副总裁林松涛任虎牙董事长,押注“内容分发+应用分发”赛道

腾讯副总裁林松涛任虎牙董事长,押注“内容分发+应用分发”赛道

腾讯副总裁林松涛任虎牙董事长,押注“内容分发+应用分发”赛道,腾讯,林松涛,黄凌冬,应用宝,事业群,内容...
05-24 19:06:21
“恋爱洋湖计划”龙湖天街站圆满落幕 超级喜欢APP引领交友新潮流

“恋爱洋湖计划”龙湖天街站圆满落幕 超级喜欢APP引领交友新潮流

“恋爱洋湖计划”龙湖天街站圆满落幕超级喜欢APP引领交友新潮流
05-24 18:23:43
2023徐州市妇幼保健院幼儿园入园体检腰带什么材料?_速看

2023徐州市妇幼保健院幼儿园入园体检腰带什么材料?_速看

携带材料:请家长携带《江苏省母子健康手册》(医护版—儿册)及儿童医保卡和就诊卡,按照预约日期当天时...
05-24 16:37:23
全球通讯!心虚像个贼雨从未放过了谁闹够了没是什么歌

全球通讯!心虚像个贼雨从未放过了谁闹够了没是什么歌

随着抖音的火爆,里面的歌曲也一批一批的火起来,大家经常会听到歌曲的高潮部分,但是不清楚歌名,那么心虚
05-24 16:17:29
苹果宣布与博通达成一项为期多年价值数十亿美元新协议 每日焦点

苹果宣布与博通达成一项为期多年价值数十亿美元新协议 每日焦点

【TechWeb】5月24日消息,据外媒报道,当地时间周二,苹果宣布与博通达成一项为期多年、价值数十亿美元的新
05-24 15:50:45
世界即时:CIID中室学常德室内建筑师中心挂牌成立

世界即时:CIID中室学常德室内建筑师中心挂牌成立

汇聚设计力量,共建家乡常德!5月21日下午,2023年“CIID中室学常德室内建筑师中心授牌仪式暨“金十佳”...
05-24 15:10:19
快资讯丨黑龙江省第十五届运动会滑板项目收官 全运冠军韩晓刚轻松包揽两金

快资讯丨黑龙江省第十五届运动会滑板项目收官 全运冠军韩晓刚轻松包揽两金

黑龙江省第十五届运动会滑板项目收官全运冠军韩晓刚轻松包揽两金,韩晓刚,奥运会,全运会,2020年东京奥运会,滑板
05-24 14:03:23
基金早班车|市场观望情绪明显升温 林园:看好新能源汽车下乡政策对车企发展的助推利好

基金早班车|市场观望情绪明显升温 林园:看好新能源汽车下乡政策对车企发展的助推利好

一、交易提示1 A股缩量下挫,市场成交额不足7700亿元,创逾两个月新低。盘面上,中字头、大金融领跌,人工
05-24 13:20:20
翡翠原石长在哪里 原石价格一般是多少具体情况详细内容介绍

翡翠原石长在哪里 原石价格一般是多少具体情况详细内容介绍

想必大家现在对于翡翠原石长在哪里原石价格一般是多少方面的消息都是比较想了解的吧,那么针对于翡翠原石长
05-24 12:34:12
瑞可达(688800):加速国际化战略布局 海外订单逐步落地助力业绩持续提升

瑞可达(688800):加速国际化战略布局 海外订单逐步落地助力业绩持续提升

瑞可达(688800):加速国际化战略布局海外订单逐步落地助力业绩持续提升
05-24 12:07:09
2023年“我是生态环境讲解员”陕西省选拔赛决赛举行-全球热门

2023年“我是生态环境讲解员”陕西省选拔赛决赛举行-全球热门

正值国家科技活动周之际,5月23日,由陕西省生态环境厅主办,陕西省环境保护宣传教育中心承办的2023年“我
05-24 11:12:32
环球热讯:国家统计局:生猪(外三元)价格较上期下降1.4%

环球热讯:国家统计局:生猪(外三元)价格较上期下降1.4%

e公司讯,国家统计局数据显示,2023年5月中旬与5月上旬相比,8种产品价格上涨,41种下降,1种持平。其中,
05-24 10:25:04
非极性分子是什么(什么是非极性分子?)

非极性分子是什么(什么是非极性分子?)

本文目录一览:1、什么是非极性分子?2、什么是极性非极性分子,怎么区别3、什么叫极性分子和非极性分子
05-24 09:36:35
多措并举稳就业 驻马店市城镇新增就业3.02万人|全球报资讯

多措并举稳就业 驻马店市城镇新增就业3.02万人|全球报资讯

截至4月底,全市城镇新增就业3 市人社部门组织各县区在“驻马店公共就业服务网”“驻马店人才信息网”...
05-24 08:58:02
妊娠分娩新生儿全书_妊娠分娩育儿百科全书

妊娠分娩新生儿全书_妊娠分娩育儿百科全书

1、《妊娠分娩育儿百科全书》是一本科学孕育类的实用宝典。2、从妊娠、分娩到育儿,是一个科学、系统、复杂
05-24 07:58:26
布基纳法索军队消灭超100名恐怖分子 全球热消息

布基纳法索军队消灭超100名恐怖分子 全球热消息

当地时间5月23日,布基纳法索空军在该国中东部的比图地区的萨文加森林中,通过空中打击消灭了超过100名恐怖
05-24 07:08:24
当前信息:“智慧海关”赋能外贸高质量发展

当前信息:“智慧海关”赋能外贸高质量发展

关悦 科技日报记者 陈瑜5月23日,在华南地区最大的综合性枢纽海港广州南沙港,一艘艘国际货轮正有序靠
05-24 06:20:58
美女掐死勒死捂死优酷视频下载_美女掐死勒死捂死优酷 动态

美女掐死勒死捂死优酷视频下载_美女掐死勒死捂死优酷 动态

1、绝对经典的《香水》里面有各种美女的死法。2、但是不是恐怖片。3、应该是文艺片。本文就为大家分享到这
05-24 04:35:45
麻阳农商银行金融活水浇灌高标准农田建设 焦点热门

麻阳农商银行金融活水浇灌高标准农田建设 焦点热门

麻阳农商银行金融活水浇灌高标准农田建设,良田,农田建设,高标准农田,麻阳农商银行
05-24 03:10:22
桃子品种介绍及图片 桃子品种 全球信息

桃子品种介绍及图片 桃子品种 全球信息

今天来聊聊关于桃子品种介绍及图片,桃子品种的文章,现在就为大家来简单介绍下桃子品种介绍及图片,桃子品
05-24 01:17:24
必应中国市场份额超百度是乌龙?研究机构回应:统计存在异常 正调查|全球通讯

必应中国市场份额超百度是乌龙?研究机构回应:统计存在异常 正调查|全球通讯

美国数据研究机构的统计数据称,2023年4月,百度桌面搜索中国市场份额被微软必应Bing超越,引发网络热议。
05-24 00:51:26
里昂网球公开赛张之臻止步首轮 当前速递

里昂网球公开赛张之臻止步首轮 当前速递

新华社法国里昂5月22日电在22日的男子职业网球选手协会(ATP)里昂网球公开赛上,中国选手张之臻在正赛首轮以
05-23 23:42:55
红魔8Pro销售火爆,618首降300!

红魔8Pro销售火爆,618首降300!

今天上午,红魔618活动正式发布,将于5月23日20点开启抢购。根据红魔游戏手机官方微博发布的消息了解,此次
05-23 23:09:51

为您推荐

精彩推送