什么是事件驱动架构

Event-driven architecture (EDA) is a software architecture paradigm promoting the production, detection, consumption of, and reaction to events. - Wikipedia 什么是事件驱动架构? 按 维基百科的定义,事件驱动架构(EDA)是一种软件架构范式,促进事件的产生、观测、消费和反应。 在认识事件驱动架构之前,先来明确一下,什么是事件。 事件是已经发生的事实,并且不可变。例如,“创建订单”是个指令,而“订单已创建”就是个事件,订单的信息、订单创建的时间,在这个事件发生后就无法被修改。 在传统的架构体系下,编程思维可以说是过程驱动的,一个指令触发了一段逻辑,这其中可能包含了几个不同的方法行为,它们之间按照过程顺序来编排、嵌套。看起来似乎很清晰,但是很容易写出长长的“面条”代码。而事件驱动架构则强调了事件的产生与消费,将逻辑的过程转换为事件之间的环环相扣。 就如上图所展示的,如果采用事件驱动架构,订单服务就只负责订单的创建,然后发出“订单已创建”的事件,交由 EventBus 路由,转发给关心这个事件的各个监听者。 在我的开发经历中,也有采用事件驱动架构的项目,接下来,就结合自身经验,总结一下 EDA 的优缺点和其适用场景。 EDA 的优点 解耦 首先,解耦是事件驱动架构所带来的最明显的优点。从上述的例子中就可以看出,采用了 EDA 后,订单服务只需要负责处理对应的业务逻辑,而其他的切面逻辑,例如操作记录、发短信等,都可以通过事件的通知机制来解耦,从而保证业务逻辑的简洁、专注。并且,这些切面功能点可以考虑使用异步处理,也能很好地提升系统的响应能力。 DDD 与事件风暴 在领域驱动设计(DDD)中,如果采用 以“领域事件”为核心的建模思路,与业务人员通过事件风暴的形式来梳理业务流程,就会得到一系列的事件列表,也就是事件驱动架构中的所有事件。从业务人员到开发人员,从真实业务逻辑到系统设计实现,都以这些事件为核心,就能够形成统一语言,方便沟通和理解。 事件溯源 事件上存储了必要的信息和时间,如果将所有的事件持久化,结合最初的实体信息,你就拥有了一台来去自如的时光机。例如在一个资产管理系统中,存储了“资产已入池”、“资产归属已变更”、“资产已出池”等所有的事件,并且存储了资产初始化时的快照数据,就可以根据快照数据和给定时间范围内的事件列表,重新计算出某个时间的资产数据,这就是事件溯源。如果整个生命周期中事件量很大,可以考虑定期给实体做快照,溯源时获取最近的一份快照数据。事件溯源能给业务提供更灵活的数据支撑,同时,因为存储了所有的事件数据,也保障了系统的故障恢复能力和数据一致性。 EDA 的缺点 系统复杂度 “在软件工程中,没有一个中间层解决不了的问题”,事件驱动架构,就是通过引入中间层 EventBus 来实现事件机制,看似能带来不少诱人的优点,也必然会增加系统的复杂度。Spring 虽然有提供事件机制,但是比较简单,如果有复杂的使用场景,得考虑自己实现。 事件驱动架构改变了编程思维,一切都围绕事件的发布和订阅,将完整的功能过程,拆解为了不同的事件,也丧失了过程驱动带来的叙事能力。如果事件数量众多,就容易在“事件丛林”中迷了路。 使用场景 软件工程没有银弹,事件驱动架构也有其适用的场景,结合上述优缺点,个人认为,以下几个方向可以考虑采用 EDA: 组件解耦(消息推送、操作记录等) 数据沉淀系统(审计、资产等) 常规的业务逻辑里,如果有一些切面组件,例如消息、操作记录,可以接入轻量的 EDA 来解耦,保证业务逻辑清晰和职责的单一;而在数据沉淀系统中,例如审计、资产等领域,通常没有特别复杂、长链路的业务逻辑,由业务系统来触发更新数据,更关注的是数据的准确性、一致性,就可以考虑使用 EDA 和事件溯源机制。...

