I'm using WSO2 ESB to route API requests send to an application hosted on Heroku, through proxy service.
In the last few days, we've noticed connections to the Heroku app would timeout from time to time, resulting in the failure of the whole client process.
Those requests are part of a long process (video transcoding), so relaunching the entire process just because 1 out of 40 requests failed is not really an option. It would be best to retry every failed request automatically a second (or n) time(s).
Implementing "retry on timeout" directly into client code is a mess, so we thought the could handle it for us by configuring the endpoint to retry all timed out requests. The WSO2 ESB documentation on endpoint error handling, advertises it's possible by setuping a failover group that contains only one leaf endpoint, dealing with my exact use case when "even rare message failures are not acceptable".
However, the provided sample configuration seem to continue dropping messages:
<endpoint name="SampleFailover">
<failover>
<endpoint name="Sample_First" statistics="enable" >
<address uri="http://localhost/myendpoint" statistics="enable" trace="disable">
<timeout>
<duration>60000</duration>
</timeout>
<markForSuspension>
<errorCodes>101504, 101505, 101500</errorCodes>
<retriesBeforeSuspension>3</retriesBeforeSuspension>
<retryDelay>1</retryDelay>
</markForSuspension>
<suspendOnFailure>
<initialDuration>1000</initialDuration>
<progressionFactor>2</progressionFactor>
<maximumDuration>64000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</failover>
</endpoint>
I'm still seeing log entries in wso2carbon.log such as:
[2016-04-13 16:02:50,576] WARN - Expiring message ID : urn:uuid:fd515b80-8d67-47e5-b409-0ec39ed58fc6; dropping message after timeout of : 60 seconds {org.apache.synapse.core.axis2.TimeoutHandler}
What am I missing here ?
I add some difficulties with this topic, and it is yet not clear if the endpoint can itself retrigger and timed out call.
After reading this tutorial : https://www.yenlo.com/blog/wso2torial-error-handling-in-wso2-esb-with-wiremock?success=true, it seems that yes, but I'm not sure...
Have you already tried to remveo the error codes ?
<timeout>
<duration>60000</duration>
<responseAction>fault</responseAction>
</timeout>
<suspendOnFailure>
<initialDuration>1000</initialDuration>
<progressionFactor>2.0</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>3</retriesBeforeSuspension>
<retryDelay>1000</retryDelay>
</markForSuspension>
Related
I'm trying to write a SFTP location through a jms/http proxy. However when there is an error on SFTP endpoint (wrong password, network connectivity issue, remote Dir not exists) I want to trigger fault sequence and handle this error (Try some DLC kind of scenario). I found that fault Sequcence is not invoking for FTP errors unless you set OUT_ONLY=false. However WSO2 docs recommends set OUT_ONLY=true for ftp writes. Similar Question is asked here too. How to handle VFS proxy error in WSO2 EI 6.4?
If I set OUT_ONLY=false it triggers faultSquence for both failures and success FTP writes.
Any workaround to catch FTP errors and trigger faultSequence ?
You can define a responseAction in the endpoint configuration. Please refer to the following sample configuration. The responseAction spedifies when a response comes to a timed out request specifies whether to discard it or invoke the fault handler. Apart from defining the responseAction in the endpoint, you can replace the send mediator with the file connector and it will also invoke the fault sequence during an error.
<send>
<endpoint name="wms-fault-endpoint">
<address uri="vfs:ftp://admin:admin1#localhost:2121/testJ/out">
<timeout>
<duration>10000</duration>
<responseAction>fault</responseAction>
</timeout>
</address>
</endpoint>
</send>
[1]-https://docs.wso2.com/display/EI611/Endpoint+Error+Handling
[2]- https://docs.wso2.com/display/ESBCONNECTORS/File+Connector
We can see calls going from ESB to backend system old Ip instead of the new IP. For example
Wso2 ESB Endpoint configured as: somebackend.com
If we do nslookup to see the IP of the system.
$nslookup somebackend.com
10.20.30.40
If we trace the traffic from ESB using tcpdump with host as "somebackend.com" then calls are going to old IP of the system (somebackend.com) i,e, 50.60.70.80 instead of new IP 10.20.30.40
Is the name/Ip/DNS Name is cached anywhere in the WSo2 ESB.?
Any suggestions, please resolve this.
Below is the endpoint file configured.
<endpoint xmlns="http://ws.apache.org/ns/synapse"
name="conf//endpoint/endpointname">
<property name="System-Name" value="Backend" scope="default" type="STRING"/>
<http uri-template="somebackend.com"
method="get">
<suspendOnFailure>
<errorCodes>-1</errorCodes>
<initialDuration>0</initialDuration>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<errorCodes>-1</errorCodes>
</markForSuspension>
</http>
</endpoint>
Can you check in your /etc/hosts file whether you have wrongly mapped the old IP to the domain name (somebackend.com)? It might be a possibility because AFAIK ESB does not cache IP. Maybe restarting the ESB server would also help.
AFAIR WSO2 ESB does not cache endpoint IPs. Can you run a traceroute command on "somebackend.com" from the ESB node and check whether how DNS resolves from your machine?
Wso2 will store the connection details in connection pool and re-use the same connection details for the next calls instead new one. We added below property before making a call to the endpoint to initiate a fresh new connection for each call which resolved our issue.
FYI: https://docs.wso2.com/display/ESB490/HTTP+Transport+Properties
Thanks for the support guys.
I have setted configure and endpoint timeout but it have below response.
What should I pay attention if I want to increase endpoint timeout?
<html>
<body>
<h1>504 Gateway Time-out</h1>
The server didn't respond in time.
</body>
</html>
There are 3 steps to set timeout but it appear fault....
1) Global timeout defined in synapse.properties (EI_HOME\conf\synapse.properties)
synapse.global_timeout_interval=17000000
2) Socket timeout defined in the passthru-http.properties (EI_HOME\conf\passthru-http.properties )
http.socket.timeout=18000000
3) Also set timeout in API.
<?xml version="1.0" encoding="UTF-8"?>
<endpoint name="ep_dsData" xmlns="http://ws.apache.org/ns/synapse">
<http method="post" uri-template="{uri.var.origin.ds}/api/v1/GetData">
<timeout>
<duration>17000000</duration>
<responseAction>fault</responseAction>
</timeout>
</http>
</endpoint>
The following link clearly explains the configurations requried for tuning the timeout variables in WSO2 EI. Please refer it once again.
https://docs.wso2.com/display/EI611/WSO2+Enterprise+Integrator+Best+Practices#WSO2EnterpriseIntegratorBestPractices-Workingwithendpoints
The timeout limit shared in the question is very abnormal, 5 hours.
Remember, the following..
http.socket.timeout > max(Global endpoint timeout,Timeout of individual endpoints).
Also if you have configured a timeout value at the endpoint level, the global timeout value is not taken into consideration for that endpoint. For all the other endpoints, which do not have a timeout value configured, the global value is considered as the timeout value.
I am using wso2 esb4.9 on windows7. The JDK is 7.0.
I want to let esb to retry 5 times when timeout error happens.
ESB log display 5 times retry...
But there is no retry log is printed...
<endpoint name="Sample_First" statistics="enable" >
<address uri="http://localhost/myendpoint" statistics="enable" trace="disable">
<timeout>
<duration>60000</duration>
</timeout>
<markForSuspension>
<errorCodes>101504, 101505</errorCodes>
<retriesBeforeSuspension>5</retriesBeforeSuspension>
<retryDelay>1</retryDelay>
</markForSuspension>
<suspendOnFailure>
<errorCodes>101500, 101501, 101506, 101507, 101508</errorCodes>
<initialDuration>1000</initialDuration>
<progressionFactor>2</progressionFactor>
<maximumDuration>60000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
As I understand you are asking whether ESB tries to connect to the endpoint 4 more times if it gets timed out (fails to connect). This is not the idea of <retriesBeforeSuspension> tag. This integer means ESB marks that endpoint as a SUSPENDED endpoint if 4(as per your configuration) more requests get timed out consecutively. These other requests should be done manually and its not done by ESB automatically. Thats the reason you don't see retry log 5 times.
Hope this helps.
I want to proxy RemoteUserStoreManagerService (exposed on WSO2 IS) over WSO2 ESB.
When I call getUserClaimValuesForClaims operation I get the response. I tested the WSO2 IS (connected to my Active Directory) for performance. I sent requests in 100 threads (each thread with 250ms delay) and it gave me an average response of 250ms (which is ok for me).
So I proxied the getUserClaimValuesForClaims operation using the Transformation proxy and it also worked. But during the performace testing (with the same or smaller load) I have got following errors and not all the messages have returned (on average 1 of 100 messages).
[2014-01-06 19:28:21,047] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:d2b85c03-beaf-409b-bf39-2e8143bd9e0b, Direction: response
[2014-01-06 19:28:38,441] ERROR - SourceHandler I/O error: An established connection was aborted by the software in your host machine
java.io.IOException: An established connection was aborted by the software in your host machine
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:25)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:202)
at sun.nio.ch.IOUtil.read(IOUtil.java:175)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:243)
at org.apache.http.nio.reactor.ssl.SSLIOSession.receiveEncryptedData(SSLIOSession.java:348)
at org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:376)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady
[2014-01-06 19:29:14,051] WARN - TargetHandler http-outgoing-66: Connection time out while in state: REQUEST_DONE
[2014-01-06 19:29:14,061] WARN - EndpointContext Endpoint : AnonymousEndpoint will be marked SUSPENDED as it failed
[2014-01-06 19:29:15,041] WARN - EndpointContext Suspending endpoint : AnonymousEndpoint - last suspend duration was : 30000ms and current suspend duration is : 30000ms - Next retry after : Mon
[2014-01-06 19:29:14,451] WARN - SourceHandler Connection time out after request is read: http-incoming-57
I thing that it says, it timeouts on backend; but I get the response logged in faultSeuence.
I noticed that the problem is caused by the XSLT mediator in proxy implementation, because when I removed the xslt mediators the log is empty. I tried xquery and it was the same. Even the log mediator in outSequence causes this issues.
Here is my final Proxy.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="GetUserProxy" transports="https http" startOnLoad="true" trace="disable">
<target>
<endpoint>
<address uri="https://localhost:9443/services/RemoteUserStoreManagerService.RemoteUserStoreManagerServiceHttpsSoap12Endpoint/"/>
</endpoint>
<inSequence/>
<outSequence>
<log/>
<send/>
</outSequence>
<faultSequence/>
</target>
</proxy>
When I remove the log mediator, the WARN messages disapears from log and ALL response messages are returned to SoapUI.
Could anybody tell me why it behaves this way?
Thank you very much.
David
RemoteUserStoreManagerService is an admin service. Therefore, you need to send Identity Server's user name/password in a basic authentication header or session cookie. I can not see setting of authorization headers in your proxy configuration such as following
<property expression="fn:concat('Basic ', base64Encode('username:password'))" name="Authorization" scope="transport"></property>
More details would be here. Also you need to create a message body to send to the "RemoteUserStoreManagerService" and read the response messages. These must be implemented using ESB configuration. However, you can write an custom ESB mediator to do this also. Sample java code to call this service can be found here. You can find the detail on writing custom mediator from here
We have figured out, that the problem is probably more general and doesn't relate only to WSO2 IS, because we have the same problem when similating the WSO2 IS service as SoapUI mock.
The problem is probably in HTTP-passthru transport in axis configuration, because when we switched to HTTP-NIO the problem disapears and it is even faster.
There is a post about performance tunnig that helped us.
Howevever, I would like to know what transport we should use in production or where the problem is. Because now it seems that we cannot use HTTP-passthru transport for production environment.
Is anyone experiencing this problem?
what are the versions of ESB and IS your working with..?
try to restart the ESB and call the Service again. Do remember call to Identity server is a secure call.