反应式编程与土豆炖肉

发布于: 2020 年 06 月 21 日
反应式编程与土豆炖肉

1:分析方法

内容涉及主要概念

函数编程,回调,异步编程,非阻塞流,事件驱动,消息驱动,反应式编程

参照现实生活理解

程序解决问题过程就是完成某个任务,也可类比按现实世界人类完成某个任务过程。

程序处理过程核心概念:数据,线程,函数,三者的配合分解串联

人完成某个任务:物,人,活(处理方法)

对应关系为:物-数据,人-线程,活-函数

解决问题方法

解决复杂问题(大任务)就是把问题分解为若干小问题(小任务),调配执行者(线程,人)去配合完成。问题越复杂,任务的拆分,组合,人力调配过程就越重要,直接决定任务能否正确完成及完成的效率高低。

这个过程对应到程序就是程序的子任务拆分与协助方法。

解决问题(任务)的复杂性演化推动程序设计方法的演化,对应出现解决某类特性问题相适应的设计方法。

 

就以在家媳妇安排自己做一顿饭为任务,来分析场景演化与对应方法。

2:子任务拆分协调的编程模型

1:顺序调用

生活场景

第一次安排做土豆炖肉--逐步安排

1》给你葱去切丝

2》给你土豆去切块

3》给你肉去切块

4》把放葱,土豆,肉 入锅 炖

特点:一步步的安排--单人按顺序逐步执行

物:土豆,葱,肉

执行人:自己

活(任务)拆分:切土豆,切葱,切肉,炖(材料放入,加火炖)。

编程模型

面向过程执行。

程序处理简单任务的过程一般比较符合,把处理过程拆分为几个函数,逐步将数据给函数处理。

 

2:流水线模式

生活场景

给你任务单,你按顺序做。

1>任务拆分到任务单:切葱,切土豆,切肉,炖肉

2>给你任务单,材料去按照这个顺序做土豆炖肉

好处:把物与任务单一次给你,中间步骤不用操心。

编程模型

java的流处理模型,函数链(比如Netty的Pipeline模型的责任链模式)

netty的pipleline 用相同类型的工序组织。

java流本质就是函数链,抽象出几种类型工种,可方便组装流水线。某个类型工种的具体做法可定义。

区别点:java的流是拉的,只有最后收集点才会触动流水线开工,java流的并发模式支持中间某个工序用多个人。

用途

1>对符合流水线工序要求的基础上灵活拼接多个,方便将一个大任务分解为一系列按步骤处理的子任务。

Netty 的Pipleline 添加handler 就是典型例子,可以将编码,心跳检查,加解密,安全认证等组装起来,而每一个工段只关注自己的一件事。

把土豆变成炒菜的土豆块:洗,削皮,切块,每一道任务都很专一,上一道任务结果给下一道处理。

将来需要切丝,只把最后一道工作替换,需要把土豆有芽的扔掉,就再最前面加一道挑拣工序。

需要将不规则土豆在削皮前切成规则大块,就在削皮前加一道工序。可以不断精细优化。

2>部分工作重用,重用总体工序(一种步骤限制),重用其中某个工段。

总体工序

如:定义切土豆的流水模式:洗,削皮,切。 

工序是通用固定的,但其中某些工段可个性设置。比如根据喜好可以更换洗,削,切的个性手法

一般在框架上定义好工序,具体工段应用个性注入。

重用工段

切块机,什么固态东西放入都给切成要求的块。那肉,土豆都可以用。

关键点:定义流水线,按顺序执行,个性配置流水线中的工段

 

3:函数编程

生活场景

给你一个炒土豆炖肉机

炒菜你不会炒(难吃),你就做切的活(粗活),给你炒菜机,切好用机器炒。炒菜机只要你把材料按要求放进去,按按钮就行了。

 

科技发达后续可能给你几个机器,切肉机,切土豆机,炒土豆炖肉机,你分别按顺序操作就行。

还可以更发达,炒菜机可以灵活组装,包括切土豆,切肉的机器接口

你把切肉机,切土豆机连上炒菜机,把土豆,肉放进去,摁按钮就出来土豆炖肉了

 

编程模型

函数编程,将函数像数据一样传入,方法内部直接调用传入的函数。具体函数实现不用了解。

函数也可用由其他函数组装(炒菜机有切肉机接口)

函数编程与回调区别

函数编程是可在执行中间用,也可传递若干函数,函数也可以由其他函数装配。

回调一般是最后调用-炒菜机,并且传递一个,更多用于执行完后触发另一个函数,回调是函数编程的简化版(不能组装,最后调)。

 

函数也可能是闭包(炒菜机里面内置辣椒酱),如何炒跟口味你都控制不了。

 

4:异步编程

生活场景

你先忙,干完叫我

还是炒菜,这次媳妇把任务跟材料都给你,让你做完通过某种方式告诉她。交代完就走了,在你做菜期间她可以做别的重要的事(刷碗,刷微博,刷抖音)。

编程模型

异步编程,

交给专业线程做。可以是线程池,可以用协程(go),或交给其他服务,交给系统。

分两种情况:关注结果--菜做完了要给她(还没吃),不关注结果(她吃过了)

不关注结果:直接丢给新线程做就完了。

关注结果:要求有做完后的通知机制。

如何确认任务完成呢:

1>轮询(多问问好了没),

2>等通知(做好了叫她-回调),