July 11, 2021

过期影像 | 20210704

“秋刀鱼会过期,肉酱会过期,连保鲜纸都会过期” 相册里的影像,放久了也是会过期的。 着急回家吃车厘子差点错过不过期的粉雾海 @涵涵 @过期头发 春天在屋里 @lilpilot 岛雨 @lilpilot 喝好咖啡 @lilpilot @lilpilot @lilpilot @lilpilot @lilpilot 一只假鸟 @lilpilot 一只真鸟 @lilpilot Summer Remains @lilpilot...

July 4, 2021

不能想象没有书的世界 | 《日常生活中的自我呈现》

这本书是关于社会生活的研究报告,从生活记录、生活经验中抽取认知框架,来分析英美社会活动中的底层逻辑。 “人”这个词,最初的含义是一种面具。 无论在何处,每个人会或多或少地意识到自己在扮演一种角色。书中就是使用了舞台剧的模型,来讨论个体在日常生活中,如何向他人呈现自我,引导和控制他人对自己的印象,以及在他人面前维持表演时可能会做、不会做的各种事情。 舞台剧这个解释模型还是挺贴切的。表演者的目的是维持特定的情境定义,所以会有舞台设置;多个表演者会形成一个剧班,在前台给观众呈现表演,又在后台有不一样的行为,例如一些“秘密”的交流;除了台下的观众,还有各种角色,例如告密者、托儿、局外人;表演可能很精彩,也有可能会崩溃,所以会有很多的行为策略。 书中有大量的引用记载和举例来支撑这个模型,例如波伏娃是这样描述女性在前后台活动的区别:女人在男人面前总是演戏,她会假装乐意接受那种无足轻重的地位,装腔作势……然而,女人与其他女人在一起时,她就像是在幕后;她擦拭装备,但并不是要投入战斗……对有些女人来说,她们之间那种温暖亲密的关系要比和男人在一起时那种严肃的虚饰可爱多了。 生活中的例子也数不胜数。不同阶级之间的阿谀奉承,职场里的尔虞我诈。出色的表演能竖立好的角色形象,演的不好会遭人耻笑,如果表里不一就容易翻车,这样的场景,微博吃瓜网友表示再熟悉不过了。 当然,因为是社会学的底层逻辑,在日常生活中或多或少都有接触和感悟,所以通过这本书很难学习到什么实用的技能,倒不如挑几个有趣的点,结合书中的模型来解释、思考一番。 首先是关于角色扮演。如果我想在行业里变得很优秀、厉害,那是不是只需要观察、模仿那些优秀的人,并且表演出与他们一致的行为,就意味着自己是这样的人了?对于这个问题,需要区分一下人和角色,人扮演的产物是角色。通过观察、模仿、学习和进步,我们可以很好的扮演一些角色,而正是在这些角色中,我们互相了解,并认识自我,在人性化的自我(人)和社会化的自我(角色)之间来回摇摆,并找到平衡。值得注意的是,在到达了一个梦寐以求的位置,成为一个新的角色后,往往会发现,新老处境会有始料未及的相似之处,因为这又是一场表演,有着光鲜亮丽的前台,以及肮脏、琐碎的后台。 然后是关于表达和行为的冲突。就像萨特说的,“一个试图显得很专心听讲的学生,两眼紧盯着老师,竖起耳朵,结果却什么也没听见”。为了解决这种困境,一些组织就会把功能委托给专家,专家只负责对工作进行戏剧化的表达,而不是真正参与工作。这让我想到了一个观点,如果要用一句话来概括创作者经济,就是 B 级玩家(内容创作者)给 C 级玩家(普通听众和新手)讲述 A 级玩家(顶级创作者和艺术家)的成功之道。在互联网上,神奇的算法决定了我们最容易接触到的内容都是来自于 B 级玩家,而需要警惕的是,真正有价值的内容是来自于 A 级玩家。所以,在浏览内容的时候,要尽可能地通过 B 级玩家的筛选管道,来靠近 A 级玩家那些有价值的思想和内容,而不是仅仅沉溺于 B 级玩家的内容创作之中。 最后是关于欣赏表演。如果是欣赏一场表演,最合适的角色自然是观众,能直接地接收表演者所要传递的内容。而除了观众之外,还有一种角色,局外人。我自己一个人去 livehouse 或者 bar 的时候,有时候就会扮演局外人。游离在演出的边缘,去观察表演者、观众的行为,去感受整个表演的氛围和情境。偶尔会因为自己这样子的“闯入”,遇到一些很有趣的人和事,例如不知道怎么点酒的人,第一次看 live 的人,当然,随后产生的一些互动,会让游离的局外人也加入了整场表演,成为了有趣的一部分。 呐,暂时只想到了这些。 人作为社会化的动物,喜欢也好,排斥也罢,是逃离不了表演这种社会行为的。所以,手捧《演员的自我修养》,练习,并做好每一场演出,在一个又一个角色之中,找自己。 最后再吐槽一句,翻译是很难做好的事,而这本书的翻译,显然不咋地。...

