springboot项目中,用atomikos做的多数据源配置,某一个数据库,白天的时候访问非常慢,深夜访问就正常?

项目连接了3个数据库,分别是 base1,base2,base3;
base1,base2白天晚上访问都正常;
base3,白天访问大部分都是超时,偶尔能通,还非常慢,到了晚上就可以正常访问了;
三个数据库数据结构,接口配置一模一样,只是用来区分不同的国家而已;
因为做了实时大屏看板,所以会频繁的请求该项目,并且会不停的切换数据源;会不会是数据源的通用配置有点小了?

数据源的通用配置如下:

    <bean id="dataSourceConfig" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close" abstract="true">

<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>

<property name="poolSize" value="10"/>

<property name="maxPoolSize" value="20"/>

<property name="minPoolSize" value="5"/>

<property name="maxIdleTime" value="5"/>

<property name="maxLifetime" value="60"/>

<property name="borrowConnectionTimeout" value="60"/>

<property name="testQuery" value="SELECT 'x' from dual"/>

<property name="isLoad" value="${datasource.loadDB.haier}" />

</bean>

AtomikosDataSourceBean代码如下

/**

* Copyright (C) 2000-2013 Atomikos <info@atomikos.com>

*

* This code ("Atomikos TransactionsEssentials"), by itself,

* is being distributed under the

* Apache License, Version 2.0 ("License"), a copy of which may be found at

* http://www.atomikos.com/licenses/apache-license-2.0.txt .

* You may not use this file except in compliance with the License.

*

* While the License grants certain patent license rights,

* those patent license rights only extend to the use of

* Atomikos TransactionsEssentials by itself.

*

* This code (Atomikos TransactionsEssentials) contains certain interfaces

* in package (namespace) com.atomikos.icatch

* (including com.atomikos.icatch.Participant) which, if implemented, may

* infringe one or more patents held by Atomikos.

* It should be appreciated that you may NOT implement such interfaces;

* licensing to implement these interfaces must be obtained separately from Atomikos.

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

*/

package com.atomikos.jdbc;

import java.util.Enumeration;

import java.util.HashMap;

import java.util.Map;

import java.util.Properties;

import javax.sql.XADataSource;

import com.atomikos.beans.PropertyUtils;

import com.atomikos.datasource.RecoverableResource;

import com.atomikos.datasource.xa.jdbc.JdbcTransactionalResource;

import com.atomikos.icatch.system.Configuration;

import com.atomikos.logging.Logger;

import com.atomikos.logging.LoggerFactory;

import com.atomikos.util.ClassLoadingHelper;

/**

* The preferred class for using Atomikos connection pooling. Use an instance of

* this class if you want to use Atomikos JTA-enabled connection pooling. All

* you need to do is construct an instance and set the required properties as

* outlined below. The resulting bean will automatically register with the

* transaction service (for recovery) and take part in active transactions.

* All SQL done over connections (gotten from this class) will participate in JTA transactions.

*/

public class AtomikosDataSourceBean

extends AbstractDataSourceBean

