Oscarcheng0312 opened a new pull request, #7782:
URL: https://github.com/apache/incubator-seata/pull/7782
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Please make sure you have read and understood the contributing
guidelines -->
- [ ] I have read the
[CONTRIBUTING.md](https://github.com/apache/incubator-seata/blob/2.x/CONTRIBUTING.md)
guidelines.
- [ ] I have registered the PR
[changes](https://github.com/apache/incubator-seata/tree/2.x/changes).
### Ⅰ. Describe what this PR did
1.Connection pool registration
### 1)Modifications
`rm-datasource/src/main/java/org/apache/seata/rm/datasource/DataSourceProxy.java`
- After `init(DataSource, String)` finishes the original initialization, the
enhancer is invoked to register the data source into connection pool monitoring:
```java
// Register DataSource for connection pool monitoring
DataSourceProxyEnhancer.onDataSourceProxyInitialized(this);
```
- In `close()` a destroy hook is added to unregister monitoring and clear
caches:
```java
public void close() throws Exception {
// TODO: Need to unregister resource from DefaultResourceManager
TableMetaCacheFactory.shutdown(resourceId);
DataSourceProxyEnhancer.onDataSourceProxyDestroyed(this);
}
```
-Effect: the lifecycle of `DataSourceProxy` is bound to the connection pool
monitoring lifecycle. Initialization triggers registration, and close triggers
unregistration, ensuring that metrics are only collected from valid data source
instances.
### 2)Additions
`rm-datasource/src/main/java/org/apache/seata/rm/datasource/DataSourceProxyEnhancer.java`
- Connection-pool monitoring integration enhancer. It automatically
registers/unregisters data sources when DataSourceProxy is
initialized/destroyed, and also provides public methods for manual
registration/unregistration.
- Key methods and code snippet:
```java
public static void onDataSourceProxyInitialized(DataSourceProxy
dataSourceProxy) {
DataSource targetDataSource = dataSourceProxy.getTargetDataSource();
if
(!DataSourceConnectionPoolCollector.isSupportedDataSource(targetDataSource)) {
return; }
String dataSourceName = generateDataSourceName(dataSourceProxy);
DataSourceConnectionPoolCollector.registerDataSource(dataSourceName,
targetDataSource);
LOGGER.info("Registered DataSource [{}] for connection pool
monitoring: {}", dataSourceName,
targetDataSource.getClass().getSimpleName());
}
public static void onDataSourceProxyDestroyed(DataSourceProxy
dataSourceProxy) {
String dataSourceName = generateDataSourceName(dataSourceProxy);
DataSourceConnectionPoolCollector.unregisterDataSource(dataSourceName);
LOGGER.info("Unregistered DataSource [{}] from connection pool
monitoring", dataSourceName);
}
public static void registerDataSource(String name, DataSource dataSource)
{ /* manual registration */ }
public static void unregisterDataSource(String name) { /* manual
unregistration */ }
```
- Effect: acts as the bridge between `rm-datasource` and the `core` module’s
`DataSourceConnectionPoolCollector` hiding concrete pool implementations
(HikariCP / Druid) from(HikariCP/Druid)。
## 2.SQL collection
### 1)Modifications
`rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/ExecuteTemplate.java`
- In the common SQL execution entry for AT mode, SQL execution and slow SQL
are collected in the 'finally' block:
```java
finally {
String sql = statementProxy.getTargetSQL();
if (sql != null) {
long executionTimeMillis = System.currentTimeMillis() - start;
LocalDateTime ts = LocalDateTime.now();
SqlCollector.addSqlExecutionEntry(sql, executionTimeMillis,
executionTimeMillis, ts);
SqlCollector.addSlowSqlEntry(sql, executionTimeMillis, ts);
}
}
```
- 作用:Effect: provides unified collection of SQL execution time and slow SQL
information in AT mode so that the client can periodically report it to the
server.
`rm-datasource/src/main/java/org/apache/seata/rm/datasource/xa/StatementProxyXA.java`
- In the XA-mode `Statement` proxy, collection is added for the `execute /
executeQuery / executeUpdate` methods:
```java
long start = System.currentTimeMillis();
boolean res = ExecuteTemplateXA.execute(...);
long cost = System.currentTimeMillis() - start;
SqlCollector.addSqlExecutionEntry(sql, cost, cost, LocalDateTime.now());
SqlCollector.addSlowSqlEntry(sql, cost, LocalDateTime.now());
return res;
```
- Effect: collects SQL execution time and slow SQL in XA mode as well,
keeping the metrics consistent with AT mode.
`rm-datasource/src/main/java/org/apache/seata/rm/datasource/xa/PreparedStatementProxyXA.java`
- In the XA-mode `PreparedStatement` proxy, collection is added for the
`executeQuery / executeUpdate / execute` methods:
```java
long start = System.currentTimeMillis();
int res = ExecuteTemplateXA.execute(...);
long cost = System.currentTimeMillis() - start;
if (targetSQL != null) {
SqlCollector.addSqlExecutionEntry(targetSQL, cost, cost,
LocalDateTime.now());
SqlCollector.addSlowSqlEntry(targetSQL, cost, LocalDateTime.now());
}
return res;
```
- Effect: collects metrics for prepared statement executions, ensuring that
SQL records are complete.
`rm-datasource/src/main/java/org/apache/seata/rm/datasource/xa/AbstractConnectionProxyXA.java`
- Updated to adapt to the new `PreparedStatementProxyXA`,constructor that
carries the SQL text.
### 2)Additions
`core/src/main/java/org/apache/seata/core/rpc/netty/SqlCollector.java`
- Client-side SQL collector that gathers information about SQL executed on
the client.
SQL models:
`core/src/main/java/org/apache/seata/core/protocol/SqlExecutionEntry.java`
- Entity class representing a SQL execution record.
`core/src/main/java/org/apache/seata/core/protocol/SlowSqlEntry.java`
- Entity class representing a slow SQL record.
## 3.Connection pool metrics collection
### 1)Additions
`core/src/main/java/org/apache/seata/core/rpc/netty/DataSourceConnectionPoolCollector.java`
- Client-side collector that::Registers/unregisters `DataSource`(invoked by
`DataSourceProxyEnhancer`)and caches them on the client.,Collects
HikariCP/Druid runtime metrics.。
- Provides runtime configuration updates via `updateConfig(poolName,
request)`,safely invoking connection-pool setter methods via reflection.
- Injects slow SQL and recent execution records from `SqlCollector` .
Example snippet:
```java
// Register a data source
public static void registerDataSource(String name, DataSource ds) {
// Put the data source into the HIKARI or DRUID registry based on type
}
// Hikari/Druid metrics collection
public static List<HikariConnectionPoolMetrics>
collectAllHikariPoolMetrics() { /* ... */ }
public static List<DruidConnectionPoolMetrics> collectAllDruidPoolMetrics()
{ /* ... */ }
// Dynamic configuration update
public static boolean updateConfig(String poolName, PoolConfigUpdateRequest
request) { /* ... */ }
```
Metrics models:
-
`core/src/main/java/org/apache/seata/core/protocol/HikariConnectionPoolMetrics.java`
- Entity class that records client-side HikariCP connection-pool metrics.
-
`core/src/main/java/org/apache/seata/core/protocol/DruidConnectionPoolMetrics.java`
- Entity class that records client-side Druid connection-pool metrics.
-
`core/src/main/java/org/apache/seata/core/model/PoolConfigUpdateRequest.java`
- Entity class that represents connection-pool configuration update
information.
## 4.Class relationship diagram
```text
rm-datasource core
┌──────────────────────────────────────────┐
┌──────────────────────────────────────────┐
│ DataSourceProxy │ init │
DataSourceConnectionPoolCollector │
│ └─ onInit → DataSourceProxyEnhancer ────┼──────▶│
registerDataSource(name, ds) │
│ └─ onClose → DataSourceProxyEnhancer ───┼──────▶│
unregisterDataSource(name) │
└──────────────────────────────────────────┘
└──────────────────────────────────────────┘
┌──────────────────────────────────────────┐
┌──────────────────────────────────────────┐
│ ExecuteTemplate (AT) │ add │ SqlCollector
│
│ StatementProxyXA / PreparedStatementXA │ add │
addSqlExecutionEntry(...) │
│ └─ ExecuteTemplateXA (XA) │ add │ addSlowSqlEntry(...)
│
└──────────────────────────────────────────┘
└──────────────────────────────────────────┘
Explanation:
- `DataSourceProxyEnhancer` registers proxied data sources into the `core`
collector, which detects HikariCP/Druid and captures real-time metrics.
- `ExecuteTemplate` (AT) and the XA proxies call `SqlCollector` after SQL
execution to record execution time and slow SQL, which can then be periodically
reported by the client.
```
### Ⅴ. Special notes for reviews
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]