June 30, 2021

不能想象没有书的世界 | 《羊呆住了》

翻看完这本意义不明的书,我也呆住了。 说它意义不明,如果不是逼自己写读后感,这一本的读书笔记就会像《守门员面对罚点球时的焦虑》那样,一片空白。 书腰上赫然印刻着“坚持业余写作”,而在序章里,谈论了知识、日常事物、对词语过敏的自我诊断、在当代艺术和非虚构之中,寻找可能性。这一章的标题是,“业余作者如何摸索出路”。 余下的就是短篇集,短短的三两页,厚厚的一本书。如果把书整个翻过来,在封皮的简介里是这样描述的,“多从日常事物汲取灵感,却以一种高度自由的、超现实的手法加以表现…作者以其强大的想象力与精简、清奇的语言风格,向我们展现了当代中文写作的又一新的可能”。 妙啊。 于是翻开来细品。 但是,我不知道该如何去描述这种阅读体验。 就像书里的 1812 一样,不好描述,没法展开思路,只能指着说,那就是 1812。 读着读着,有那么一瞬间,我想起了缺省的那首《将死之时掩以水门汀》,下一首或许是《杀死那个石家庄人》,海浪拍打着爱死机里搁浅的巨人,天上飘着死亡搁浅里的人形物体。 “土就是碎了又碎的星”,我最喜欢这一句。 《风格练习》里也没有收录过这样的文字风格,不合逻辑,蔓延而肆意生长的想象力,但是冥冥之中又有一条细细的线,把这些故事牵连了起来。我又想到了 Glitch Art,故障艺术,但一点都不锋利,因为被软绵的中文所包裹。 可惜的是,看多了就觉得有点神神叨叨了,有点疲惫。 那就聊聊羊吧,第 67 章,羊呆住了。“草从哪里来?羊吃着吃着就呆住了,无法解释,它想不通”,我不知道你是否有见过羊呆住的画面,我见过,微博上。一场雨后,一群羊静止了,一动也不动。“草从哪里来”,羊会这样想吗,这个问题有没有答案?如果有,那么鱼儿为什么不能活在天上。如果没有,那这个问题的意义是什么。 再回过头来聊聊意义。得先讲个小故事,2016 年,美国的 CAH 公司想在一座岛上挖个洞,他们在网上筹钱,然后找建筑公司挖洞。没有计划挖多深,只要有钱,就不停地挖,一刻也不停,并且在网上直播。有人问"Is this real ?",他们的回答是"Unfortunately it is"。于是他们募集到了 10 多万美元,这个洞一共挖了 52 个小时。最后,他们把这个洞填上了,就像什么都没发生过一样。 妙啊。 我不想为此过多地解读什么,这也是 1812。只是抬头揉揉眼,墙壁,书桌,书本,我的手臂,脸颊,眼睛。所看之处,光滑或是曲折的表面之下,这样的洞无处不在。黑狗也是,书中的苏老师,跳狗自杀了。“他爬到一棵喜欢的树上,等一条黑狗跑过的时候,又稳又准地跳了进去”。 如果羊目睹了这一切,会又一次呆住吧。...