{

private static final Logger LOGGER = LoggerFactory.createLogger(AtomikosDataSourceBean.class);

private static final long serialVersionUID = 1L;

private Properties xaProperties = null;

private String xaDataSourceClassName;

private transient XADataSource xaDataSource;

public AtomikosDataSourceBean()

{

this.xaProperties = new Properties();

}

protected String printXaProperties()

{

StringBuffer ret = new StringBuffer();

if ( xaProperties != null ) {

Enumeration it = xaProperties.propertyNames();

ret.append ( "[" );

boolean first = true;

while ( it.hasMoreElements() ) {

if ( ! first ) ret.append ( "," );

String name = ( String ) it.nextElement();

String value = xaProperties.getProperty( name);

ret.append ( name ); ret.append ( "=" ); ret.append ( value );

first = false;

}

ret.append ( "]" );

}

return ret.toString();

}

/**

* Gets the properties used to

* configure the XADataSource.

*/

public Properties getXaProperties()

{

return xaProperties;

}

/**

* Sets the properties (name,value pairs) used to

* configure the XADataSource. Required, unless you call setXaDataSource directly.

*

* @param xaProperties

*

*

*/

public void setXaProperties ( Properties xaProperties )

{

this.xaProperties = xaProperties;

Map<String,String> db = new HashMap<String,String>();

db.put("url", xaProperties.getProperty("URL"));

db.put("user", xaProperties.getProperty("user"));

db.put("password", xaProperties.getProperty("password"));

//将子类的数据库信息传给父类使用

super.dbInfo = db;

}

/**

* Get the XADataSource class name.

*/

public String getXaDataSourceClassName()

{

return xaDataSourceClassName;

}

/**

* Sets the fully qualified underlying XADataSource class name. Required, unless you

* call setXaDataSource directly.

*

* @param xaDataSourceClassName

*/

public void setXaDataSourceClassName ( String xaDataSourceClassName )

{

this.xaDataSourceClassName = xaDataSourceClassName;

}

/**

* Gets the configured XADataSource (if any).

* @return The instance, or null if none.

*/

public XADataSource getXaDataSource()

{

return xaDataSource;

}

/**

* Sets the XADataSource directly - instead of providing the xaDataSourceClassName and xaProperties.

* @param xaDataSource

*/

public void setXaDataSource(XADataSource xaDataSource)

{

this.xaDataSource = xaDataSource;

}

protected com.atomikos.datasource.pool.ConnectionFactory doInit() throws Exception

{

if (xaDataSource == null)

{

if (xaDataSourceClassName == null)

throwAtomikosSQLException("Property 'xaDataSourceClassName' cannot be null");

if (xaProperties == null)

throwAtomikosSQLException("Property 'xaProperties' cannot be null");

}

if ( LOGGER.isInfoEnabled() ) LOGGER.logInfo(

this + ": initializing with [" +

" xaDataSourceClassName=" + xaDataSourceClassName + "," +

" uniqueResourceName=" + getUniqueResourceName() + "," +

" maxPoolSize=" + getMaxPoolSize() + "," +

" minPoolSize=" + getMinPoolSize() + "," +

" borrowConnectionTimeout=" + getBorrowConnectionTimeout() + "," +

" maxIdleTime=" + getMaxIdleTime() + "," +

" reapTimeout=" + getReapTimeout() + "," +

" maintenanceInterval=" + getMaintenanceInterval() + "," +

" testQuery=" + getTestQuery() + "," +

" xaProperties=" + printXaProperties() + "," +

" loginTimeout=" + getLoginTimeout() + "," +

" maxLifetime=" + getMaxLifetime() +

"]"

);

if (xaDataSource == null)

{

Class xadsClass = null;

try {

xadsClass = ClassLoadingHelper.loadClass ( getXaDataSourceClassName() );

} catch ( ClassNotFoundException nf ) {

AtomikosSQLException.throwAtomikosSQLException ( "The class '" + getXaDataSourceClassName() +

"' specified by property 'xaDataSourceClassName' could not be found in the classpath. Please make sure the spelling is correct, and that the required jar(s) are in the classpath." , nf );

}

Object driver = xadsClass.newInstance();

if ( ! ( driver instanceof XADataSource ) ) {

AtomikosSQLException.throwAtomikosSQLException (

"The class '" + getXaDataSourceClassName() +

"' specified by property 'xaDataSourceClassName' does not implement the required interface javax.jdbc.XADataSource. Please make sure the spelling is correct, and check your JDBC driver vendor's documentation."

);

}

xaDataSource = (XADataSource) driver;

xaDataSource.setLoginTimeout ( getLoginTimeout() );

xaDataSource.setLogWriter ( getLogWriter() );

PropertyUtils.setProperties(xaDataSource, xaProperties );

}

JdbcTransactionalResource tr = new JdbcTransactionalResource(getUniqueResourceName() , xaDataSource);

com.atomikos.datasource.pool.ConnectionFactory cf = new com.atomikos.jdbc.AtomikosXAConnectionFactory(xaDataSource, tr, this);

Configuration.addResource ( tr );

return cf;

}

protected void doClose()

{

RecoverableResource res = Configuration.getResource ( getUniqueResourceName() );

if ( res != null ) {

Configuration.removeResource ( getUniqueResourceName() );

//fix for case 26005

res.close();

}

}

public String toString()

{

String ret = "AtomikosDataSoureBean";

String name = getUniqueResourceName();

if ( name != null ) {

ret = ret + " '" + name + "'";

}

return ret;

}

protected boolean isAssignableFromWrappedVendorClass(Class<?> iface) {

boolean ret = false;

if (xaDataSource != null ) {

ret = iface.isAssignableFrom(xaDataSource.getClass());

}

return ret;

}

@Override

protected Object unwrapVendorInstance() {

return xaDataSource;

}

}

