MySql ReplicationDriver - Tomcat won't start when slave is down - java

Here is my tomcat context.xml file with my config for MySql (1 master / 1 read replica).
<Resource auth="Container"
driverClassName="com.mysql.jdbc.ReplicationDriver"
defaultAutoCommit="false"
initialSize="3"
logAbandoned="false"
maxActive="200"
maxIdle="10"
maxWait="10000"
name="jdbc/powerptc"
removeAbandoned="true"
testOnBorrow="true"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
username="username"
password="password"
url="jdbc:mysql:replication://localhost:3306,2.2.2.222:3306/mydb?autoReconnect=true&allowSlaveDownConnections=true&readFromMasterWhenNoSlaves=true&connectTimeout=15000&socketTimeout=15000"
validationQuery="/* ping */ SELECT 1"/>
My issue is when the slave (2.2.2.222) is down, I tomcat won't start. I was hoping to configure it so that tomcat would still start with a slave down, and just use the master for all queries is this possible?

Related

Reading tomcat server.xml in junit test case

I am using java 7, and tomcat 7. I am writing few tests for my application in jUnit which uses tomcat/conf/server.xml for jndi. Here is the maven suggest folder structure.
src
|___test
|___java
| |___Testcase.java
|___resources
|___conf
|___server.xml
My sample server.xml would look like this,
<Resource name="jdbc/junit_db"
type="javax.sql.DataSource"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/junit_db?zeroDateTimeBehavior=round&autoReconnect=true&dumpQueriesOnException=true"
username="root"
password="password"
maxIdle="0"
minIdle="0"
initialSize="1"
maxWait="5000"
maxActive="50"
loginTimeout="1000"
minEvictableIdleTimeMillis="2000"
timeBetweenEvictionRunsMillis="5000"
validationQuery="SELECT 1"
testOnBorrow="true"
testOnReturn="true"
testWhileIdle="false"
logAbandoned="true"
removeAbandoned="true"
poolPreparedStatements="true"
maxOpenPreparedStatements="10000"
accessToUnderlyingConnectionAllowed="false"
defaultAutoCommit="false"
defaultReadOnly="false"
defaultTransactionIsolation="4"/>
<Resource name="jdbc/junit_hive_db"
type="javax.sql.DataSource"
factory="com.office.hive.HiveDataSourceFactory"
driverClassName="org.apache.hive.jdbc.HiveDriver"
url="jdbc:hive2://localhost:10000/default?zeroDateTimeBehavior=round"
username=""
password="" />
I want to load this server.xml into the IntialContext before running jUnit test cases. How to achieve this?
Followed this link, it has solution for loading jndi into initialcontext manually.
http://www.alexecollins.com/tomcat-context-junit-rule/
Give TomcatJNDI a try. When fed with Tomcat's configuration files it will deliver all JNDI based objects that are declared in these files as soon as they are looked up. The code to achieve this is for example
TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processServerXml(serverXmlFile)
tomcatJNDI.processContextXml(contextXmlFile);
tomcatJNDI.start();
Then you can lookup the objects as you are used to:
DataSource ds = (DataSource) InitialContext.doLookup("java:comp/env/path/to/datasource")
More about TomcatJNDI can be found here.

Tomcat need to restart after database restart

I have a webapp deployed in Tomcat 7. There I cave configured my database pool as given below.
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
<Resource type="javax.sql.DataSource"
name="jdbc/TEST"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testdb?zeroDateTimeBehavior=convertToNull"
username="test"
password="test"
initialSize="10"
maxActive="100"
maxIdle="50"
minIdle="10"/>
This configuration works fine.But I want to configure my database pool to reconnect data database server automatically when a database server down for sometime and started again.
Try to add
?autoReconnect=true
in your url.
I found an answer for this problem. Below configuration done the job.
<Resource type="javax.sql.DataSource"
name="jdbc/TEST"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testdb?zeroDateTimeBehavior=convertToNull"
validationQuery="select 1"
validationInterval="30000"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
username="test"
password="test"
initialSize="10"
maxActive="100"
maxIdle="50"
minIdle="10"/>

How to get PoolingDataSource from Tomcat's JNDI

If I deploy a web app to Tomcat, and have code like this:
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("jdbc/myDB");
How can I specify for this DataSource to be a PoolingDataSource? How do I configure the pool (GenericObjectPool) to inject the PoolingDataSource with?
Or, is this the default behavior of Tomcat's JNDI implementation? Thanks in advance!
Just configure the connection pool settings (maxActive, maxWait, maxIdle, ...).
Tomcat comes with the apache commons-dbcp library. It is repackaged as $CATALINA_HOME/lib/tomcat-dbcp.jar.
Take a look at the tomcat doc for details: http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html#Database_Connection_Pool_%28DBCP%29_Configurations
<Context>
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest"/>
</Context>
The JDBC Connection Pool org.apache.tomcat.jdbc.pool
is a replacement or an alternative to the commons-dbcp
connection pool.
Add to the server.xml file in the GlobalNamingResources section something like the next:
<Resource name="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100"
minIdle="10"
maxWait="10000"
initialSize="10"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
username="root"
password="password"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mysql"/>
Add the JDBC driver JAR into the Tomcat lib directory.
Add in your context.xml:
<ResourceLink global="jdbc/TestDB" name="jdbc/TestDB"
type="javax.sql.DataSource"/>
See more in The Tomcat JDBC Connection Pool.

When is the tag I added in context.xml gets read?

In the context.xml of Tomcat I added the following tag :
<Resource name="jdbc/MyDatasource" auth="Container" type="javax.sql.DataSource"
driverClassName="org.apache.derby.jdbc.ClientDriver"
url="jdbc:derby://localhost:1527/my_database;create=true"
username="me" password="me"
maxActive="20" maxIdle="10" maxWait="-1" />
When does the following tag gets read ? Is it read when i start the server ?
This configuration is read when the application is deployed. If you have auto-deploy enabled, Tomcat will deploy your webapp during startup.

Mysql not reconnecting with JNDI Tomcat 6

I am using JNDI with Tomcat6 to manage Mysql connections, my Catalina/domain.com/ROOT.xml has:
<Resource name="jdbc/db" auth="Container" type="javax.sql.DataSource"
username="db1" password="somepass" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/db?autoReconnect=true" maxActive="15" maxIdle="3"
maxWait="5000" removeAbandoned="true" removeAbandonedTimeout="20" />
I though autoReconnect will do the job reconnecting to database but it does not, after about 8 hours of inactivity my app spits out lost connection to database errors. Any ideas?
Thanks, Fedor
Dont use autoReconnect. There are problems with it and it's been deprecated. For example, you could have a disconnect/reconnect event happen while a thread is using the connection. I would instead have your connection pool test connections with testOnBorrow before passing them to the app. Here is an example:
<Resource name="jdbc/db"
auth="Container"
type="javax.sql.DataSource"
username="db1"
password="somepass"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/db"
maxActive="15"
maxIdle="3"
maxWait="5000"
removeAbandoned="true"
removeAbandonedTimeout="20"
logAbandoned="true"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
validationQuery="select 1"
minEvictableIdleTimeMillis="3600000"
timeBetweenEvictionRunsMillis="1800000"
numTestsPerEvictionRun="10"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
/>

Categories

Resources