June 24, 2021

一招让 Spring 本地测试弹射起步

开发过程中,在本地启动系统来进行一些测试、联调是很日常的操作。然而随着项目不断壮大,系统内会依赖越来越多的中间件或服务,例如 Rocket MQ、Dubbo、定时任务等。在系统启动的时候,需要对这些组件进行初始化,导致启动过程缓慢无比。 系统启动 5 分钟,测试运行 3 秒钟,这谁顶得住啊。而且在本地测试时,通常也用不到这些组件。 如果你也有同样的困扰,接下来就教你一招,利用 Spring 的扩展点 BeanFactoryPostProcessor,无侵入地“阉割”这些拖慢启动时间的组件,让你的系统一键弹射起步。 我们就以 Rocket MQ 为例,在启动的时候加载 5 个消费者。 public class RocketMQConfiguration { /** * SpringBoot 启动时加载所有消费者 */ @PostConstruct public void initConsumer() { Map<String, AbstractRocketConsumer> consumers = applicationContext.getBeansOfType(AbstractRocketConsumer.class); if (CollectionUtils.isEmpty(consumers)) { log.info("no consumers"); } for (String beanName : consumers.keySet()) { AbstractRocketConsumer consumer = consumers.get(beanName); consumer.init(); createConsumer(consumer); log.info("init consumer: title {} , topics {} , tags {}", consumer.consumerTitle, consumer.topics, consumer.tags); } } } 运行一下测试类,系统启动耗时 30 秒,其中 Bean 的初始化过程就占了 28 秒。...

June 22, 2021

不能想象没有书的世界 | Show Your Work

It’s about half a year since I started learning English seriously. And recently I started reading English books. As I’ve written before, you can’t tell others you’re good at English if you rarely speak or write. So I’m trying to write a reading note in English. Show Your Work is a great book, it writes about how to promote yourself, and the key is process, not product, all you have to do is show your work....

May 29, 2021

过期影像 | 20210523

“秋刀鱼会过期,肉酱会过期,连保鲜纸都会过期” 相册里的影像,放久了也是会过期的。 #bilibili { width: 100%; height: 550px; } @media only screen and (min-device-width: 320px) and (max-device-width: 480px) { #bilibili { width: 100%; height: 250px; } } 🌏 亲密宝贝俱乐部(上海市黄浦区淡水路226号) 🎵 恍惚 - 蛋堡 & JABBERLOOP...

May 23, 2021

不能想象没有书的世界 | 《穆里尼奥传》