AbstractDataSourceBean代码如下

/**

* Copyright (C) 2000-2010 Atomikos <info@atomikos.com>

*

* This code ("Atomikos TransactionsEssentials"), by itself,

* is being distributed under the

* Apache License, Version 2.0 ("License"), a copy of which may be found at

* http://www.atomikos.com/licenses/apache-license-2.0.txt .

* You may not use this file except in compliance with the License.

*

* While the License grants certain patent license rights,

* those patent license rights only extend to the use of

* Atomikos TransactionsEssentials by itself.

*

* This code (Atomikos TransactionsEssentials) contains certain interfaces

* in package (namespace) com.atomikos.icatch

* (including com.atomikos.icatch.Participant) which, if implemented, may

* infringe one or more patents held by Atomikos.

* It should be appreciated that you may NOT implement such interfaces;

* licensing to implement these interfaces must be obtained separately from Atomikos.

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

*/

package com.atomikos.jdbc;

import java.io.PrintWriter;

import java.io.Serializable;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.SQLFeatureNotSupportedException;

import java.util.Map;

import javax.naming.NameNotFoundException;

import javax.naming.NamingException;

import javax.naming.Reference;

import javax.naming.Referenceable;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;

import com.atomikos.datasource.pool.ConnectionFactory;

import com.atomikos.datasource.pool.ConnectionPool;

import com.atomikos.datasource.pool.ConnectionPoolException;

import com.atomikos.datasource.pool.ConnectionPoolProperties;

import com.atomikos.datasource.pool.CreateConnectionException;

import com.atomikos.datasource.pool.PoolExhaustedException;

import com.atomikos.icatch.HeuristicMessage;

import com.atomikos.icatch.StringHeuristicMessage;

import com.atomikos.logging.Logger;

import com.atomikos.logging.LoggerFactory;

import com.atomikos.util.IntraVmObjectFactory;

import com.atomikos.util.IntraVmObjectRegistry;

/**

*

*

* Abstract data source bean with generic functionality.

*

*

*/

public abstract class AbstractDataSourceBean

implements HeuristicDataSource, ConnectionPoolProperties, Referenceable, Serializable

{

private static final Logger LOGGER = LoggerFactory.createLogger(AbstractDataSourceBean.class);

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractDataSourceBean.class);

static final int DEFAULT_ISOLATION_LEVEL_UNSET = -1;

static final int DEFAULT_POOL_SIZE = 1;

private int minPoolSize = DEFAULT_POOL_SIZE;

private int maxPoolSize = DEFAULT_POOL_SIZE;

private int borrowConnectionTimeout = 30;

private int reapTimeout = 0;

private int maxIdleTime = 60;

private String testQuery;

private int maintenanceInterval = 60;

private int loginTimeout;

private transient ConnectionPool connectionPool;

private transient PrintWriter logWriter;

private String resourceName;

protected Map<String,String> dbInfo;

private String isLoad;//记录该数据库是否需要加载

private int defaultIsolationLevel = DEFAULT_ISOLATION_LEVEL_UNSET;

private int maxLifetime;

protected void throwAtomikosSQLException ( String msg ) throws AtomikosSQLException

{

throwAtomikosSQLException ( msg , null );

}

protected void throwAtomikosSQLException ( String msg , Throwable cause ) throws AtomikosSQLException

{

AtomikosSQLException.throwAtomikosSQLException ( msg , cause );

}

/**

* Gets the minimum size of the pool.

*/

