原文 https://docs.mulesoft.com/mule-user-guide/v/3.8/tuning-performance
一个Mule app是 一系列 flows 的集合。概述的讲,mule通过flows处理消息可以分成三个阶段:
- 通过入站连接接收消息
- 消息处理
- 消息传输到出站连接
先处理第一阶段,第二和第三阶段可以交叉操作
Mule 线程
每个Request到达Mule之后都会在自己的线程中处理。Connector在Inbound endpoints入站端点有一个确定数量的线程池来处理请求。
Mule 可以同步或者异步发送消息。除了下列几点,消息都是通过异步来发送消息:
- flow 使用同步处理策略
- flow 参与事务
- inbound endpoint 使用request-response模式接收消息
如果你使用同步方式,Mule在消息处理以及消息传递过程中始终使用同一线程。消息处理完之后发送到 outbound endpoint端点:
- 如果出站端点 outbound endpoint 是one-way方式,消息发送使用flow的同一线程,一旦消息被发送出去,该线程继续去处理相同的消息。不会等待远程端点是否接受消息。
- 如果是request-response方式,flow线程会发送消息到出站端点并且等待response回复,当response到达,flow处理response并继续处理flow其他消息。
如果你使用异步方式,mule会使用消息接受线程只将消息放置到SEDA 消息队列,在队列中消息会被调入到一个flow线程中,消息接收线程会被释放到线程池中从而继续处理其他消息。当消息在flow线程中被处理之后,如果需要发送到outbound endpoint端点:
- 如果出站端点outbound endpoint 使用 one-way方式,消息会被复制到 dispatcher thread 中进行处理,同时flow线程继续平行的处理原始消息。
- 如果出战端点是request-response方式,flow线程发送消息到outbound endpoint线程并等待response,当response到达,flow处理response并继续处理flow其他消息。
Mule flows 包含3中线程池:
- 消息接收线程(The receiver thread) - 接收消息
- 同步处理(整个flow)
- 或者最终写入seda队列做异步处理
- 消息处理线程(The flow thread) –异步处理flow
- 消息分发线程(Dispatcher threads) - 发送消息到one-way端点(异步)
线程池和线程配置文件
每个receiver消息接收器,flow(消息处理),dispatcher消息分配器都有各自隔离的线程池。
线程配置文件指定如何分配线程池。你可以指定各自的线程配置文件。每个配置文件有一个最重要的设置参数:maxThreadsActive指定线程池大小。
线程池配置文件
不像单例组件,每个线程池组件(类PooledJavaComponent.java)都有一个组件线程池,这个池中包含多个组件的实例用来处理并发请求。每个组件线程池配置文件配置了各自的组件线程池参数。其中最重要的一个参数是 maxActive
,它指定了Mule要创建用于处理并发请求的组件实例的最大数目。注意,这个参数必须要和消息接受线程池的 maxThreadsActive
一致,最终你能够又有足够的组件实例来处理线程。
计算线程
为了计算线程数量该有多少,一下因素必须考虑到:
用户并发请求
通常,用户并发请求数是指MuleServer能够在任意一个时间点同时处理请求的总数。对于Flow,用户并发请求是指flow的inbound endpoint可以同时处理消息的请求数。
处理时间
- 响应时间
- 超时时间
用户并发数 = maxThreadsActive + maxBufferSize
maxThreadsActive
是并发线程数
maxBufferSize
是队列中等待被释放的请求数目
计算Flow线程 (Flow Threads)
即使你正在执行同步消息传递,你也必须计算flow线程从而能够正确地计算消息接受线程。
您的业务需求规定了每个流程必须能够同时处理多少个线程。例如,一个流可能需要一次处理50个请求,而另一个可能需要一次处理40个请求。通常你会设置maxThreadsActive
属性的值(比如 为maxThreadsActive = 40)。
如果您有对同步处理的超时设置的需求,那么您必须为每个流做一些额外的计算:
- 运行同步测试用例以确定响应时间
- 从您的业务需求所规定的超时时间中减去响应时间,这就是你的最长等待时间。
(maximum wait time = timeout time - response time)
- 将最大等待时间除以响应时间,以获得连续运行的批处理数量,以在最大等待时间内完成所有并发请求
(batches = maximum wait time / response time)
请求在队列中等待,直到第一批完成,然后第一批的线程被释放,并被下一批批处理。 - 将并发用户请求除以批处理的数量,以获得流的maxThreadsActive设置的线程大小
(maxThreadsActive = concurrent user requests / processing batches)
这就是该flow线程并发总数。 - 将maxBufferSize 设置为并发用户请求减去maxThreadsActive
(maxBufferSize = concurrent user requests - maxThreadsActive)
.这就是队列中在等待被释放的请求数。
综上,有超时限制的同步处理的公式可以总结为:
Maximum wait time = timeout time - response time
Batches = maximum wait time / response time
maxThreadsActive = concurrent user requests / batches
maxBufferSize = concurrent user requests - maxThreadsActive
计算消息接受线程 (Receiver Threads)
当connector的reveiver接收器被所有的flow共享,这些flow在其入站端点 inbound endpoint指定相同的connector连接器。上一节讲述了如何为每个flow计算maxThreadsActive,要计算connector的receiver接收方的maxThreadsActive设置,也就是说,您应该为连接器的接收线程池分配多少线程,并为在入站端点上使用该连接器的每个flow进行maxThreadsActive设置:
maxThreadsActive = ∑ (flow 1 maxThreadsActive, flow 2 maxThreadsActive…flow n maxThreadsActive)
举个例子,如果你有三个flow,在inboud endpoint 上使用了 VM connector,业务需求前两个flow一次处理50个请求,后一个处理40个,那么在receiver接受线程配置文件中要为 vm connector 设置maxThreadsActive为140。
计算分发线程 (Dispatcher Threads)
Dispatcher线程仅用于异步出站处理,也就是one-way方式的outbound分发。通常,为该dispatcher设置的maxThreadsActive 是 使用该dispatcher的所有flow的maxThreadsActive
的和。