Skip to content

Commit

Permalink
optimize: rm appdata size limit (#4473)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bughue authored Nov 28, 2023
1 parent 2122c6d commit 9fef2db
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 3 deletions.
2 changes: 2 additions & 0 deletions changes/en-us/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Add changes here for all PR submitted to the 2.x branch.
### optimize:
- [[#6061](https://github.com/seata/seata/pull/6061)] merge the rpcMergeMessageSend threads of rm and tm and increase the thread hibernation duration
- [[#6031](https://github.com/seata/seata/pull/6031)] add a check for the existence of the undolog table
- [[#4473](https://github.com/seata/seata/pull/4473)] rm appdata size limit

### security:
- [[#6069](https://github.com/seata/seata/pull/6069)] Upgrade Guava dependencies to fix security vulnerabilities
Expand All @@ -30,5 +31,6 @@ Thanks to these contributors for their code commits. Please report an unintended
- [imcmai](https://github.com/imcmai)
- [DroidEye2ONGU](https://github.com/DroidEye2ONGU)
- [funky-eyes](https://github.com/funky-eyes)
- [Bughue](https://github.com/Bughue)

Also, we receive many valuable issues, questions and advices from our community. Thanks for you all.
3 changes: 2 additions & 1 deletion changes/zh-cn/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
### optimize:
- [[#6061](https://github.com/seata/seata/pull/6061)] 合并rm和tm的rpcMergeMessageSend线程,增加线程休眠时长
- [[#6031](https://github.com/seata/seata/pull/6031)] 添加undo_log表的存在性校验
- [[#4473](https://github.com/seata/seata/pull/4473)] rm appdata大小限制


### security:
Expand All @@ -31,6 +32,6 @@
- [imcmai](https://github.com/imcmai)
- [DroidEye2ONGU](https://github.com/DroidEye2ONGU)
- [funky-eyes](https://github.com/funky-eyes)

- [Bughue](https://github.com/Bughue)

同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。
19 changes: 19 additions & 0 deletions common/src/main/java/io/seata/common/ConfigurationKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -982,4 +982,23 @@ public interface ConfigurationKeys {
*/
String ENABLE_PARALLEL_HANDLE_BRANCH_KEY = SERVER_PREFIX + "enableParallelHandleBranch";

/**
* The constant RM_APPLICATION_DATA_SIZE_ERROR
*/
String RM_APPLICATION_DATA_SIZE_LIMIT = CLIENT_RM_PREFIX + "applicationDataLimit";

/**
* The constant RM_APPLICATION_DATA_SIZE_CHECK
*/
String RM_APPLICATION_DATA_SIZE_CHECK = CLIENT_RM_PREFIX + "applicationDataLimitCheck";

/**
* The constant SERVER_APPLICATION_DATA_SIZE_ERROR
*/
String SERVER_APPLICATION_DATA_SIZE_LIMIT = SERVER_PREFIX + "applicationDataLimit";

/**
* The constant SERVER_APPLICATION_DATA_SIZE_CHECK
*/
String SERVER_APPLICATION_DATA_SIZE_CHECK = SERVER_PREFIX + "applicationDataLimitCheck";
}
5 changes: 5 additions & 0 deletions common/src/main/java/io/seata/common/DefaultValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ public interface DefaultValues {
*/
long DEFAULT_RPC_TC_REQUEST_TIMEOUT = Duration.ofSeconds(15).toMillis();

/**
* the constant DEFAULT_APPLICATION_DATA_SIZE_LIMIT
*/
int DEFAULT_APPLICATION_DATA_SIZE_LIMIT = 64000;

/**
* the constant DEFAULT_XAER_NOTA_RETRY_TIMEOUT
*/
Expand Down
27 changes: 27 additions & 0 deletions common/src/main/java/io/seata/common/util/StringUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
Expand All @@ -29,6 +30,8 @@

import io.seata.common.Constants;
import io.seata.common.exception.ShouldNeverHappenException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The type String utils.
Expand All @@ -38,6 +41,7 @@
*/
public class StringUtils {

private static final Logger LOGGER = LoggerFactory.getLogger(StringUtils.class);
private static final Pattern CAMEL_PATTERN = Pattern.compile("[A-Z]");
private static final Pattern LINE_PATTERN = Pattern.compile("-(\\w)");

Expand Down Expand Up @@ -349,6 +353,29 @@ public static String hump2Line(String str) {
return sb.toString();
}

/**
* check string data size
*
* @param data the str
* @param dataName the data name
* @param errorSize throw exception if size > errorSize
* @return boolean
*/
public static boolean checkDataSize(String data, String dataName, int errorSize, boolean throwIfErr) {
if (isBlank(data)) {
return true;
}
int length = data.getBytes(StandardCharsets.UTF_8).length;
if (length > errorSize) {
LOGGER.warn("{} data is large(errorSize), size={}", dataName, length);
if (!throwIfErr) {
return false;
}
throw new IllegalArgumentException(dataName + " data is too large, size=" + length);
}
return true;
}

public static boolean hasLowerCase(String str) {
if (null == str) {
return false;
Expand Down
11 changes: 11 additions & 0 deletions common/src/test/java/io/seata/common/util/StringUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,15 @@ public String toString() {
')';
}
}

@Test
void checkDataSize() {
assertThat(StringUtils.checkDataSize("","testdata",10,false)).isEqualTo(Boolean.TRUE);
assertThat(StringUtils.checkDataSize("1234567","testdata",17,false)).isEqualTo(Boolean.TRUE);
assertThat(StringUtils.checkDataSize("1234567","testdata",4,false)).isEqualTo(Boolean.FALSE);
Assertions.assertThrows(IllegalArgumentException.class, () ->
StringUtils.checkDataSize("1234567","testdata",6,true)
);
assertThat( StringUtils.checkDataSize("1234567","testdata",6,false)).isEqualTo(Boolean.FALSE);
}
}
15 changes: 14 additions & 1 deletion rm/src/main/java/io/seata/rm/AbstractResourceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
package io.seata.rm;

import java.util.concurrent.TimeoutException;

import io.seata.common.ConfigurationKeys;
import io.seata.common.DefaultValues;
import io.seata.common.exception.NotSupportYetException;
import io.seata.common.util.StringUtils;
import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
import io.seata.core.exception.RmTransactionException;
import io.seata.core.exception.TransactionException;
import io.seata.core.exception.TransactionExceptionCode;
Expand All @@ -43,6 +47,12 @@ public abstract class AbstractResourceManager implements ResourceManager {

protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractResourceManager.class);

private static final Configuration CONFIG = ConfigurationFactory.getInstance();

private static int appDataErrSize = CONFIG.getInt(ConfigurationKeys.RM_APPLICATION_DATA_SIZE_LIMIT,
DefaultValues.DEFAULT_APPLICATION_DATA_SIZE_LIMIT);

private static boolean throwDataSizeExp = CONFIG.getBoolean(ConfigurationKeys.RM_APPLICATION_DATA_SIZE_CHECK, false);
/**
* registry branch record
*
Expand All @@ -57,6 +67,8 @@ public abstract class AbstractResourceManager implements ResourceManager {
@Override
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid, String applicationData, String lockKeys) throws TransactionException {
try {
StringUtils.checkDataSize(applicationData, "applicationData", appDataErrSize, throwDataSizeExp);

BranchRegisterRequest request = new BranchRegisterRequest();
request.setXid(xid);
request.setLockKey(lockKeys);
Expand Down Expand Up @@ -94,6 +106,7 @@ public Long branchRegister(BranchType branchType, String resourceId, String clie
@Override
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status, String applicationData) throws TransactionException {
try {
StringUtils.checkDataSize(applicationData, "applicationData", appDataErrSize, throwDataSizeExp);
BranchReportRequest request = new BranchReportRequest();
request.setXid(xid);
request.setBranchId(branchId);
Expand Down
2 changes: 2 additions & 0 deletions script/client/conf/file.conf
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ client {
sqlParserType = "druid"
branchExecutionTimeoutXA = 60000
connectionTwoPhaseHoldTimeoutXA = 10000
applicationDataLimit = 64000
applicationDataLimitCheck = false
}
tm {
commitRetryCount = 5
Expand Down
2 changes: 2 additions & 0 deletions script/client/spring/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ seata.client.rm.lock.retry-times=30
seata.client.rm.lock.retry-policy-branch-rollback-on-conflict=true
seata.client.rm.branchExecutionTimeoutXA=60000
seata.client.rm.connectionTwoPhaseHoldTimeoutXA=10000
seata.client.rm.applicationDataLimit=64000
seata.client.rm.applicationDataLimitCheck=false
seata.client.tm.commit-retry-count=5
seata.client.tm.rollback-retry-count=5
seata.client.tm.default-global-transaction-timeout=60000
Expand Down
2 changes: 2 additions & 0 deletions script/client/spring/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ seata:
saga-compensate-persist-mode-update: false
tcc-action-interceptor-order: -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000
sql-parser-type: druid
applicationDataLimit: 64000
applicationDataLimitCheck: false
lock:
retry-interval: 10
retry-times: 30
Expand Down
2 changes: 2 additions & 0 deletions script/config-center/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=true
server.enableParallelHandleBranch=false
server.applicationDataLimit=64000
server.applicationDataLimitCheck=false

server.raft.cluster=127.0.0.1:7091,127.0.0.1:7092,127.0.0.1:7093
server.raft.snapshotInterval=600
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import static io.seata.common.DefaultValues.TCC_ACTION_INTERCEPTOR_ORDER;
import static io.seata.common.DefaultValues.DEFAULT_XA_BRANCH_EXECUTION_TIMEOUT;
import static io.seata.common.DefaultValues.DEFAULT_XA_CONNECTION_TWO_PHASE_HOLD_TIMEOUT;
import static io.seata.common.DefaultValues.DEFAULT_APPLICATION_DATA_SIZE_LIMIT;
import static io.seata.spring.boot.autoconfigure.StarterConstants.CLIENT_RM_PREFIX;

/**
Expand All @@ -53,6 +54,9 @@ public class RmProperties {
private int connectionTwoPhaseHoldTimeoutXA = DEFAULT_XA_CONNECTION_TWO_PHASE_HOLD_TIMEOUT;
private String sqlParserType = SqlParserType.SQL_PARSER_TYPE_DRUID;

private Boolean applicationDataLimitCheck = false;
private Integer applicationDataLimit = DEFAULT_APPLICATION_DATA_SIZE_LIMIT;

public int getAsyncCommitBufferLimit() {
return asyncCommitBufferLimit;
}
Expand Down Expand Up @@ -164,4 +168,19 @@ public void setConnectionTwoPhaseHoldTimeoutXA(int connectionTwoPhaseHoldTimeout
this.connectionTwoPhaseHoldTimeoutXA = connectionTwoPhaseHoldTimeoutXA;
}

public Boolean getApplicationDataLimitCheck() {
return applicationDataLimitCheck;
}

public void setApplicationDataLimitCheck(Boolean applicationDataLimitCheck) {
this.applicationDataLimitCheck = applicationDataLimitCheck;
}

public Integer getApplicationDataLimit() {
return applicationDataLimit;
}

public void setApplicationDataLimit(Integer applicationDataLimit) {
this.applicationDataLimit = applicationDataLimit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public class ServerProperties {
private Integer servicePort;
private Integer xaerNotaRetryTimeout = 60000;

private Boolean applicationDataLimitCheck = false;
private Integer applicationDataLimit = 64000;

public long getMaxCommitRetryTimeout() {
return maxCommitRetryTimeout;
}
Expand Down Expand Up @@ -114,4 +117,19 @@ public void setEnableParallelHandleBranch(Boolean enableParallelHandleBranch) {
this.enableParallelHandleBranch = enableParallelHandleBranch;
}

public Boolean getApplicationDataLimitCheck() {
return applicationDataLimitCheck;
}

public void setApplicationDataLimitCheck(Boolean applicationDataLimitCheck) {
this.applicationDataLimitCheck = applicationDataLimitCheck;
}

public Integer getApplicationDataLimit() {
return applicationDataLimit;
}

public void setApplicationDataLimit(Integer applicationDataLimit) {
this.applicationDataLimit = applicationDataLimit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
import java.io.IOException;
import java.util.concurrent.TimeoutException;

import io.seata.common.ConfigurationKeys;
import io.seata.common.DefaultValues;
import io.seata.common.util.StringUtils;
import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
import io.seata.core.context.RootContext;
import io.seata.core.exception.BranchTransactionException;
import io.seata.core.exception.GlobalTransactionException;
Expand Down Expand Up @@ -59,13 +64,21 @@ public abstract class AbstractCore implements Core {

protected LockManager lockManager = LockerManagerFactory.getLockManager();

private static final Configuration CONFIG = ConfigurationFactory.getInstance();
private int appDataErrSize ;
private boolean throwDataSizeExp ;

protected RemotingServer remotingServer;

public AbstractCore(RemotingServer remotingServer) {
if (remotingServer == null) {
throw new IllegalArgumentException("remotingServer must be not null");
}
this.remotingServer = remotingServer;
this.appDataErrSize = CONFIG.getInt(ConfigurationKeys.SERVER_APPLICATION_DATA_SIZE_LIMIT,
DefaultValues.DEFAULT_APPLICATION_DATA_SIZE_LIMIT);
this.throwDataSizeExp = CONFIG.getBoolean(ConfigurationKeys.SERVER_APPLICATION_DATA_SIZE_CHECK, false);

}

public abstract BranchType getHandleBranchType();
Expand All @@ -74,6 +87,13 @@ public AbstractCore(RemotingServer remotingServer) {
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
String applicationData, String lockKeys) throws TransactionException {
GlobalSession globalSession = assertGlobalSessionNotNull(xid, false);
try {
StringUtils.checkDataSize(applicationData, "applicationData", appDataErrSize, throwDataSizeExp);
} catch (RuntimeException e) {
throw new BranchTransactionException(TransactionExceptionCode.FailedToAddBranch,
String.format("Failed to store branch xid = %s ", globalSession.getXid()), e);
}

return SessionHolder.lockAndExecute(globalSession, () -> {
globalSessionStatusCheck(globalSession);
BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, branchType, resourceId,
Expand All @@ -90,7 +110,7 @@ public Long branchRegister(BranchType branchType, String resourceId, String clie
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Register branch successfully, xid = {}, branchId = {}, resourceId = {} ,lockKeys = {}",
globalSession.getXid(), branchSession.getBranchId(), resourceId, lockKeys);
globalSession.getXid(), branchSession.getBranchId(), resourceId, lockKeys);
}
return branchSession.getBranchId();
});
Expand Down
2 changes: 2 additions & 0 deletions server/src/main/resources/application.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ seata:
retry-dead-threshold: 130000
xaer-nota-retry-timeout: 60000
enableParallelRequestHandle: true
applicationDataLimitCheck: true
applicationDataLimit: 64000
recovery:
committing-retry-period: 1000
async-committing-retry-period: 1000
Expand Down
2 changes: 2 additions & 0 deletions server/src/main/resources/application.raft.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ seata:
retry-dead-threshold: 130000
xaer-nota-retry-timeout: 60000
enableParallelRequestHandle: true
applicationDataLimitCheck: true
applicationDataLimit: 64000
recovery:
committing-retry-period: 1000
async-committing-retry-period: 1000
Expand Down

0 comments on commit 9fef2db

Please sign in to comment.