spring-integration二探
学海无涯,旅“途”漫漫,“途”中小记,如有错误,敬请指出,在此拜谢!
前言
本次探的呢,是公司项目中使用到的一种组合方式。
内容
先上未改之前的代码
<int:gateway service-interface="com.lin.integration.service.interfaces.IEventSender" id="publishEvent" default-request-channel="publishEventChannel"/>
<int:publish-subscribe-channel id="publishEventChannel"/>
<!--更新缓存的触发点-->
<int:service-activator input-channel="publishEventChannel" ref="cacheEventPublisher" method="publish"/>
<!--写审计的触发点-->
<int:service-activator input-channel="publishEventChannel" ref="eventHandler4Audit" method="handle"/>
<!--对客户端发送消息的触发点-->
<int:service-activator input-channel="publishEventChannel" ref="clientEventPublisher" method="publish"/>
<!--对外发送消息的的bridge-->
<int:bridge input-channel="publishEventChannel" output-channel="publishEsbEventChannel"/>
<!--对内发送消息的bridge-->
<int:bridge input-channel="publishEventChannel" output-channel="publishInnerEventChannel"/>
<int:channel id="publishEsbEventChannel">
<int:queue/>
</int:channel>
<int:outbound-channel-adapter channel="publishEsbEventChannel" ref="esbEventPublisher" method="publish">
<int:poller fixed-delay="1000" />
</int:outbound-channel-adapter>
<int:channel id="publishInnerEventChannel">
<int:queue/>
</int:channel>
<int:outbound-channel-adapter channel="publishInnerEventChannel" ref="innerEventPublisher" method="publish">
<int:poller fixed-delay="2000" />
</int:outbound-channel-adapter>
解释一下,这里面的业务逻辑为:
(1)先更新缓存
(2)向数据库中写入日志审计等
(3)向客户端发送刷新申请
(4)对外部系统发送消息,对内部的其他微服务发送消息
而突然感觉不满足业务逻辑,需要将(4)中的外部和内部消息排列先后顺序,且还要满足和前三个不属于同一个线程。(有趣的需求)
所以便将配置方式做了个demo,进行分析,输出的结果为:
***********************注意哈,我发了哈
2021-07-20 13:51:28.863 INFO 18948 --- [nio-8091-exec-2] c.l.i.test.CacheEventPublisher : CacheEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 13:51:28.864 INFO 18948 --- [nio-8091-exec-2] c.l.integration.test.EventHandler4Audit : EventHandler4Audit 收到:{a=a, b=b, c=c}
2021-07-20 13:51:28.865 INFO 18948 --- [nio-8091-exec-2] c.l.i.test.ClientEventPublisher : ClientEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 13:51:28.865 INFO 18948 --- [ask-scheduler-2] c.l.i.test.InnerEventPublisher : InnerEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 13:51:30.009 INFO 18948 --- [ask-scheduler-8] c.l.integration.test.EsbEventPublisher : EsbEventPublisher 收到:{a=a, b=b, c=c}
***********************注意哈,我发了哈
2021-07-20 13:55:20.821 INFO 18948 --- [nio-8091-exec-5] c.l.i.test.CacheEventPublisher : CacheEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 13:55:20.822 INFO 18948 --- [nio-8091-exec-5] c.l.integration.test.EventHandler4Audit : EventHandler4Audit 收到:{a=a, b=b, c=c}
2021-07-20 13:55:20.822 INFO 18948 --- [nio-8091-exec-5] c.l.i.test.ClientEventPublisher : ClientEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 13:55:20.825 INFO 18948 --- [ask-scheduler-6] c.l.integration.test.EsbEventPublisher : EsbEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 13:55:21.344 INFO 18948 --- [ask-scheduler-2] c.l.i.test.InnerEventPublisher : InnerEventPublisher 收到:{a=a, b=b, c=c}
分析一下,可以很明显的看出,前面3个service-activator是在同一个线程连操作的,并且它们3个为顺序执行的操作。当三个执行完之后会进入bridge。而bridge的两个是两个异步线程处理的,不受互相影响。这个时候,好奇心不禁在问我,那前三个和bridge呢?然后我调了下代码,把bridge调到前面,如下:
<int:gateway service-interface="com.lin.integration.service.interfaces.IEventSender"
id="publishEvent" default-request-channel="publishEventChannel"/>
<int:publish-subscribe-channel id="publishEventChannel"/>
<int:bridge input-channel="publishEventChannel" output-channel="publishEsbEventChannel"/>
<int:bridge input-channel="publishEventChannel" output-channel="publishInnerEventChannel"/>
<int:service-activator input-channel="publishEventChannel" ref="cacheEventPublisher"
method="publish"/>
<int:service-activator input-channel="publishEventChannel" ref="eventHandler4Audit"
method="handle"/>
<int:service-activator input-channel="publishEventChannel" ref="clientEventPublisher"
method="publish"/>
输出结果为:
***********************注意哈,我发了哈
2021-07-20 14:05:39.389 INFO 20928 --- [ask-scheduler-6] c.l.integration.test.EsbEventPublisher : EsbEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:05:39.389 INFO 20928 --- [nio-8091-exec-2] c.l.i.test.CacheEventPublisher : CacheEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:05:39.390 INFO 20928 --- [nio-8091-exec-2] c.l.integration.test.EventHandler4Audit : EventHandler4Audit 收到:{a=a, b=b, c=c}
2021-07-20 14:05:39.391 INFO 20928 --- [nio-8091-exec-2] c.l.i.test.ClientEventPublisher : ClientEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:05:40.480 INFO 20928 --- [ask-scheduler-8] c.l.i.test.InnerEventPublisher : InnerEventPublisher 收到:{a=a, b=b, c=c}
***********************注意哈,我发了哈
2021-07-20 14:05:43.109 INFO 20928 --- [nio-8091-exec-3] c.l.i.test.CacheEventPublisher : CacheEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:05:43.110 INFO 20928 --- [nio-8091-exec-3] c.l.integration.test.EventHandler4Audit : EventHandler4Audit 收到:{a=a, b=b, c=c}
2021-07-20 14:05:43.110 INFO 20928 --- [nio-8091-exec-3] c.l.i.test.ClientEventPublisher : ClientEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:05:43.410 INFO 20928 --- [ask-scheduler-9] c.l.integration.test.EsbEventPublisher : EsbEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:05:43.490 INFO 20928 --- [ask-scheduler-3] c.l.i.test.InnerEventPublisher : InnerEventPublisher 收到:{a=a, b=b, c=c}
***********************注意哈,我发了哈
2021-07-20 14:07:35.390 INFO 20928 --- [nio-8091-exec-6] c.l.i.test.CacheEventPublisher : CacheEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:07:35.390 INFO 20928 --- [sk-scheduler-10] c.l.i.test.InnerEventPublisher : InnerEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:07:35.390 INFO 20928 --- [nio-8091-exec-6] c.l.integration.test.EventHandler4Audit : EventHandler4Audit 收到:{a=a, b=b, c=c}
2021-07-20 14:07:35.391 INFO 20928 --- [nio-8091-exec-6] c.l.i.test.ClientEventPublisher : ClientEventPublisher 收到:{a=a, b=b, c=c}
2021-07-20 14:07:36.278 INFO 20928 --- [ask-scheduler-3] c.l.integration.test.EsbEventPublisher : EsbEventPublisher 收到:{a=a, b=b, c=c}
我又经过很多次调整,总结了一下发现的内容:
(1)channel中是xml的配置的顺序进行的
(2)当进入service-activator时,会在当前线程中进行执行,方法执行完后,才会继续执行后面的内容
(3)当进入bridge时,会另起一个线程开始处理内容
(4)当然,因为service-activator的线程问题,如果其中一个报错,后面也会报错。在bridge因为开启了另一个线程,如果其中一个报错,不会影响其他线程的操作