3>消息|事件队列(做好了放到固定位置-桌子上,她有空了去桌子上看(事件列表,消息列表)好没,好了就吃

4>阻塞等待,等线程执行完毕后在继续执行,没事或急需要执行结果时采用。(啥也不干就干等,虽然她不累但也没干别的事,饿了就会这么干,吃饭前啥也不做)。

 

Java--可用Callback 接口的Feature .GO 可用传递一个channel.也可以完成后用其他消息模式通知。这也是很多异步框架做的事(可用有专门线程监控消息,或轮询,完成后通知给关注者)。

JAVA NIO ,linux epoll模式相当于有一个线程监控多个连接的完成情况(专人轮询)。

 

5:MQ,任务队列

生活场景

发挥主人翁精神,主动要活,不累坏,也不偷懒

媳妇可能有很多任务安排,做饭,洗衣服,扫地等。都给你怕你累着(体贴人),就把需要的任务放到列表上,想起一个放一个,你就发挥主人翁精神,去逐个领取,完成一项,马上再去取下一个执行,没就等活。

即便你不在或忙别的,一会来了按着做就是,或孩子帮你完成也可以,媳妇不用等。

解耦了任务分配方与任务执行方。

不用等待任务执行完毕,也不用怕你累着,需要的时候可以针对性的扩容消费者

编程模型

MQ,任务队列

用消息队列做流量削峰,线程池去任务队列领任务都有这层意思,这要求任务间是相对独立的,没有严格的次序依赖(不需要上一个任务的结果),拉任务可以是本进程内(线程池任务队列),也可以使网络上(MQ)

同时也是一种架构模式:可减少系统间的依赖,但要求是上游不依赖下游的执行结果.

消费者临时故障,也不影响生产者。

6:消息驱动,事件驱动

生活场景

如果家里没家务活你不用一直干等吩咐,可以干别的事,媳妇有活告诉孩子,孩子告诉你

孩子自己有要求也告诉你。收到后处理。

媳妇说下午去公园玩,你收到后,去准备水,水果,牛奶,帐篷, 儿子收到后去准备渔网,滑板等

编程模型

消息驱动

典型UI事件处理模式。注册关注UI事件的处理函数(可关注多种事件),没有事件时线程是休息的,有的时候才唤起执行。

可有一个线程去专门负责事件列表,消息列表,发现有就启动任务(可用它线程)执行。一个处理者接受多种个生产者指令。

事件驱动

一个事件可有多个事件监听者,生产者发布自己的事件,有多种消费者关注,在收到后分别去做不同的事。

实现了业务解耦。将来可有扩展很多下层的业务种类(前段业务不关注后端业务)。

解耦了任务分配方与任务执行方,一个事件(消息)可能有多个人都关注,都领取并进行不同的处理

7: 反应式编程

生活场景

分工协作效率高

孩子们都能帮忙了,媳妇把任务分配好,切葱,切土豆,切肉,摘青菜,洗菜,孩子们去抢着做,爸爸负责炖,炒。

切葱土豆肉,洗菜,摘菜是孩子们并行做的,炖肉,炒菜你要等他们有材料齐备的就去做,做完看是否还有齐备的,有就继续做下一道菜。

编程模型

反应式编程,这是前面方法的综合运用。

反应式编程解决的问题

场景:

1>任务拆分为有些可并行,有些需要依赖的子任务。可并行的用多个线程并行执行,缩短任务总体耗时。(异步编程)

2>依赖其他结果的子任务怎么确认可以执行,不要去等待前面的所有线程,而是看自己的消息列表(任务列表)有就去处理。不用一个线程专门等待前面某个任务可以执行,而是多种任务都放到任务列表,去列表中取,或专门负值守线程发现任务后生成任务交给线程池(任务队列,消息驱动,事件驱动-),可减少任务线程的等待,同时也可避免瞬间压力过大开启很多任务线程。

反应式编程的核心:异步编程+非阻塞消息流。

任务要拆分为多个并行--异步编程

拆分提高任务线程的执行效率,就要不阻塞等待

不要进行IO耗时的等待-异步IO

任务间完成通知-异步消息

最后结果:提高执行效率,缩短耗时,并防止系统被压垮。

1>对单个任务由于部分子任务并行执行,提高了响应(耗时短),

2>总体上很多类似的任务,每个任务都拆分到任务列表,子任务间交接用消息队列(相当于转化为任务列表),所有子任务最终都由线程池去任务列表去取,会减少等待的线程数,由于是任务列表,程序也不会压垮。

缺点:

一个请求切换了多次线程,调试不方便

如果cpu压力不大,并行部分执行后,用feature 或channel就好。

 

8: 分布式系统下的应用

同一个进程内函数调用,通知等待,任务列表等语言本身都包括了,而在分布式下

1>程序内的调用,改用系统间的调用

2>任务可以由多个线程执行变为可以由多个节点执行

3>本地的任务队列,事件列表改用网络上的消息队列

上述如果要配合好,推荐用框架统一实现,减少编码的复杂度

参考

https://www.cnblogs.com/lguow/p/10750296.html

https://www.cnblogs.com/feiquan/p/11286993.html

https://studygolang.com/articles/20278

https://www.jianshu.com/p/c95e29854cb1

发布于: 2020 年 06 月 21 日 阅读数: 50
用户头像

superman

关注

还未添加个人签名 2018.07.20 加入

还未添加个人简介

评论

发布
暂无评论
反应式编程与土豆炖肉