﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-paulwong-随笔分类-EVEN DRIVEN ARCHITECT</title><link>http://www.blogjava.net/paulwong/category/55385.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 23 Nov 2021 14:41:59 GMT</lastBuildDate><pubDate>Tue, 23 Nov 2021 14:41:59 GMT</pubDate><ttl>60</ttl><item><title>SPRING REACTOR 之Flux和Mono</title><link>http://www.blogjava.net/paulwong/archive/2021/11/23/436063.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Tue, 23 Nov 2021 06:30:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2021/11/23/436063.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/436063.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2021/11/23/436063.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/436063.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/436063.html</trackback:ping><description><![CDATA[<div>SPRING REACTOR 之Flux和Mono，有点象SPRING INTEGRATION的IntegrationFlow，有如下特点<br />
<ul>
     <li>定义了针对某种类型数据的处理流程</li>
     <li>可以进行类型转换</li>
     <li>长期运行，除非被要求中止</li>
     <li>流程中的每种操作可以在新的线程中执行</li>
     <li>可以正常中止，如果中途有异常，则该流程也会中止</li>
     <li>要subscribe，流程才开始被启动</li>
     <li>可以分割成各个子流程</li>
     <li>可以聚合子流程</li>
<li>Mono发送一个数据，就发送中止信号</li><li>Flux发送任意数据，由程序决定何时发送中止信号</li></ul>
<br />
编程则比较简单，先根据不同的数据类型定义不同的Flux或Mono，业务操作用Function包装后，放在map/flatmap中，再调用subscribe启动流程。</div><img src ="http://www.blogjava.net/paulwong/aggbug/436063.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2021-11-23 14:30 <a href="http://www.blogjava.net/paulwong/archive/2021/11/23/436063.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EVEN DRIVEN - SPRING CLOUD STREAM - @PollableBean for Reactive Suppliers</title><link>http://www.blogjava.net/paulwong/archive/2021/11/23/436060.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Tue, 23 Nov 2021 02:03:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2021/11/23/436060.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/436060.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2021/11/23/436060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/436060.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/436060.html</trackback:ping><description><![CDATA[<p style="font-family: &quot;Open Sans&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; overflow-wrap: break-word; word-break: break-word; line-height: inherit; color: #222222; font-size: 16px; box-sizing: inherit; margin: 0px 0px 16px; padding: 0px; border: 0px; vertical-align: baseline; outline: 0px; text-overflow: ellipsis; background-color: #ffffff;"><code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">Supplier</code>&nbsp;beans, or functions that only publish messages in Spring Cloud Stream, are a bit special in that they aren't triggered by the receiving of events like&nbsp;<code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">Function</code>&nbsp;or&nbsp;<code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">Consumer</code>&nbsp;beans. This means that you often need a way to trigger them to be executed periodically.</p>
<p style="font-family: &quot;Open Sans&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; overflow-wrap: break-word; word-break: break-word; line-height: inherit; color: #222222; font-size: 16px; box-sizing: inherit; margin: 8px 0px 16px; padding: 0px; border: 0px; vertical-align: baseline; outline: 0px; text-overflow: ellipsis; background-color: #ffffff;">For&nbsp;<strong style="font-family: inherit; overflow-wrap: break-word; word-break: break-word; line-height: inherit; color: inherit; font-size: inherit; box-sizing: inherit;">imperative</strong>&nbsp;functions the framework by default "polls" a&nbsp;<code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">Supplier</code>&nbsp;function every 1 second, but that duration is configurable using the&nbsp;<code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">spring.cloud.stream.poller.fixed-delay</code>&nbsp;property.</p>
<p style="font-family: &quot;Open Sans&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; overflow-wrap: break-word; word-break: break-word; line-height: inherit; color: #222222; font-size: 16px; box-sizing: inherit; margin: 8px 0px 16px; padding: 0px; border: 0px; vertical-align: baseline; outline: 0px; text-overflow: ellipsis; background-color: #ffffff;">However, for&nbsp;<strong style="font-family: inherit; overflow-wrap: break-word; word-break: break-word; line-height: inherit; color: inherit; font-size: inherit; box-sizing: inherit;">reactive</strong>&nbsp;functions supplying a&nbsp;<code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">Flux</code>&nbsp;it is only triggered once by default. This is because a Flux itself is potentially an infinite stream of events so in many cases it will only need to be triggered once. But don't worry, if you want to periodically trigger a reactive&nbsp;<code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">Supplier</code>&nbsp;because you are producing a finite stream of events you can still do so using&nbsp;<code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">@PollableBean</code>. This annotation then allows you to configure how often the function is triggered using the same&nbsp;<code codeinline"="" spellcheck="false" tabindex="0" style="font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; overflow-wrap: break-word; word-break: break-word; line-height: inherit; font-size: 0.85em; font-weight: inherit; box-sizing: inherit; margin: 0px; padding: 0.2em 0.4em; border: none; font-style: inherit; vertical-align: middle; background: #f7f7f7; overflow: auto; outline: 0px; display: inline; position: static; max-width: 100%; flex-shrink: 0; border-radius: 2px;">spring.cloud.stream.poller.fixed-delay</code>&nbsp;property!</p>
<p style="font-family: &quot;Open Sans&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; overflow-wrap: break-word; word-break: break-word; line-height: inherit; color: #222222; font-size: 16px; box-sizing: inherit; margin: 8px 0px 16px; padding: 0px; border: 0px; vertical-align: baseline; outline: 0px; text-overflow: ellipsis; background-color: #ffffff;">One example use case here could be periodically querying a data store and publishing each entry/row as an event. The number of rows in your data store is a finite number at any given time.</p>
<p style="font-family: &quot;Open Sans&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, -apple-system, BlinkMacSystemFont, HelveticaNeue-Light, &quot;Segoe UI&quot;, &quot;Helvetica Neue&quot;, Helvetica, Raleway, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; overflow-wrap: break-word; word-break: break-word; line-height: inherit; color: #222222; font-size: 16px; box-sizing: inherit; margin: 8px 0px 16px; padding: 0px; border: 0px; vertical-align: baseline; outline: 0px; text-overflow: ellipsis; background-color: #ffffff;">Example code:</p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->@PollableBean&nbsp;<br /><span style="color: #0000FF; ">public</span>&nbsp;Supplier&lt;Flux&lt;String&gt;&gt;&nbsp;stringSupplier()&nbsp;{&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;()&nbsp;-&gt;&nbsp;Flux.just("foo","bar","baz");&nbsp;}</div><br /><br />Reference:<br /><a href="https://solace.community/discussion/360/pollablebean-for-reactive-suppliers-in-spring-cloud-stream" target="_blank">https://solace.community/discussion/360/pollablebean-for-reactive-suppliers-in-spring-cloud-stream</a><img src ="http://www.blogjava.net/paulwong/aggbug/436060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2021-11-23 10:03 <a href="http://www.blogjava.net/paulwong/archive/2021/11/23/436060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EVEN DRIVEN - SPRING CLOUD STREAM - 从非SCS组件发送消息到SCS组件</title><link>http://www.blogjava.net/paulwong/archive/2021/11/19/436054.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Fri, 19 Nov 2021 03:47:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2021/11/19/436054.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/436054.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2021/11/19/436054.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/436054.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/436054.html</trackback:ping><description><![CDATA[在SPRING INTEGRATION中，如果要从非SPRING INTEGRATION代码发送MESSAGE到SPRING INTEGRATION程序，通常用BUS GATEWAY。<br />
<br />
那么在SPRING CLOUD STREAM中，如果要从非SPRING CLOUD STREAM代码发送MESSAGE到SPRING CLOUD STREAM程序，通常就要先通知框架自动生成一个SOURCE。<br />
<br />
application.property<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->spring.cloud.stream.source=supplier<br />
spring.cloud.stream.bindings.supplier-out-0.destination=notification-events</div>
<br />
java<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->streamBridge.send("supplier-out-0",&nbsp;userDto);</div>
<br />Reference:<br /><a href="https://blog.devgenius.io/event-driven-microservices-with-spring-cloud-stream-e034eee3f394" target="_blank">https://blog.devgenius.io/event-driven-microservices-with-spring-cloud-stream-e034eee3f394</a><br /><img src ="http://www.blogjava.net/paulwong/aggbug/436054.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2021-11-19 11:47 <a href="http://www.blogjava.net/paulwong/archive/2021/11/19/436054.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EVEN DRIVEN - SPRING CLOUD STREAM - Error Handling</title><link>http://www.blogjava.net/paulwong/archive/2021/11/17/436052.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Wed, 17 Nov 2021 02:50:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2021/11/17/436052.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/436052.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2021/11/17/436052.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/436052.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/436052.html</trackback:ping><description><![CDATA[如果Function中抛出异常，系统没有配置捕获异常，则异常消息会被丢弃。通常会进行配置。<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->@ServiceActivator(inputChannel&nbsp;=&nbsp;"my-destination.my-group.errors")<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;handleError(ErrorMessage&nbsp;message)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable&nbsp;throwable&nbsp;=&nbsp;message.getPayload();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error("截获异常",&nbsp;throwable);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Message&lt;?&gt;&nbsp;originalMessage&nbsp;=&nbsp;message.getOriginalMessage();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">assert</span>&nbsp;originalMessage&nbsp;!=&nbsp;<span style="color: #0000FF; ">null</span>;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.info("原始消息体&nbsp;=&nbsp;{}",&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;String((<span style="color: #0000FF; ">byte</span>[])&nbsp;originalMessage.getPayload()));<br />&nbsp;&nbsp;&nbsp;&nbsp;}</div><br />详情参考：<br /><a href="https://www.itmuch.com/spring-cloud/spring-cloud-stream-error-handling/" target="_blank">https://www.itmuch.com/spring-cloud/spring-cloud-stream-error-handling/</a><img src ="http://www.blogjava.net/paulwong/aggbug/436052.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2021-11-17 10:50 <a href="http://www.blogjava.net/paulwong/archive/2021/11/17/436052.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EVEN DRIVEN - SPRING CLOUD STREAM - Function Component</title><link>http://www.blogjava.net/paulwong/archive/2021/11/15/436051.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Mon, 15 Nov 2021 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2021/11/15/436051.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/436051.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2021/11/15/436051.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/436051.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/436051.html</trackback:ping><description><![CDATA[如果要在SPRING CLOUD STREAM中和其他中间件打交道，如FILE、FTP、HTTP等，则要用到SPRING CLOUD FUNCTION。<br /><br />组件地址：<br /><a href="https://github.com/spring-cloud/stream-applications/tree/main/functions" target="_blank">https://github.com/spring-cloud/stream-applications/tree/main/functions</a><br /><br />特殊组件，将FUNCTION变成HTTP ENDPOINTS：<br /><a target="null"></a><a href="https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-starter-function-web" target="_blank">https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-starter-function-web</a><br /><a href="https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-starter-function-webflux" target="_blank">https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-starter-function-webflux</a><br /><br /><img src ="http://www.blogjava.net/paulwong/aggbug/436051.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2021-11-15 17:40 <a href="http://www.blogjava.net/paulwong/archive/2021/11/15/436051.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EVEN DRIVEN - SPRING CLOUD STREAM 3.x - Functional Programming Model</title><link>http://www.blogjava.net/paulwong/archive/2021/11/10/436035.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Wed, 10 Nov 2021 07:10:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2021/11/10/436035.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/436035.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2021/11/10/436035.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/436035.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/436035.html</trackback:ping><description><![CDATA[<div>SPRING CLOUD STREAM 3.x&nbsp;版本时，之前的一些编程模式，如@Enablebindding，@StreamListenner等注释被废弃了，这是由于一些框架的代码必需由用户编写，如配置框架用的Input MessageChannel，Output&nbsp; MessageChannel，连接MessageHandler与MessageChannel等，被视为不必要的动作。为了简化用户代码，于是推出Functional Programming Model。<br /><br />引入了新名词：Supplier、Function与Consumer。实际上这几个类可视为Adapter，如果之前已经有存在的Service类，且方法名为各种各样，可以重新包装成Supplier、Function与Consumer，并在固定的方法名：apply/get/accept中调用Service的方法。<br /><br /><h2>Supplier</h2>当在配置文件中注入此类型的Bean，并在spring.cloud.stream.function.definition加入此Bean的名称，SPRING CLOUD STREAM就会帮你生成一个Output&nbsp; MessageChannel，并连接上此Bean，后续只需要在BINDDING中加入对应的Destination Name，即可向BROKER发消息了。<br /><br /><h2>Consumer</h2>当在配置文件中注入此类型的Bean，并在spring.cloud.stream.function.definition加入此Bean的名称，SPRING CLOUD STREAM就会帮你生成一个Input&nbsp; MessageChannel，并连接上此Bean，后续只需要在BINDDING中加入对应的Destination Name，即可收到BROKER推送关于此Destination的消息了。<br /></div><h2>Function</h2>当在配置文件中注入此类型的Bean，并在spring.cloud.stream.function.definition加入此Bean的名称，SPRING CLOUD STREAM就会帮你生成一个Input和Output&nbsp; MessageChannel，并连接上此Bean，后续只需要在BINDDING中分别对Input和Output&nbsp;MessageChannel加入对应的Destination Name1/Name2，即可收到BROKER推送关于此Destination的消息，也可以向BROKER发消息了。<br /><br /><h2>与SPRING INTEGRATION的整合</h2>如果要对消息进行复杂处理，如拆分消息、聚合消息、IF ELSE消息等，就要借助SPRING INTEGRATION了。<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->@Bean<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;IntegrationFlow&nbsp;upperCaseFlow(LoanService&nbsp;loanService)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;IntegrationFlows<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">turn&nbsp;this&nbsp;IntegrationFlow&nbsp;as&nbsp;a&nbsp;gateway,&nbsp;here&nbsp;is&nbsp;a&nbsp;Function&nbsp;interface&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">with&nbsp;loadCheckerFunction&nbsp;as&nbsp;bean&nbsp;name</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.from(LoadCheckerFunction.<span style="color: #0000FF; ">class</span>,&nbsp;gateway&nbsp;-&gt;&nbsp;gateway.beanName("loadCheckerFunction"))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.handle(loanService,&nbsp;"check")<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.logAndReply(LoggingHandler.Level.WARN);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;LoadCheckerFunction&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;Function&lt;Loan,&nbsp;Loan&gt;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;}</div><br />IntegrationFlows.from(Class&lt;?&gt; serviceInterface)是可以将本IntegrationFlow包装成serviceInterface的实现类，如果调用此接口，最终会返回IntegrationFlow最后一个步骤的实体，如果这个serviceInterface是Function的话，刚好和SPRING CLOUD STREAM对接上。<br /><br />后续在spring.cloud.stream.function.definition加入此Bean的名称loadCheckerFunction，SPRING CLOUD STREAM就会帮你生成一个Input和Output&nbsp; MessageChannel，并连接上此Bean，再在BINDDING中分别对Input和Output&nbsp;MessageChannel加入对应的Destination Name1/Name2，即可收到BROKER推送关于此Destination的消息，也可以向BROKER发消息。<br /><br />application.yaml<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;This&nbsp;setting&nbsp;can&nbsp;increase&nbsp;or&nbsp;decrease&nbsp;the&nbsp;rate&nbsp;of&nbsp;message&nbsp;production&nbsp;(1000&nbsp;=&nbsp;1s)<br />#&nbsp;spring.cloud.stream.poller.fixed-delay=1000<br /><br />#&nbsp;This&nbsp;setting&nbsp;can&nbsp;control&nbsp;which&nbsp;function&nbsp;method&nbsp;in&nbsp;our&nbsp;code&nbsp;will&nbsp;be&nbsp;triggered&nbsp;if&nbsp;there&nbsp;are&nbsp;multiple<br />#&nbsp;spring.cloud.function.definition=supplyLoan<br /><br />#&nbsp;Give&nbsp;the&nbsp;autogenerated&nbsp;binding&nbsp;a&nbsp;friendlier&nbsp;name</span><span style="color: #008000; "><br /></span>spring:<br />&nbsp;&nbsp;&nbsp;application:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name:&nbsp;loan-check-rabbit<br />&nbsp;&nbsp;&nbsp;banner:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location:&nbsp;classpath:/banner-rabbit.txt<br />&nbsp;&nbsp;&nbsp;cloud:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function.definition:&nbsp;loadCheckerFunction<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">BindingProperties</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bindings:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loadCheckerFunction-in-<span style="color: #800000; ">0</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destination:&nbsp;queue.pretty.<span style="color: #0000FF; ">log</span>.messages<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;binder:&nbsp;local_rabbit<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loadCheckerFunction-out-<span style="color: #800000; ">0</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destination:&nbsp;queue.pretty.approved.messages<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;binder:&nbsp;local_rabbit<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">BinderProperties</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;binders:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_rabbit:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type:&nbsp;rabbit<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;environment:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spring:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rabbitmq:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host:&nbsp;<span style="color: #800000; ">10.80</span>.<span style="color: #800000; ">27.69</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;<span style="color: #800000; ">5672</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;username:&nbsp;guest<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password:&nbsp;guest<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual-host:&nbsp;<span style="color: #0000FF; ">my</span>-virtual-host</div><br /><h2>Reference</h2><a href="https://spring.io/blog/2019/10/25/spring-cloud-stream-and-spring-integration" target="_blank">https://spring.io/blog/2019/10/25/spring-cloud-stream-and-spring-integration</a><img src ="http://www.blogjava.net/paulwong/aggbug/436035.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2021-11-10 15:10 <a href="http://www.blogjava.net/paulwong/archive/2021/11/10/436035.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EVEN DRIVEN - SPRING CLOUD STREAM - SPRING CLOUD微服务的EVEN DRIVEN框架</title><link>http://www.blogjava.net/paulwong/archive/2021/11/05/436031.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Fri, 05 Nov 2021 06:58:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2021/11/05/436031.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/436031.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2021/11/05/436031.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/436031.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/436031.html</trackback:ping><description><![CDATA[通常微服务应用之间的通信是通过HTTP调用，吞吐性不建都高，高并发的场景建议使用EVENT DRIVEN的框架，即使用MESSAGE通信。<br /><br />即A微服务应用将数据发送到MESSAGE BROKER中的某个DESTINATION，此DESTINATION是广播型，非点对点型。B微服务应用订阅此DESTINATION，当有新MESSAGE到达此DESTINATION时，MESSAGE BROKER会将此MESSAGE推送给B应用。所有对此MESSAGE有需要的应用均可订阅，从而收到此MESSAGE。<br /><br />SPRING CLOUD&nbsp;中EVENT DRIVEN的框架就是SPRING CLOUD STREAM。其底层是使用SPRING INTEGRATION实现。<br /><br />SPRING CLOUD STREAM有以下新名词：<br /><br /><ul><li>BINDER：</li></ul>是对MESSAGE BROKER操作方法的抽象，即应用通过此BINDER操作MESSAGE BROKER。目前只实现了RABITMQ和KAFKA。<br /><ul><li>CHANNEL</li></ul>MESSAGE从SPRING CLOUD STREAM传给应用或相反是通过CHANNEL传递的，这点和SPRING INTEGRATION是一样的。<br /><ul><li>SOURCE</li></ul>MESSAGE从应用传给SPRING CLOUD STREAM的CHANNEL，叫@INPUT，包含这种CHANNEL的接口叫SOURCE。<br /><ul><li>SINK</li></ul>MESSAGE从SPRING CLOUD STREAM传给应用的CHANNEL，叫@OUPUT，包含这种CHANNEL的接口叫SINK。<br /><ul><li>BIDDING</li></ul>绑定哪个@INPUT或哪个@OUPUT与哪个DESTINATION发送或接收关系的MAPPING。<br /><ul><li>EnableBinding</li></ul>应用启动时就会建立EnableBinding指定的接口中的CHANNEL<br /><ul><li>消费者群组</li></ul>默认下如果同一个应用部署了多个实例，则每个实例都会收到MESSAGE，这时如果设置了消费者群组名称，则同一个名称下的多个实例，只有一个能收到MESSAGE。<br /><ul><li>PARTITION</li></ul>如果为MESSAGE指定规则，如MESSAGE某个字段值以A开头为一个规则，以B开头为一个规则，那么以A开头的MESSAGE会放到同一个分区中。<br /><br />这样使用就很简单了，只要取得OUTPUT CHANNEL，就可以发送MESSAGE，将代码关联到INPUT CHANNEL，就能在收到MESSAGE时，相关代码就会被执行。<br /><br /><img src ="http://www.blogjava.net/paulwong/aggbug/436031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2021-11-05 14:58 <a href="http://www.blogjava.net/paulwong/archive/2021/11/05/436031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>