public int getMinPoolSize() {

return minPoolSize;

}

/**

* Sets the minimum pool size. The amount of pooled connections won't go

* below that value. The pool will open this amount of connections during

* initialization. Optional, defaults to 1.

*

* @param minPoolSize

*/

public void setMinPoolSize(int minPoolSize) {

this.minPoolSize = minPoolSize;

}

/**

* Get the maximum pool size.

*/

public int getMaxPoolSize() {

return maxPoolSize;

}

/**

* Sets the maximum pool size. The amount of pooled connections won't go

* above this value. Optional, defaults to 1.

*

* @param maxPoolSize

*/

public void setMaxPoolSize(int maxPoolSize) {

this.maxPoolSize = maxPoolSize;

}

/**

* Sets both the minimal and maximal pool size.

* Required if the maxPoolSize is not set. Overrides any minPoolSize

* or maxPoolSize settings you might have configured before!

*/

public void setPoolSize(int poolSize) {

this.minPoolSize = poolSize;

this.maxPoolSize = poolSize;

}

/**

* Get the maximum amount of time in seconds the pool will block

* waiting for a connection to become available in the pool when it

* is empty.

*/

public int getBorrowConnectionTimeout() {

return borrowConnectionTimeout;

}

/**

* Sets the maximum amount of time in seconds the pool will block

* waiting for a connection to become available in the pool when it

* is empty. Optional.

*

* @param borrowConnectionTimeout The time in seconds. Zero or negative means no waiting at all.

* Defaults to 30 seconds.

*/

public void setBorrowConnectionTimeout(int borrowConnectionTimeout) {

this.borrowConnectionTimeout = borrowConnectionTimeout;

}

/**

* Get the amount of time in seconds the connection pool will allow a connection

* to be borrowed before claiming it back.

*/

public int getReapTimeout() {

return reapTimeout;

}

/**

* Sets the amount of time (in seconds) that the connection pool will allow a connection

* to be in use, before claiming it back. Optional.

*

* @param reapTimeout The timeout in seconds. Zero means unlimited. Note that this value is

* only an indication; the pool will check regularly as indicated by the maintenanceInteval property.

* Default is 0 (no timeout).

*/

public void setReapTimeout(int reapTimeout) {

this.reapTimeout = reapTimeout;

}

/**

* Sets the maintenance interval for the pool maintenance thread.

* Optional.

*

* @param maintenanceInterval The interval in seconds. If not set or not positive then the pool's default (60 secs) will be used.

*/

public void setMaintenanceInterval(int maintenanceInterval) {

this.maintenanceInterval = maintenanceInterval;

}

/**

* Gets the maintenance interval as set.

*/

public int getMaintenanceInterval() {

return this.maintenanceInterval;

}

/**

* Gets the maximum amount of time in seconds a connection can stay in the pool

* before being eligible for being closed during pool shrinking.

*/

public int getMaxIdleTime() {

return maxIdleTime;

}

/**

* Sets the maximum amount of seconds that unused excess connections should stay in the pool. Optional.

*

* Note: excess connections are connections that are created above the minPoolSize limit.

*

* @param maxIdleTime The preferred idle time for unused excess connections. Note that this value is

* only an indication; the pool will check regularly as indicated by the maintenanceInteval property.

* The default is 60 seconds.

*/

public void setMaxIdleTime(int maxIdleTime) {

this.maxIdleTime = maxIdleTime;

}

/**

* Sets the maximum amount of seconds that a connection is kept in the pool before

* it is destroyed automatically. Optional, defaults to 0 (no limit).

* @param maxLifetime

*/

public void setMaxLifetime(int maxLifetime) {

this.maxLifetime = maxLifetime;

}

/**

* Gets the maximum lifetime in seconds.

*

*/

public int getMaxLifetime() {

return maxLifetime;

}

/**

* Gets the SQL query used to test a connection before returning it.

*/

public String getTestQuery() {

return testQuery;

}

/**

* Sets the SQL query or statement used to validate a connection before returning it. Optional.

*

* @param testQuery - The SQL query or statement to validate the connection with. Note that

* although you can specify updates here, these will NOT be part of any JTA transaction!

*/