穆里尼奥,魔力鸟,狂人,鸟叔,不论如何称呼,他总是最特别的一个,也是我最喜爱的足坛主教练。 十年前刚开始看球的时候,那时候的皇马还被大家戏称为十六郎,连续六年倒在欧冠十六强的比赛中,见谁输谁。 2010 年 5 月,穆里尼奥入主伯纳乌,带领着银河战舰重新起航。在任的三年内,连续三年进入欧冠半决赛,在西甲联赛中,多次掀翻如日中天的宇宙队巴萨,更是以创纪录的 100 分夺得西甲冠军。 在 11-12 赛季的欧冠,面对拜仁,比赛拖入点球大战,鸟叔跪坐在球场边,我也跪坐在电视机前,然而 C 罗、卡卡、拉莫斯接连罚丢点球,穆氏皇马没能捧起大耳朵杯,这可能是穆里尼奥职业生涯最大的遗憾,也是我球迷生涯里最大的遗憾。 不过在这三年中,穆里尼奥的足球哲学、战术体系已经深深烙印在了整支球队,防守反击的快打旋风令整个欧洲足坛都闻风丧胆,为之后的五年四冠打下了坚实的基础。时至今日,我自己最爱的阵型和打法,也还是 4-2-3-1 体系下的防守反击。 这本书讲述的是穆里尼奥在教练生涯早期的故事,第一次当上主教练,随后在波尔图夺得多个冠军。虽然那个时期我还是个毛头小子,里面的事迹也都发生在我看球之前,但是跟着书,回顾鸟叔一路走来的心旅历程,从这些经历的成功和失败中,也能学到很多。 在《数字游戏:关于足球》一书中,有个有意思的结论,足球比赛里的运筹帷幄、技战术能力自然能影响胜负,但是运气始终占令一半。但是看完这本传记,我更坚信,专业的能力和对比赛的投入才是关键。 穆里尼奥的球员生涯短暂而黯淡无光,随后做过默默无名的小翻译,在几支球队间辗转并担任助理教练,但是他并没有选择躺平。穆里尼奥对自己的未来有着清晰而长远的规划,他在罗布森手下学习组织防守,在范加尔手下学习指导球员训练,在巴萨学习和顶级球员相处和处理人际关系,并逐渐发展和形成了自己带训练课的哲学。 “不是我不明白,这世界变化快,所以我逐渐养成了随时随地记笔记的习惯”,看球的时候总能注意到,穆里尼奥会在场边掏出自己的笔记本,匆匆记录着什么,而这些笔记就是他的“执教圣经”,记录了自入行以来所有的笔记、思考和总结。而且他永远在对自己的战术思想、训练方法以及比赛理念做系统地分析和研究,并且不断演进它们。 不喜欢穆里尼奥的人会说他傲慢,总是在记者发布会上口出狂言。 然而事实上,比赛并不是在主裁判吹哨时才开始打响,而是早在每一堂训练课,赛前的每一分每一秒。在新闻发布会上说一些带有攻击性的话,才能把媒体的枪口从球员身上转移,而球员要做的,就是专注于比赛。 当然,除了工作,穆里尼奥最重视的就是家人,工作之余,就是陪伴妻子和两个孩子。在夺得一次又一次地冠军时,穆里尼奥明白,这些成功并不专属于他自己,还属于他的家人,他们总是在背后默默支持,书中也有不少温馨的家庭互动。 “教练,我们做到了”,而当大家都沉浸在胜利的喜悦中,主教练已经在冷静地思考下一步,“我不能让球员们被这些荣誉冲昏头脑。我会要求他们更加进取、更加谦卑。只有这样,我们才能继续取得胜利。” 坚毅,专注,勤奋,天生的领袖,“上帝之后,就是我”,穆里尼奥就是这样魅力又杰出。 这个夏天,穆里尼奥将挂帅罗马,征战意甲。祝一切顺利,Boss。...

May 22, 2021

过期影像 | 20210517

“秋刀鱼会过期,肉酱会过期,连保鲜纸都会过期” 相册里的影像,放久了也是会过期的。 之前在《路上观察学》的笔记里,邀请大家一起“办个展”,有几位朋友寄来了美妙瞬间,就在这里一起分享,谢谢你们~ @Lenore 美丽花花 @豆豆子 退潮 @自核 亲子时间 @zelos 也想要翘jio晒太阳🐻 @玥玥 @过期头发 @过期头发 @lilpilot @lilpilot @lilpilot @lilpilot @lilpilot @lilpilot @lilpilot @lilpilot...

May 17, 2021

如何在一个月内,从旱鸭子变成游泳高手

