Failover for pooled LDAP connections - java

I am working with a Spring LDAP application for which I did none of the setup of the LDAP workings, but now I need to add a failover feature.
We supply our ContextSource with two space-seperated URLs:
String theseUrls = primaryLdapUrl + " " + secondaryLdapUrl;
environment.put("java.naming.provider.url", theseUrls);
ilc = new InitialLdapContext(environment, null);
If the primary URL is functional, then it connects to that. If not, it connects to the secondary just fine. The connections are then pooled, however I am having trouble figuring out the exact mechanics. But, as it is, due to the pooling if the established connection goes down, the whole application shits the bed.
Is there a way to disable pooling, or create a short timeout for it? I have done some research but can't find exact mechanics that have worked for me (including trying to call setPooled(false)). Ideally, the secondary server is only queried if the first is down. When the first is restored, then it will go back to that.
NOTE: This URL (http://forum.spring.io/forum/spring-projects/data/ldap/34643-switching-ldap-contexts-for-failover) has given me a lot of ideas, but I can't get anything to work.

Related

Finagle service discovery issue

Here I wanted to register to 2 endpoints and send requests to them. You can see this in the code below. I name one env1 and the other env2.
val client = Http.client
.configured(Transport.Options(noDelay = false, reuseAddr = false))
.newService("gexampleapi-env1.localhost.net:8081,gexampleapi-env2.localhost.net:8081")
So far everything is normal. But env1 instance had to be down for some reason(for a few hours' maintenance etc. not sure why.). Under normal circumstances, our expectation is that it continues to send requests through the env2 instance. But this didn't happen. Could not send requests to both servers. Normally it was working correctly, but it didn't work that day for a reason we don't know.
Since the event took place months ago, I only have the following log.
2022-02-15 12:09:40,181 [finagle/netty4-1-3] INFO com.twitter.finagle
FailureAccrualFactory marking connection to "gExampleAPI" as dead.
Remote Address:
Inet(gexampleapi-env1.localhost.net/10.0.0.1:8081,Map())
To solve the problem, we removed gexampleapi-env1.localhost.net:8081 host from the config file. and after restarting it continued to process requests. If you have any ideas about why we may have experienced this problem and how to avoid this next time, I would appreciate it if you could share them.

What causes ch.ethz.ssh2.Connection to have a hang time?

I am currently using ch.ethz.ssh2.Connection to connect to my servers in java. sometimes it hangs on one server.(maybe like 10-15 seconds). I wanted to know what causes this hang time and how to avoid it.
Connection sample
conn = new ch.ethz.ssh2.Connection(serverName);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(user, pass);
logger.info("Connecting to " + server);
if (isAuthenticated == false) {
logger.info(server + " Please check credentials");
}
sess = conn.openSession();
// I am connecting to over 200 servers and closing them. What would be the best practice to loop thru all these servers in the minimal time.
//some servers quickly connects, while some takes some time.
why does this happen?
The main question is: Is it a code problem, a network problem or a server problem.
A code problem can be debugged - unfortunately ch.ethz.ssh2.Connection does not have any logging possibility to detect what is going inside.
May be you should thing about switching the ssh library (or use it for some tests with the problematic servers). From my experience sshj is very useful.
If it is a network problem or a server problem you can check what is going on via Wireshark. If network packets are sent but the response is delayed the problem is not the used client-side code.
My psychic debugging powers tell me that the server is doing a DNS lookup on the IP address of each client which connects. These DNS lookups are either taking a long time to complete, or they're failing entirely. The DNS lookup will block the authentication process until it finishes, successfully or not.
If the server is the OpenSSH server, this behavior is controlled by the sshd config "UseDNS" option.

"Destroying connection that could not be successfully matched"

I have an application that seems to work fine, but if I browse the log files I see a lot of these kind of errors:
2015-06-04 08:23:55,656 WARN [org.jboss.resource.connectionmanager.InternalManagedConnectionPool] [DA366C7824A976BA8D1121A6E9A4F1C1.Node23] Destroying connection that could not be successfully matched: org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener#5d115719[state=NORMAL mc=org.apache.jackrabbit.jca.JCAManagedConnection#3aed875b handles=0 lastUse=1433398630770 permit=false trackByTx=false mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$OnePool#45ccbfb9 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool#53f2e7c xaResource=org.apache.jackrabbit.jca.TransactionBoundXAResource#40518596 txSync=null]
I am very curious what the error "Destroying connection that could not be successfully matched" exactly means. Google doesn't seem to help me too much on this one.
We work with JBoss 4.0.5.GA and JackRabbit 1.4 (I know it's old, but that's the way it is).
Just Googled and got the below link of 4.2 brancode
Based on code, while retrieving connection from pool, first it checks
1. Does it has managed Connection
1a. if that has Managed Connection, it checks it is in good shape to return by doing matching algorithm.
1b. if it found it is not in valid state ( not matched ) . it is destroy the Managed connection and create new connection ( or retrieve another Managed connection ) and return it.
2. if it doesnt found any managed connection, create new connection and return it
And this is Warning message from thier source code
//Match did not succeed but no exception was thrown.
//Either we have the matching strategy wrong or the
//connection died while being checked. We need to
//distinguish these cases, but for now we always
//destroy the connection.
log.warn("Destroying connection that could not be successfully matched: " + cl);
At any case , have you overridden GWConnectionRequestInfo equals method ?
Your application may work fine, but it is not effectively using connection pool, since it is destroying lot of managed connection due to different reason. i would analysis more and find reason behind why it is not matching
Ad per thier comment , you connection may already closed / matching not working due to different reason.

Check reachability of servers in java programmatically

In my application architecture I am having two database servers primary db and secondary db server (Replica server).
In my java code I am making a connection with DB to fetch some data now what I want is I will give the IP addresses of both DB servers in my code and will check which DB server is reachable and will connect with that only. But I am not getting how to implement it, the one way is try to telnet but not a good option because I want to disable the telnet on application server for some reasons.
Is there any other and best way to do this?
Personally, I would just attempt the connection (using standard database classes) and handle the exceptions if the connection fails.
Even if you confirm connectivity initially, nothing prevents a network problem occurring between that test and your actual attempt to use the database.
You can try pinging both hosts and use the one which responds. Here is a sample program.
InetAddress address = InetAddress.getByName("172.16.2.0");
// Try to reach the specified address within the timeout
// periode. If during this periode the address cannot be
// reach then the method returns false.
boolean reachable = address.isReachable(10000);
System.out.println("Is host reachable? " + reachable);
For a more elaborate program, see this Ping program example in Java.

How to create one database connection per user on a Java Servlet application?

I am working on a website using Java Servlets and my research showed me that it is best to keep one database connection per user (rather than have only one connection sitting all the time on the background or connect to the database every time that a transaction needs to be made). I don't know how to accomplish this, however. What I am currently doing is in my Data Access Object class I have a
private static Connection conn;
and I have a HTTPSessionListener - on sessionCreated event I connect to the Database using this static "conn" variable, and on sessionDestroyed event I disconnect the "conn" variable:
...in my "MySessionListener"...
public void sessionCreated(HttpSessionEvent sessionEvent) {
System.out.println("Session created!");
DAO.connect();
}
public void sessionDestroyed(HttpSessionEvent sessionEvent)
{
System.out.println("Session destroyed");
String user = (String) sessionEvent.getSession().getAttribute("userid" );
if (user != null) DAO.signUserOut(user);
DAO.disconnect();
}
Now the problem with this is that:
I am afraid that this way I essentially degrade to only having one connection that everyone shares(instead of a connection per user as I wanted), just that I disconnect from time to time if there are no users. Correct?
If multiple users are online and one closes their session, they will close the connection for everyone until someone else starts a session and creates a new connection for everyone, correct? I cannot test this very well because I am testing it locally on my laptop, with 3 browsers, but even when I close a browser that had my website on, the session doesn't die immediately and I am not sure what exactly is going on. All i know is that sometimes I get an exception saying "No transactions allowed after connection is closed".
Typically this is achieved using connection pool. You can configure it to have specific number of connections available and the pool manages open and closing connections. Your code will only take available connection from the pool and return it when done.
See this (fairly generic) Wikipedia article.
Some well known pools are DBCP and C3P0.
There ate two issues here:
http session timeout
database session connectivity
You seem to be mixing the two session concepts.
HTTP session
You need to further familiarize yourself with client-server http mechanism. Closing the browser does not close the http session. When you close the browser, you have to code into your pages "on close". "On close"?? Absolutely not - there is no such thing as onclose in html/javascript. But there is onunload (as well as onload).
Why isn't there "onclose" in javascript/html? I think the people who invented http/html were paranoid over many contingencies. Perhaps, rightly so. Perhaps, we have to understand the mindset and motivation of html/http invention. So, you have no choice but concoct a chain-reaction of onunload events. ONUNLOAD/ONLOAD are html page events, not browser events. The whole html mechanism is page driven not browser driven. Therefore, when you close the browser, it would trigger onunload event for every tab on the browser.
You will have to make use of page onunload to inform the server that the user has intention to close the session. Otherwise, the server would have to depend on session timeout value to end the session. What if the user closes the browser on one of your pages on which you did not code in the onunload event? Too bad - that is why I wrote "concoct a chain reaction of onunload" on every page. Which is very tiresome and bothersome.
Sometimes. especially for highly mathematical servlets, the server takes a long time to respond. Then the client page would need an indication to differentiate between a server still processing a response vs the server has gone dead - session timeout enforced on the browser. e.g. http://support.microsoft.com/kb/813827 (How to change the default keep-alive time-out value in Internet Explorer).
May be, the server should poke at the browser page once a while to see if the browser session is still alive. Nope. Http is client pull technology. The server cannot push responses to the client. Why not? Why so silly? You have to read up on the whole http/html mindset/paranoia to understand. The browser can poke at the server but not vice versa.
Therefore AJAX and comet was invented/concocted. To simulate, to pretend on server push. With ajax you have some means for the server to psuedo-poke at the client. And that is what you have to do -- use ajax e.g. jquery or gwt. I prefer gwt.
What if the client computer had a power failure or the OS hit a blue screen, or the browser process was abruptly terminated? There would be no opportunity to trigger the onunload event for any of the pages.
Database connection session
Alex's answer hit the nail -- connection pooling. However, there are situations when I needed to have a database connection per session. Hmmm ... how do I do it? Yes, I store the connection as the session attribute. Therefore, there would be as many db connections as there are sessions. Which, essentially has the same effect as what you are currently doing.
Developing stateful web applications for a stateless(despite the cookies) and presumed unstable client requires cautiousness. What if the user presses the back button after logging out? The backed/prev page might contain an action that causes the server to use a db connection, which was already closed by the log-out page before the user pressed the back button. Or, it may be the server timed out due to client not having poked at the server for a duration longer than the session keep-alive timeout value.
Therefore, before developing a "multi-tier" client-server app, you have to sit down and chart out all your contingencies, with a good understanding of the mindset/paranoia of http technology. You need to infect yourself with http's compulsive obsessions in order to design your applications.

Categories

Resources