public void setTestQuery(String testQuery) {

this.testQuery = testQuery;

}

public int poolAvailableSize() {

return connectionPool.availableSize();

}

public int poolTotalSize() {

return connectionPool.totalSize();

}

public PrintWriter getLogWriter() throws SQLException {

return logWriter;

}

public int getLoginTimeout() throws SQLException {

return loginTimeout;

}

public void setLogWriter(PrintWriter out) throws SQLException {

this.logWriter = out;

}

public void setLoginTimeout(int seconds) throws SQLException {

this.loginTimeout = seconds;

}

public synchronized void init() throws AtomikosSQLException

{

/*2021年3月29日13:37:03增加动态加载数据源,来适配Romania和国内工厂一套代码,通过isLoad属性指定加载 */

if(StringUtils.isBlank(this.isLoad) || "false".equals(this.isLoad)) {

log.info("[{}]数据源加载配置为[{}],跳过加载",this.resourceName,this.isLoad);

return;

}else {

log.info("[{}]数据源加载配置为[{}],正常加载",this.resourceName,this.isLoad);

}

if ( LOGGER.isInfoEnabled() ) {

LOGGER.logInfo ( this + ": init..." );

}

//目前连接池存在连接

if (connectionPool != null) {

log.info("connectionPool不为null,存在连接");

LOGGER.logInfo("测试log日志是否打印1");

return;

}else {

log.info("connectionPool为null,不存在连接");

LOGGER.logInfo("测试log日志是否打印2");

//数据库名称

String dbName = this.resourceName;

String driver="com.mysql.jdbc.Driver";//获取mysql数据库的驱动类

Connection conn = null;

try {

Class.forName(driver);

LOGGER.logInfo("dbInfo信息:"+dbInfo.toString());

long startTime = System.currentTimeMillis();

conn = DriverManager.getConnection(dbInfo.get("url")+"&connectTimeout=10000",dbInfo.get("user"),dbInfo.get("password"));

long endTime = System.currentTimeMillis();

log.info("conn run time(毫秒):"+(endTime - startTime));

if(conn != null) {

if(conn.isClosed()) {

log.error("[{}]数据库连接检测异常:[{}]",dbName,JSON.toJSONString(dbInfo));

LOGGER.logInfo("数据库连接检测异常1");

return;//假如打不开数据库链接则跳过初始化数据库

}else {

LOGGER.logInfo("数据库连接检测正常1");

//说明数据库可以正常连接,关闭测试连接

conn.close();

log.info("[{}]数据库连接检测正常",dbName);

}

}else {

LOGGER.logInfo("数据库连接检测异常2");

log.error("[{}]数据库连接检测异常:[{}]",dbName,JSON.toJSONString(dbInfo));

return;

}

} catch (SQLException e) {

LOGGER.logInfo("数据库连接检测异常3");

log.error("[{}]数据库连接检测异常:[{}]",dbName,JSON.toJSONString(dbInfo),e);

//出现异常则跳过初始化数据库

return;

} catch (ClassNotFoundException e) {

log.error("未找到数据库驱动[{}]",driver,e);

//出现异常则跳过初始化数据库

return;

}finally {

if(null != conn) {

try {

conn.close();

} catch (SQLException throwables) {

throwables.printStackTrace();

}

}

}

}

if ( maxPoolSize < 1 ) {

throwAtomikosSQLException("Property 'maxPoolSize' must be greater than 0, was: " + maxPoolSize);

}

if ( minPoolSize < 0 || minPoolSize > maxPoolSize ) {

throwAtomikosSQLException("Property 'minPoolSize' must be at least 0 and at most maxPoolSize, was: " + minPoolSize);

}

if ( getUniqueResourceName() == null ) {

throwAtomikosSQLException("Property 'uniqueResourceName' cannot be null");

}

if ( getTestQuery() != null ) {

LOGGER.logWarning(this + ": testQuery set - pool may be slower / you might want to consider setting maxLifetime instead...");

}

if ( getMinPoolSize() == DEFAULT_POOL_SIZE ) {

LOGGER.logWarning ( this + ": poolSize equals default - this may cause performance problems!" );

}

try {

//initialize JNDI infrastructure for lookup

getReference();

ConnectionFactory cf = doInit();

connectionPool = new ConnectionPool(cf, this);

} catch ( AtomikosSQLException e ) {

//these are logged at creation time -> just rethrow

throw e;

} catch ( Exception ex) {

String msg = "Cannot initialize AtomikosDataSourceBean";

AtomikosSQLException.throwAtomikosSQLException ( msg , ex );

}

if ( LOGGER.isDebugEnabled() ) {

LOGGER.logDebug ( this + ": init done." );

}

}