“我想去游泳了”,老鲁握着方向盘,忽然对我说。 我笑了笑,“拉倒吧,两年前你也是这么讲的”。 本以为又是一个说了就忘的 flag,没想到这回他认真了。这次的缘由并不是因为兴起,而是在一周前,我的朋友老鲁,发烧大病一场,意识到身体在敲打警钟,因此想做点改变。 老鲁是一只旱鸭子,但是这个称号马上就不复存在了。短短的一个月,从旱鸭子,变成了游泳高手。 进步之快,真是令老师傅刮目相看。 期间有帮他做一些指点,也目睹了整个学习进步的过程,是个教科书式的“正向循环”,于是想总结一下其中的经验和过程。 如果你想快速学习一些技能,或是在基础上精进,这套方法论或许能给你带来帮助。 什么是“正向循环”呢?就是将整个学习的过程,拆分为各个小循环,在每一个循环中,先定一个小目标,做点尝试,然后检查自己的不足,找到改进点,进而制定下一个小目标。 即 目标 -> 尝试 -> 检查 -> 改进,往复地正向循环,快速学习和进步。 而其中的每一步,该怎么做? 先定一个小目标 第一步,就是给自己定下一个小目标。 什么才是目标?是自己从未做到的程度。怎样才算小?小到当下就可以触碰到门槛(一个亿当然不算!)。 如果自己从没在泳池里游过泳,那你的小目标一定不能是“学会蛙泳”,而应该是“在泳池里扑腾几下”。 例如老鲁在学游泳的过程中,制定的几个小目标分别是:下水感受一下,游满一小时,用蛙泳游完一公里,用自由泳在 30 分钟内游完一公里。 一旦完成了这个小目标,那下一个就会带来新的挑战,也就意味着你进步了! 尽快尝试 有了目标后,下一步就是尝试了。 尝试自然是要亲历亲为,但是俗话说的好,“师傅领进门”。学习一个新技能的时候,老师傅的指点会有很大的帮助。如果身边没有老师傅也不用担心,互联网上有太多优质的老师和教学。 我和老鲁都在 b 站 up 主 梦觉教游泳 的视频中学到了很多,在下水前,看视频预习一下,然后就可以在泳池里自己体会。 在尝试这一步,先挑简单的去完成。如果自己怕水,就在浅水池里泡泡澡,感受水的浮力;如果不会蛙泳,就先找块浮板,照着视频里的拆解动作,分步骤练习;学会蛙泳后,可以在深水池里尝试踩水漂浮,克服一下对于深水的恐惧;最后就能在深水区练习长距离的游泳了。 检查反思 “吾日三省吾身”,检查自己,才能明白先前的尝试还有哪方面的不足,然后反思,并做出改进。 学游泳的时候,很常见的问题是,“动作我都练了,但是有点别扭”,又或者是“明明很用力了,为什么还是游不快呢”。遇到这种情况,往往是因为动作不连贯、不标准。 那么要如何解决呢?首先要检查一下自己的动作,看看问题到底出在哪。 身边有小伙伴的话,找他观察点评一下。如果没有小伙伴,又或者连他也看不出个所以然,可以录个视频,然后和教程视频做对比,就能很明显地看出自己的不足了。 我和老鲁用 go pro,从不同角度,拍了几段游泳的画面,一下子就明白了,自己的动作是哪里做的不好。 做出改进 知道不足之处后,就可以想办法做出改进了,调整一下自己的动作,重复多次练习,并且完成之前制定的小目标。 成功后,接着制定下一个小目标吧。至此,一个“正向循环”就形成了。 完成一个又一个的小循环,每次都有进步,耗时短,有成就感,也形成了继续前进的动力。 上图就是老鲁在学游泳时,采用“正向循环”的全过程。 仅仅一个月,就从完全不会游泳的旱鸭子,成长为了游泳高手。当然,其中少不了日复一日的坚持。 学习技能的时候,尝试一下这套“正向循环”,你可以做得更好。轻点油门,感受自己的澎湃能量吧!...

May 15, 2021