I have a scenario where , I am trying to read data from Yelp API and want to put it into a ActiveMQ queue after certain intervals, So I am using quartz scheduler for the same.My quartz scheduler runs after every 10 minutes and pushes the data to queue,
All is fine till here,
Now I want this to work in a clustered environment, where I will have 2 instances deployed and listening to same Yelp Endpoint , Now what is happening is, my quartz scheduler from 2 instances are executing at same instance and they extract same information from Yelp ,causing same messages to land up in ActiveMQ queue, that is DUPLICATES,(I want to use clustered environment for High availability purposes, i.e. if any node fails other node can takeover.)
So is there any configuration, in Mule which can promote one node as master and other as failover node.
Thanks for all the help!
This will trigger by the cron expression 0/10 * * * * ? (each 10th second) for one of all nodes running the same application and that connects to the same database (MySQL in this case). The Quartz setup is a bit messy. You need to configure the database etc, but I leave you studying the Quartz docs for that. You should look at version 1.8.x and not 2.x.
It's pretty much a budget alternative of clustering endpoints in Mule EE. It's useful when you do not want to cluster your EE nodes or need to run CE nodes.
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:quartz="http://www.mulesoft.org/schema/mule/quartz" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.6.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/quartz http://www.mulesoft.org/schema/mule/quartz/current/mule-quartz.xsd">
<quartz:connector name="quartzConnector" validateConnections="true" doc:name="Quartz">
<quartz:factory-property key="org.quartz.scheduler.instanceName" value="QuartzScheduler" />
<quartz:factory-property key="org.quartz.scheduler.instanceId" value="AUTO" />
<quartz:factory-property key="org.quartz.jobStore.isClustered" value="true" />
<quartz:factory-property key="org.quartz.scheduler.jobFactory.class" value="org.quartz.simpl.SimpleJobFactory" />
<quartz:factory-property key="org.quartz.threadPool.class" value="org.quartz.simpl.SimpleThreadPool" />
<quartz:factory-property key="org.quartz.threadPool.threadCount" value="3" />
<quartz:factory-property key="org.quartz.scheduler.rmi.proxy" value="false" />
<quartz:factory-property key="org.quartz.scheduler.rmi.export" value="false" />
<quartz:factory-property key="org.quartz.jobStore.class" value="org.quartz.impl.jdbcjobstore.JobStoreTX" />
<quartz:factory-property key="org.quartz.jobStore.driverDelegateClass" value="org.quartz.impl.jdbcjobstore.StdJDBCDelegate" />
<quartz:factory-property key="org.quartz.jobStore.dataSource" value="quartzDataSource" />
<quartz:factory-property key="org.quartz.jobStore.tablePrefix" value="QRTZ_" />
<quartz:factory-property key="org.quartz.dataSource.quartzDataSource.driver" value="com.mysql.jdbc.Driver" />
<quartz:factory-property key="org.quartz.dataSource.quartzDataSource.URL" value="jdbc:mysql://localhost:3306/qrtz" />
<quartz:factory-property key="org.quartz.dataSource.quartzDataSource.user" value="root" />
<quartz:factory-property key="org.quartz.dataSource.quartzDataSource.password" value="" />
<quartz:factory-property key="org.quartz.dataSource.quartzDataSource.maxConnections" value="8" />
</quartz:connector>
<flow name="cFlow1">
<quartz:inbound-endpoint jobName="job1" cronExpression="0/10 * * * * ?" repeatInterval="0" connector-ref="quartzConnector" responseTimeout="10000" doc:name="Quartz">
<quartz:event-generator-job>
<quartz:payload>Job Trigger</quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
<logger level="INFO" message="Got message" doc:name="Logger"/>
</flow>
</mule>
We use 3.5.2-Enterprise edition but not sure if there is restriction on the community edition as such. Can you try the following way and see if that works:
<!-- Quart Connector with one thread to ensure that we don't have duplicate processing at any point of time -->
<quartz:connector name="QuartzConnector" validateConnections="true">
<receiver-threading-profile maxThreadsActive="1" />
</quartz:connector>
Then refer this in your flow wherever you are planning to trigger this action.
<flow name="test">
<quartz:inbound-endpoint jobName="myQuartzJob" cronExpression="${my.job.cron.expression}" repeatInterval="${my.job.repeat.interval}" responseTimeout="${my.job.response.timeout}" connector-ref="QuartzConnector">
<quartz:event-generator-job>
<quartz:payload>blah</quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
</flow>
Hope that works.
Related
My Mule Quartz Connector runs for several hours then terminates abruptly. I want the job to run continuously every 30 minutes past the hour. However, after running for several hours it suddenly terminates. I suspect it is related to the cronExpression but I am not sure which part will cause that to happen. I feel that the cronExpression has something that is making this happen, as it simply shuts the application down terminating the process.
Please help!!
Here is the quartz configuration:
<quartz:connector name="updateQuartzConnector" validateConnections="true" doc:name="Quartz">
<receiver-threading-profile maxThreadsActive="1"/>
<quartz:factory-property key="org.quartz.scheduler.instanceName" value="updateQuartzScheduler"/>
<quartz:factory-property key="org.quartz.threadPool.class" value="org.quartz.simpl.SimpleThreadPool"/>
<quartz:factory-property key="org.quartz.threadPool.threadCount" value="1"/>
<quartz:factory-property key="org.quartz.scheduler.rmi.proxy" value="false"/>
<quartz:factory-property key="org.quartz.scheduler.rmi.export" value="false"/>
<quartz:factory-property key="org.quartz.jobStore.class" value="org.quartz.simpl.RAMJobStore"/>
</quartz:connector>
And here is the flow using the quartz configuration above:
<flow name="processClientData" tracking:enable-default-events="true" processingStrategy="synchronous">
<quartz:inbound-endpoint responseTimeout="10000" doc:name="30 minutes past hour" cronExpression="0 30/30 0/1 * * ?"
jobName="ProcessClientUpdates" repeatInterval="0" connector-ref="updateQuartzConnector">
<quartz:event-generator-job/>
</quartz:inbound-endpoint>
<flow-ref name="process.client.data" />
</flow>
I show part of the flow, although this part works fine:
<flow name="process.client.data" processingStrategy="synchronous">
<db:select config-ref="ORACLE_CONFIG" doc:name="Check Customer existence in Database">
<db:parameterized-query><![CDATA[SELECT first_name,last_name,email FROM contact
WHERE email=#[payload.email]]]></db:parameterized-query>
</db:select>
<enrich source="#[payload.size() > 0]" target="#[recordVars['exists']]"/>
<enrich source="#[payload]" target="#[recordVars['dbRecord']]"/>
.......
</flow>
Please help this issue is just perplexing
The cron expression should be 0 30/30 * * *?
I have a request-response flow that starts with VM. Is there a way to restrict a number of the requests that could be processed in parallel by the flow? I'm on 3.7. Thanks.
Ps. I've tried using maxThreadsActive in VM connector but it still runs in the "source" thread. This is how the VM connector in defined:
<vm:connector name="myvm" validateConnections="true" doc:name="VM">
<receiver-threading-profile maxThreadsActive="1"/>
<vm:queue-profile>
<default-in-memory-queue-store/>
</vm:queue-profile>
</vm:connector>
and then in the flow:
<vm:inbound-endpoint exchange-pattern="request-response" path="myqueue" connector-ref="myvm" doc:name="getevent">
<vm:transaction action="NONE"/>
</vm:inbound-endpoint>
This is how it's called from the "source" flow:
<vm:outbound-endpoint exchange-pattern="request-response" path="myqueue" connector-ref="myvm" doc:name="VM">
<vm:transaction action="NONE"/>
</vm:outbound-endpoint>
You can configure the number of receiver threads for the connector or your inbound-endpoint to one:
<vm:connector name="VM" validateConnections="true">
<receiver-threading-profile maxThreadsActive="1"/>
</vm:connector>
<flow name="testFlow1">
<vm:inbound-endpoint path="in" connector-ref="VM"/>
<echo-component/>
</flow>
You can control this with the threading profiles. For example:
<configuration >
<default-threading-profile maxBufferSize="100" maxThreadsActive="20" maxThreadsIdle="10" threadTTL="60000" poolExhaustedAction="RUN" />
</configuration>
You can read more here: https://docs.mulesoft.com/mule-user-guide/v/3.7/tuning-performance
I went to the following site:
http://www.mulesoft.org/documentation/display/current/Tuning+Performance
and it says to alter the following 2 values:
maxThreadsActive and maxBufferSize
with maxThreadsActive being the number of active threads at anyone time, and maxBufferSize being the number of requests that can wait in a queue
But I am having difficulty finding any examples of how to do this in code.
-- Is there a central Mule ESB file where I can change the default number of maxThreadsActive and maxBufferSize ???
Would this be the dispatcher threading profile. What file would that be ?
--
If there is no central filet, for a synchronous process, how would I change the following code to use a maximum number of active threads to 100 and a maximum number of requests on the queue to 60
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:https="http://www.mulesoft.org/schema/mule/https" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:db="http://www.mulesoft.org/schema/mule/db" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/https http://www.mulesoft.org/schema/mule/https/current/mule-https.xsd">
<db:generic-config name="Generic_Database_Configuration" url="jdbc:db2://localhost:50000/TEST:user=instuid;password=instpw;" driverClassName="com.ibm.db2.jcc.DB2Driver" doc:name="Generic Database Configuration"/>
<http:endpoint exchange-pattern="request-response" host="localhost" port="8081" method="POST" name="HTTP" doc:name="HTTP"/>
<flow name="test1Flow1" doc:name="test1Flow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" contentType="application/json" keepAlive="true" mimeType="application/json"/>
<echo-component doc:name="Echo"/>
</flow>
</mule>
Thanks
You can used a queued-asynchronous processing strategy in you flow. With this approach you can change the number of threads available to the flow.
For Example:
<queued-thread-per-processor-processing-strategy name="ProcessingStrategy" maxThreads="60" minThreads="10" threadTTL="5000" poolExhaustedAction="WAIT" threadWaitTimeout="5000" maxBufferSize="100"/>
<flow name="test1Flow1" doc:name="test1Flow1" processingStrategy="ProcessingStrategy">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" contentType="application/json" keepAlive="true" mimeType="application/json"/>
<echo-component doc:name="Echo"/>
</flow>
"You can specify a separate threading profile for each receiver thread pool, flow thread pool, and dispatcher thread pool". For example:
<http:connector name="DefaultHTTPConnector" clientSoTimeout="120000" keepSendSocketOpen="false" >
<receiver-threading-profile maxThreadsActive="500"/>
<dispatcher-threading-profile maxThreadsActive="500"/>
</http:connector>
or
<configuration>
<default-receiver-threading-profile maxThreadsActive="130" />
</configuration>
I recommend the first option in the flow.
I hope to help;
You cannot add a flow processing strategy on a request-response exchange pattern
Add a global configuration element as follows:
I have a complex flow that can be drastically reduced to this one (for the sake of this question):
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:context="http://www.springframework.org/schema/context" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:ajax="http://www.mulesoft.org/schema/mule/ajax" xmlns:quartz="http://www.mulesoft.org/schema/mule/quartz"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/quartz http://www.mulesoft.org/schema/mule/quartz/current/mule-quartz.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ajax http://www.mulesoft.org/schema/mule/ajax/current/mule-ajax.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">
<quartz:connector name="quartzConnector_vm" validateConnections="true" doc:name="Quartz">
<quartz:factory-property key="org.quartz.scheduler.instanceName" value="MuleScheduler1"/>
<quartz:factory-property key="org.quartz.threadPool.class" value="org.quartz.simpl.SimpleThreadPool"/>
<quartz:factory-property key="org.quartz.threadPool.threadCount" value="3"/>
<quartz:factory-property key="org.quartz.scheduler.rmi.proxy" value="false"/>
<quartz:factory-property key="org.quartz.scheduler.rmi.export" value="false"/>
<quartz:factory-property key="org.quartz.jobStore.class" value="org.quartz.simpl.RAMJobStore"/>
</quartz:connector>
<context:property-placeholder location="my-mule-app.properties"/>
<flow name="testQuartzFlow1" doc:name="testQuartzFlow1">
<quartz:inbound-endpoint cronExpression="${SCHEDULE_FREQUENCY}" responseTimeout="10000" connector-ref="quartzConnector_vm" doc:name="Event_generator" jobName="pollastro">
<quartz:event-generator-job groupName="DEFAULT" jobGroupName="DEFAULT">
<quartz:payload>"${WHOAMI}"</quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
<logger level="INFO" doc:name="Logger" message="#[message:payload]"/>
</flow>
</mule>
Basically a quartz component that every certain amount of minutes (read from a property file) fires a logger that logs another data taken from a property file.
What I want is:
To run more instance of the same flow simultaneously, each instance with a different set of properties (to be contained on a file)
To be able, in some way, to stop/start the a certain instance.
How can I do this?
Thank you
For 1), I've heard of an experimental module that allows using configuration templates and substitute values in the template at start-up time. I unfortunately can't locate it for now but will update my answer if I can.
Alternatively, if what's happening after each quartz:inbound-endpoints is the same, you could wrap them in a <composite-source> and programatically add more endpoints to this source at start-up time.
Other alternatives are to completely build the flow with custom code or even generate the XML configuration based on the properties files as a pre-Mule boot phase.
For 2) You can control endpoints (connect/disconnect) over JMX so, in theory, you should be able to control the Quartz endpoints that way.
How do I create a delayed JMS message processor in Mule 3.3.1? My goal is to process messages from a queue in certain interval...some listener that wakes up every minute to process messages.
I have the following configuration, but the delay is not honored. When a message is rolled back, it is immediately picked for processing.
<spring:bean id="MQConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<spring:property name="transportType" value="1"/>
<spring:property name="hostName" value="myHost"/>
<spring:property name="port" value="1414"/>
<spring:property name="queueManager" value="myQmgr"/>
</spring:bean>
<jms:connector name="queueConnector" connectionFactory-ref="MQConnectionFactory"
specification="1.1" username="xxx" password="yyy"
disableTemporaryReplyToDestinations="true"
numberOfConcurrentTransactedReceivers="3" maxRedelivery="5">
<service-overrides transactedMessageReceiver="com.mulesoft.mule.transport.jms.TransactedPollingJmsMessageReceiver"/>
</jms:connector>
<jms:endpoint name="someQueue" queue="osmQueue" connector-ref="queueConnector">
<jms:transaction action="ALWAYS_BEGIN"/>
<property key="pollingFrequency" value="60000"/>
</jms:endpoint>
I did a lot of search but am unable to indentify a proper solution. If there is a better option, I'm open. Appreciate any help. 2 days and no response? Did I phrase the question wrong?
Have you tried using Quartz?
This config fires up your JMS inbound every minute
<flow name="ftpFlow2" doc:name="ftpFlow2">
<quartz:inbound-endpoint jobName="job1" repeatInterval="60000" responseTimeout="10000" doc:name="Quartz">
<quartz:endpoint-polling-job>
<quartz:job-endpoint ref="someQueue"/>
</quartz:endpoint-polling-job>
</quartz:inbound-endpoint>
</flow>