improve dynamic config

This commit is contained in:
wenshao
2013-05-26 18:52:21 +08:00
parent 32e3ed98e6
commit f42f6fdba3
14 changed files with 424 additions and 40 deletions
@@ -57,12 +57,18 @@ import com.alibaba.druid.proxy.jdbc.StatementProxy;
/**
* @author wenshao<szujobs@hotmail.com>
*/
public interface Filter {
public interface Filter extends Wrapper {
void init(DataSourceProxy dataSource);
void destory();
void configFromProperties(Properties properties);
boolean isWrapperFor(java.lang.Class<?> iface);
<T> T unwrap(java.lang.Class<T> iface);
ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException;
StatementProxy connection_createStatement(FilterChain chain, ConnectionProxy connection) throws SQLException;
@@ -1277,6 +1283,7 @@ public interface Filter {
void clob_truncate(FilterChain chain, ClobProxy wrapper, long len) throws SQLException;
void dataSource_releaseConnection(FilterChain chain, DruidPooledConnection connection) throws SQLException;
DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException;
DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis)
throws SQLException;
}
@@ -67,6 +67,23 @@ public abstract class FilterAdapter extends NotificationBroadcasterSupport imple
public void destory() {
}
public void configFromProperties(Properties properties) {
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return iface == this.getClass();
}
@SuppressWarnings("unchecked")
public <T> T unwrap(Class<T> iface) {
if (iface == this.getClass()) {
return (T) this;
}
return null;
}
@Override
public Array callableStatement_getArray(FilterChain chain, CallableStatementProxy statement, int parameterIndex)
@@ -412,7 +412,7 @@ public abstract class LogFilter extends FilterEventAdapter implements LogFilterM
@Override
protected void statementExecuteAfter(StatementProxy statement, String sql, boolean firstResult) {
logExecutableSql(statement, sql);
if (statementExecuteAfterLogEnable && isStatementLogEnabled()) {
statement.setLastExecuteTimeNano();
double nanos = statement.getLastExecuteTimeNano();
@@ -436,9 +436,9 @@ public abstract class LogFilter extends FilterEventAdapter implements LogFilterM
} else {
sql = statement.getBatchSql();
}
logExecutableSql(statement, sql);
if (statementExecuteBatchAfterLogEnable && isStatementLogEnabled()) {
statement.setLastExecuteTimeNano();
double nanos = statement.getLastExecuteTimeNano();
@@ -460,7 +460,7 @@ public abstract class LogFilter extends FilterEventAdapter implements LogFilterM
@Override
protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) {
logExecutableSql(statement, sql);
if (statementExecuteQueryAfterLogEnable && isStatementLogEnabled()) {
statement.setLastExecuteTimeNano();
double nanos = statement.getLastExecuteTimeNano();
@@ -810,4 +810,18 @@ public abstract class LogFilter extends FilterEventAdapter implements LogFilterM
chain.preparedStatement_clearParameters(statement);
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return iface == this.getClass() || iface == LogFilter.class;
}
@SuppressWarnings("unchecked")
@Override
public <T> T unwrap(Class<T> iface) {
if (iface == this.getClass() || iface == LogFilter.class) {
return (T) this;
}
return null;
}
}
@@ -16,7 +16,21 @@
package com.alibaba.druid.filter.stat;
public class MergeStatFilter extends StatFilter {
public MergeStatFilter() {
super.setMergeSql(true);
}
public MergeStatFilter(){
super.setMergeSql(true);
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return iface == MergeStatFilter.class || iface == StatFilter.class;
}
@SuppressWarnings("unchecked")
public <T> T unwrap(Class<T> iface) {
if (iface == MergeStatFilter.class || iface == StatFilter.class) {
return (T) this;
}
return null;
}
}
@@ -156,11 +156,11 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
this.dbType = dataSource.getDbType();
}
initFromProperties(dataSource.getConnectProperties());
initFromProperties(System.getProperties());
configFromProperties(dataSource.getConnectProperties());
configFromProperties(System.getProperties());
}
private void initFromProperties(Properties properties) {
public void configFromProperties(Properties properties) {
if (properties == null) {
return;
}
@@ -46,6 +46,7 @@ import javax.sql.ConnectionEventListener;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.PooledConnection;
import com.alibaba.druid.Constants;
import com.alibaba.druid.TransactionTimeoutException;
import com.alibaba.druid.VERSION;
import com.alibaba.druid.filter.AutoLoad;
@@ -144,8 +145,12 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
public DruidDataSource(boolean fairLock){
super(fairLock);
configFromPropety(System.getProperties());
}
public void configFromPropety(Properties properties) {
{
String property = System.getProperty("druid.testWhileIdle");
String property = properties.getProperty("druid.testWhileIdle");
if ("true".equals(property)) {
this.setTestWhileIdle(true);
} else if ("false".equals(property)) {
@@ -153,7 +158,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
{
String property = System.getProperty("druid.testOnBorrow");
String property = properties.getProperty("druid.testOnBorrow");
if ("true".equals(property)) {
this.setTestOnBorrow(true);
} else if ("false".equals(property)) {
@@ -161,13 +166,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
{
String property = System.getProperty("druid.validationQuery");
String property = properties.getProperty("druid.validationQuery");
if (property != null && property.length() > 0) {
this.setValidationQuery(property);
}
}
{
String property = System.getProperty("druid.useGloalDataSourceStat");
String property = properties.getProperty("druid.useGloalDataSourceStat");
if ("true".equals(property)) {
this.setUseGloalDataSourceStat(true);
} else if ("false".equals(property)) {
@@ -175,7 +180,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
{
String property = System.getProperty("druid.filters");
String property = properties.getProperty("druid.filters");
if (property != null && property.length() > 0) {
try {
@@ -186,7 +191,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
{
String property = System.getProperty("druid.timeBetweenLogStatsMillis");
String property = properties.getProperty("druid.timeBetweenLogStatsMillis");
if (property != null && property.length() > 0) {
try {
long value = Long.parseLong(property);
@@ -196,6 +201,19 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
}
{
String property = properties.getProperty(Constants.DRUID_STAT_SQL_MAX_SIZE);
if (property != null && property.length() > 0) {
try {
int value = Integer.parseInt(property);
if (dataSourceStat != null) {
dataSourceStat.setMaxSqlSize(value);
}
} catch (NumberFormatException e) {
LOG.error("illegal property '" + Constants.DRUID_STAT_SQL_MAX_SIZE + "'", e);
}
}
}
}
public boolean isUseGloalDataSourceStat() {
@@ -371,15 +389,42 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
@SuppressWarnings("rawtypes")
public void setConnectProperties(Properties properties) {
if (properties == null) {
properties = new Properties();
}
if (inited) {
if (!this.connectProperties.equals(properties)) {
boolean equals;
if (properties.size() == this.connectProperties.size()) {
equals = true;
for (Map.Entry entry : properties.entrySet()) {
Object value = this.connectProperties.get(entry.getKey());
Object entryValue = entry.getValue();
if (value == null && entryValue != null) {
equals = false;
break;
}
if (!value.equals(entry.getValue())) {
equals = false;
break;
}
}
} else {
equals = false;
}
if (!equals) {
if (inited && LOG.isInfoEnabled()) {
LOG.info("connectProperties changed : " + this.connectProperties + " -> " + properties);
}
configFromPropety(properties);
for (Filter filter : this.filters) {
filter.configFromProperties(properties);
}
}
this.connectProperties = properties;
@@ -499,7 +544,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
dataSourceStat.setDbType(this.getDbType());
}
} else {
dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType);
dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType, this.connectProperties);
}
connections = new DruidConnectionHolder[maxActive];
@@ -2188,4 +2233,26 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
public Lock getLock() {
return lock;
}
@Override
public boolean isWrapperFor(Class<?> iface) {
for (Filter filter : this.filters) {
if (filter.isWrapperFor(iface)) {
return true;
}
}
return super.isWrapperFor(iface);
}
@SuppressWarnings("unchecked")
public <T> T unwrap(Class<T> iface) {
for (Filter filter : this.filters) {
if (filter.isWrapperFor(iface)) {
return (T) filter;
}
}
return super.unwrap(iface);
}
}
@@ -585,12 +585,16 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
}
String varName = x.getName();
if (x.isGlobal()) {
print("@@global.");
} else {
String varName = x.getName();
if ((!varName.startsWith("@")) && (!varName.equals("?")) && (!varName.startsWith("#"))
&& (!varName.startsWith("$"))) {
if ((!varName.startsWith("@")) // /
&& (!varName.equals("?")) //
&& (!varName.startsWith("#")) //
&& (!varName.startsWith("$")) //
&& (!varName.startsWith(":"))
) {
print("@@");
}
}
@@ -3006,7 +3010,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print(' ');
x.getValues().accept(this);
}
if (x.getDataDirectory() != null) {
incrementIndent();
println();
@@ -3021,7 +3025,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
x.getIndexDirectory().accept(this);
decrementIndent();
}
return false;
}
@@ -39,7 +39,6 @@ import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.Histogram;
import com.alibaba.druid.util.LRUCache;
public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
@@ -53,11 +52,13 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
private final JdbcResultSetStat resultSetStat = new JdbcResultSetStat();
private final JdbcStatementStat statementStat = new JdbcStatementStat();
private int maxSize = 1000 * 1;
private int maxSqlSize = 1000 * 1;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final LinkedHashMap<String, JdbcSqlStat> sqlStatMap;
private final AtomicLong skipSqlCount = new AtomicLong();
private final Histogram connectionHoldHistogram = new Histogram(new long[] { //
//
1, 10, 100, 1000, 10 * 1000, //
@@ -100,6 +101,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
this(name, url, dbType, null);
}
@SuppressWarnings("serial")
public JdbcDataSourceStat(String name, String url, String dbType, Properties connectProperties){
this.name = name;
this.url = url;
@@ -114,14 +116,36 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
if (arg != null) {
try {
maxSize = Integer.parseInt(arg.toString());
maxSqlSize = Integer.parseInt(arg.toString());
} catch (NumberFormatException ex) {
LOG.error("maxSize parse error", ex);
}
}
}
sqlStatMap = new LRUCache<String, JdbcSqlStat>(maxSize, 16, 0.75f, false);
sqlStatMap = new LinkedHashMap<String, JdbcSqlStat>(16, 0.75f, false) {
protected boolean removeEldestEntry(Map.Entry<String, JdbcSqlStat> eldest) {
boolean remove = (size() > maxSqlSize);
if (remove) {
JdbcSqlStat sqlStat = eldest.getValue();
if (sqlStat.getRunningCount() > 0 || sqlStat.getExecuteCount() > 0) {
skipSqlCount.incrementAndGet();
}
}
return remove;
}
};
}
public int getMaxSqlSize() {
return this.maxSqlSize;
}
public void setMaxSqlSize(int value) {
this.maxSqlSize = value;
}
public String getDbType() {
@@ -131,6 +155,14 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
public void setDbType(String dbType) {
this.dbType = dbType;
}
public long getSkipSqlCount() {
return skipSqlCount.get();
}
public long getSkipSqlCountAndReset() {
return skipSqlCount.getAndSet(0);
}
public void reset() {
blobOpenCount.set(0);
@@ -140,6 +172,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
statementStat.reset();
resultSetStat.reset();
connectionHoldHistogram.reset();
skipSqlCount.set(0);
lock.writeLock().lock();
try {
@@ -286,7 +319,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
} finally {
lock.writeLock().unlock();
}
List<JdbcSqlStatValue> values = new ArrayList<JdbcSqlStatValue>(stats.size());
for (int i = 0; i < stats.size(); ++i) {
JdbcSqlStat stat = stats.get(i);
@@ -375,7 +408,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
public long getClobOpenCount() {
return clobOpenCount.get();
}
public long getClobOpenCountAndReset() {
return clobOpenCount.getAndSet(0);
}
@@ -387,7 +420,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
public long getBlobOpenCount() {
return blobOpenCount.get();
}
public long getBlobOpenCountAndReset() {
return blobOpenCount.getAndSet(0);
}