public void close()

{

if ( LOGGER.isInfoEnabled() ) {

LOGGER.logInfo ( this + ": close..." );

}

if (connectionPool != null) {

connectionPool.destroy();

}

connectionPool = null;

doClose();

try {

IntraVmObjectRegistry.removeResource ( getUniqueResourceName() );

} catch ( NameNotFoundException e ) {

//ignore but log

if ( LOGGER.isDebugEnabled() ) {

LOGGER.logDebug ( this + ": Error removing from JNDI" , e );

}

}

if ( LOGGER.isDebugEnabled() ) {

LOGGER.logDebug ( this + ": close done." );

}

}

protected abstract ConnectionFactory doInit() throws Exception;

protected abstract void doClose();

/* DataSource impl */

public Connection getConnection ( HeuristicMessage msg ) throws SQLException

{

if ( LOGGER.isInfoEnabled() ) {

LOGGER.logInfo ( this + ": getConnection ( " + msg + " )..." );

}

Connection connection = null;

long startTime = System.currentTimeMillis();

init();

long endTime = System.currentTimeMillis();

log.info("getConnection run time(毫秒):"+(endTime - startTime));

try {

connection = (Connection) connectionPool.borrowConnection ( msg );

} catch (CreateConnectionException ex) {

throwAtomikosSQLException("Failed to grow the connection pool", ex);

} catch (PoolExhaustedException e) {

throwAtomikosSQLException ("Connection pool exhausted - try increasing 'maxPoolSize' and/or 'borrowConnectionTimeout' on the DataSourceBean.");

} catch (ConnectionPoolException e) {

throwAtomikosSQLException("Error borrowing connection", e );

}

if ( LOGGER.isDebugEnabled() ) {

LOGGER.logDebug ( this + ": returning " + connection );

}

return connection;

}

public Connection getConnection(String username, String password) throws SQLException

{

LOGGER.logWarning ( this + ": getConnection ( user , password ) ignores authentication - returning default connection" );

return getConnection();

}

/**

* Get the resource name.

*/

public String getUniqueResourceName() {

return resourceName;

}

/**

* Sets the resource name. Required.

*

* @param resourceName An arbitrary user-specified value that identifies

* this datasource. It must be unique for recovery purposes.

*/

public void setUniqueResourceName(String resourceName) {

this.resourceName = resourceName;

}

/**

* Tests whether local transactions are allowed - defaults to true

* for JDBC. This property is used by the pooling mechanism.

*/

public boolean getLocalTransactionMode() {

return true;

}

public Reference getReference() throws NamingException

{

return IntraVmObjectFactory.createReference ( this , getUniqueResourceName() );

}

public Connection getConnection() throws SQLException

{

StringHeuristicMessage m = null;

return getConnection ( m );

}

public Connection getConnection ( String msg ) throws SQLException

{

return getConnection ( new StringHeuristicMessage ( msg ) );

}

public Connection getConnection ( String user , String passwd , String msg )

throws SQLException

{

LOGGER.logWarning ( this + ": getConnection ( user , password , msg ) ignores authentication - returning default connection" );

return getConnection ( msg );

}

public Connection getConnection ( String user , String passwd ,

HeuristicMessage msg ) throws SQLException

{

LOGGER.logWarning ( this + ": getConnection ( user , password , msg ) ignores authentication - returning default connection" );

return getConnection ( msg );

}

/**

* Sets the default isolation level of connections returned by this datasource.

* Optional, defaults to the vendor-specific JDBC or DBMS settings.

*

* @param defaultIsolationLevel The default isolation level.

* Negative values are ignored and result in vendor-specific JDBC driver or DBMS internal defaults.

*/

public void setDefaultIsolationLevel(int defaultIsolationLevel) {

this.defaultIsolationLevel = defaultIsolationLevel;

}

/**

* Gets the default isolation level for connections created by this datasource.

*

* @return The default isolation level, or -1 if no specific value was set.

*

*/

public int getDefaultIsolationLevel() {

return defaultIsolationLevel;

}

public boolean isWrapperFor(Class<?> iface) {

return isAssignableFromThisClass(iface) || isAssignableFromWrappedVendorClass(iface);

}

protected abstract boolean isAssignableFromWrappedVendorClass(Class<?> iface);

private boolean isAssignableFromThisClass(Class<?> iface) {

return iface.isAssignableFrom(getClass());

}

public <T> T unwrap(Class<T> iface) throws SQLException {

if (isAssignableFromThisClass(iface)) {

return (T) this;

} else if (isAssignableFromWrappedVendorClass(iface)) {

return (T) unwrapVendorInstance();

}

throw new SQLException("Not a wrapper for class: " + iface);

}

protected abstract Object unwrapVendorInstance();

/**

* JDK 1.7 requirement.

*

* @throws SQLFeatureNotSupportedException

*/

public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {

throw new SQLFeatureNotSupportedException();

}

/**

* Refreshes all available connections in the pool.

*/

public void refreshPool() {

if (connectionPool != null) {

connectionPool.refresh();

}

}

public String getIsLoad() {

return isLoad;

}

public void setIsLoad(String isLoad) {

this.isLoad = isLoad;

}

}

这是系统运行日志

2023-06-27 12:25:15,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:25:15.875 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO  c.h.c.i.b.displayBoard.service.SystemServiceImpl - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- queryLine-service1:9771

2023-06-27 12:25:15,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:25:15.875 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO com.atomikos.jdbc.AbstractDataSourceBean - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- AtomikosDataSoureBean '9771DB': getConnection ( null )...

2023-06-27 12:25:15,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:25:15.875 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO com.atomikos.jdbc.AbstractDataSourceBean - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- [9771DB]数据源加载配置为[true],正常加载

2023-06-27 12:25:15,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:25:15.875 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO com.atomikos.jdbc.AbstractDataSourceBean - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- AtomikosDataSoureBean '9771DB': init...

2023-06-27 12:26:12,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:26:12.065 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO com.atomikos.jdbc.AtomikosConnectionProxy - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@3ef58ed7: calling getAutoCommit...

2023-06-27 12:26:12,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:26:12.065 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO com.atomikos.jdbc.AtomikosConnectionProxy - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@3ef58ed7: calling prepareStatement(select Production_Line_Id as lineId ,Production_Line_Code as lineCode,Production_Line_Desc as lineDesc from pm_production_lines_t

2023-06-27 12:26:12,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:26:12.450 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO com.atomikos.jdbc.AtomikosConnectionProxy - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@3ef58ed7: close()...

2023-06-27 12:26:25,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:26:25.263 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO c.h.c.i.b.displayBoard.service.SystemServiceImpl - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- System run time(miao):69

2023-06-27 12:26:25,sg-huaweiyun,seamom-prod,seamom-mes-base,seamom-mes-base-84748ccd44-8nlvg,2023-06-27 11:26:25.264 [DubboServerHandler-172.16.3.43:20880-thread-181] INFO c.h.c.i.b.displayBoard.service.SystemServiceImpl - [TID:59cb3626a68d4337b545619d71596be4_280_16878399158750027] --- queryLine-service2:9771

第四行跟第五行之间时间间隔1分钟,不知道为什么会这样


回答:

建议通过aop的方式记录一下 (数据源名称 访问开始 访问结束 接口路径等信息), 后面分析看看是网络导致的访问变慢 还是 和访问量相关

以上是 springboot项目中,用atomikos做的多数据源配置,某一个数据库,白天的时候访问非常慢,深夜访问就正常? 的全部内容, 来源链接: utcz.com/p/945222.html

回到顶部