Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize: branch register resource only at RM server end #5399

Merged
merged 44 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
8d2e41a
resolve fence to rm
sunrui1225 Feb 26, 2023
505f7c5
parserInterfaceToProxy eliminate aop proxy.
sunrui1225 Feb 28, 2023
61aae61
Merge branch '2.x' into resolve_fence_to_rm
sunrui1225 Mar 1, 2023
968c8d0
reimport
sunrui1225 Mar 1, 2023
bb1a55c
Merge remote-tracking branch 'origin/resolve_fence_to_rm' into resolv…
sunrui1225 Mar 1, 2023
4c3875d
Merge branch '2.x' into resolve_fence_to_rm
sunrui1225 Mar 3, 2023
7cbf600
bugfix register serviceClass
sunrui1225 Mar 3, 2023
543eb5a
Merge branch '2.x' into resolve_fence_to_rm
sunrui1225 Mar 26, 2023
ddaaa91
parse the business needed enhancement beans by bean definition.
sunrui1225 May 21, 2023
26dc039
Merge branch 'seata:2.x' into resolve_fence_to_rm
sunrui1225 May 21, 2023
38361ba
check style
sunrui1225 May 21, 2023
5cca5c4
check style
sunrui1225 May 21, 2023
d98f3ab
Revert "check style"
sunrui1225 May 21, 2023
daeaafc
check style
sunrui1225 May 22, 2023
002935e
check style
sunrui1225 May 22, 2023
e56a8b2
update the NeedEnhanceEnum GLOBAL_TRANSACTIONAL_BEAN
sunrui1225 May 23, 2023
fa6e3bf
use ReflectionUtil.getClassByName
sunrui1225 May 23, 2023
c42030e
enhancement: parse if it needs proxy by bean class
sunrui1225 Jun 15, 2023
22455a3
update tcc registerResource
sunrui1225 Jun 19, 2023
e6c90fe
Merge remote-tracking branch 'origin/2.x' into resolve_fence_to_rm
sunrui1225 Jun 19, 2023
80b175e
Merge branch '2.x' into resolve_fence_to_rm
sunrui1225 Jun 26, 2023
43f0bcc
Merge branch '2.x' into resolve_fence_to_rm
sunrui1225 Jun 30, 2023
b34ae57
Merge branch '2.x' into resolve_fence_to_rm
funky-eyes Oct 27, 2023
f4030a5
Merge remote-tracking branch 'origin/2.x' into resolve_fence_to_rm
sunrui1225 Dec 16, 2023
3ec392b
merge conflict resolve
sunrui1225 Dec 16, 2023
c3ffb17
Merge branch 'resolve_fence_to_rm' of github.com:sunrui1225/seata int…
sunrui1225 Dec 16, 2023
1da082e
Merge branch '2.x' into resolve_fence_to_rm
sunrui1225 Dec 16, 2023
bfa742a
Merge branch '2.x' into resolve_fence_to_rm
funky-eyes Dec 21, 2023
93b32cf
Update integration-tx-api/src/main/java/io/seata/integration/tx/api/i…
funky-eyes Dec 21, 2023
8c23358
Update integration-tx-api/src/main/java/io/seata/integration/tx/api/i…
funky-eyes Dec 21, 2023
e5cfe2c
Update integration-tx-api/src/main/java/io/seata/integration/tx/api/i…
funky-eyes Dec 21, 2023
6719fe7
Merge branch '2.x' into resolve_fence_to_rm
sunrui1225 Dec 23, 2023
83e4dae
Merge branch 'resolve_fence_to_rm' of github.com:sunrui1225/seata int…
sunrui1225 Dec 23, 2023
78c7121
add logs : Only the methods of classes with two phase annotations can…
sunrui1225 Dec 23, 2023
378fc00
fix : bean definition class name null issue.
sunrui1225 Dec 23, 2023
2df4c80
check style
sunrui1225 Dec 23, 2023
95c6903
add change log
sunrui1225 Dec 23, 2023
057c581
add change log
sunrui1225 Dec 23, 2023
3055c18
Merge branch '2.x' into resolve_fence_to_rm
funky-eyes Dec 23, 2023
79288d6
Merge branch '2.x' into resolve_fence_to_rm
funky-eyes Dec 29, 2023
076a8fc
add comments.
sunrui1225 Dec 29, 2023
a0fbe96
Merge remote-tracking branch 'origin/resolve_fence_to_rm' into resolv…
sunrui1225 Dec 29, 2023
967bfd6
Update integration-tx-api/src/main/java/io/seata/integration/tx/api/u…
funky-eyes Jan 4, 2024
5af4071
Merge branch '2.x' into resolve_fence_to_rm
funky-eyes Jan 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,15 @@ public ProxyInvocationHandler parserInterfaceToProxy(Object target, String objec
return null;
}

@Override
public IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass) {
for (InterfaceParser interfaceParser : ALL_INTERFACE_PARSERS) {
IfNeedEnhanceBean ifNeedEnhanceBean = interfaceParser.parseIfNeedEnhancement(beanClass);
if (ifNeedEnhanceBean.isIfNeed()) {
return ifNeedEnhanceBean;
}
}
return new IfNeedEnhanceBean();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import io.seata.common.ConfigurationKeys;
import io.seata.common.util.CollectionUtils;
import io.seata.common.util.ReflectionUtil;
import io.seata.config.ConfigurationCache;
import io.seata.config.ConfigurationChangeListener;
import io.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler;
Expand Down Expand Up @@ -60,6 +61,19 @@ public ProxyInvocationHandler parserInterfaceToProxy(Object target, String objec
return null;
}

@Override
public IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass) {
Set<Class<?>> interfaceClasses = ReflectionUtil.getInterfaces(beanClass);
Class<?>[] interfaceClasseArray = interfaceClasses.toArray(new Class<?>[0]);

IfNeedEnhanceBean ifNeedEnhanceBean = new IfNeedEnhanceBean();
if (existsAnnotation(beanClass) || existsAnnotation(interfaceClasseArray)) {
ifNeedEnhanceBean.setIfNeed(true);
ifNeedEnhanceBean.setNeedEnhanceEnum(NeedEnhanceEnum.GLOBAL_TRANSACTIONAL_BEAN);
}
return ifNeedEnhanceBean;
}

private boolean existsAnnotation(Class<?>... classes) {
boolean result = false;
if (CollectionUtils.isNotEmpty(classes)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.
*/
package io.seata.integration.tx.api.interceptor.parser;

public class IfNeedEnhanceBean {

private boolean ifNeed;

private NeedEnhanceEnum needEnhanceEnum;

public boolean isIfNeed() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is need/isNeed() better than ifNeed/isIfNeed() ?

return ifNeed;
}

public void setIfNeed(boolean ifNeed) {
this.ifNeed = ifNeed;
}

public NeedEnhanceEnum getNeedEnhanceEnum() {
return needEnhanceEnum;
}

public void setNeedEnhanceEnum(NeedEnhanceEnum needEnhanceEnum) {
this.needEnhanceEnum = needEnhanceEnum;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ public interface InterfaceParser {

ProxyInvocationHandler parserInterfaceToProxy(Object target, String objectName) throws Exception;

IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass);


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.
*/
package io.seata.integration.tx.api.interceptor.parser;

/**
* @author ruishansun
*/
funky-eyes marked this conversation as resolved.
Show resolved Hide resolved

public enum NeedEnhanceEnum {

/**
* global transactional bean type
*/
GLOBAL_TRANSACTIONAL_BEAN,
/**
* service bean type
*/
SERVICE_BEAN;
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ public interface RemotingParser {
*/
boolean isService(Object bean, String beanName) throws FrameworkException;

/**
* if it is service bean ?
*
* @param beanClass the bean class
* @return boolean boolean
* @throws FrameworkException the framework exception
*/
boolean isService(Class<?> beanClass) throws FrameworkException;

/**
* get the remoting bean info
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,21 @@ public boolean isService(Object bean, String beanName) {
return false;
}

/**
* is service bean ?
*
* @param beanClass the bean class
* @return boolean boolean
*/
public boolean isService(Class<?> beanClass) {
for (RemotingParser remotingParser : allRemotingParsers) {
if (remotingParser.isService(beanClass)) {
return true;
}
}
return false;
}

/**
* get the remoting Service desc
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public boolean isService(Object bean, String beanName) throws FrameworkException
|| "org.apache.dubbo.config.spring.ServiceBean".equals(c.getName());
}

@Override
public boolean isService(Class<?> beanClass) throws FrameworkException {
return "com.alibaba.dubbo.config.spring.ServiceBean".equals(beanClass.getName())
|| "org.apache.dubbo.config.spring.ServiceBean".equals(beanClass.getName());
}

@Override
public RemotingDesc getServiceDesc(Object bean, String beanName) throws FrameworkException {
if (!this.isRemoting(bean, beanName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ public boolean isService(Object bean, String beanName) {
return isHsf && "com.taobao.hsf.app.spring.util.HSFSpringProviderBean".equals(beanClassName);
}

@Override
public boolean isService(Class<?> beanClass) throws FrameworkException {
String beanClassName = beanClass.getName();
return isHsf && "com.taobao.hsf.app.spring.util.HSFSpringProviderBean".equals(beanClassName);
}

@Override
public RemotingDesc getServiceDesc(Object bean, String beanName) throws FrameworkException {
if (!this.isRemoting(bean, beanName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ public boolean isService(Object bean, String beanName) throws FrameworkException
return "com.alipay.sofa.runtime.spring.factory.ServiceFactoryBean".equals(beanClassName);
}

@Override
public boolean isService(Class<?> beanClass) throws FrameworkException {
String beanClassName = beanClass.getName();
return "com.alipay.sofa.runtime.spring.factory.ServiceFactoryBean".equals(beanClassName);
}

@Override
public RemotingDesc getServiceDesc(Object bean, String beanName) throws FrameworkException {
if (!this.isRemoting(bean, beanName)) {
Expand Down
12 changes: 8 additions & 4 deletions spring/src/main/java/io/seata/rm/fence/SpringFenceHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ public boolean commitFence(Method commitMethod, Object targetTCCBean,
}
return false;
}
return updateStatusAndInvokeTargetMethod(conn, commitMethod, targetTCCBean, xid, branchId, CommonFenceConstant.STATUS_COMMITTED, status, args);
boolean result = updateStatusAndInvokeTargetMethod(conn, commitMethod, targetTCCBean, xid, branchId, CommonFenceConstant.STATUS_COMMITTED, status, args);
LOGGER.info("Common fence commit result: {}. xid: {}, branchId: {}", result, xid, branchId);
return result;
} catch (Throwable t) {
status.setRollbackOnly();
throw new SkipCallbackWrapperException(t);
Expand Down Expand Up @@ -211,7 +213,9 @@ public boolean rollbackFence(Method rollbackMethod, Object targetTCCBean,
return false;
}
}
return updateStatusAndInvokeTargetMethod(conn, rollbackMethod, targetTCCBean, xid, branchId, CommonFenceConstant.STATUS_ROLLBACKED, status, args);
boolean result = updateStatusAndInvokeTargetMethod(conn, rollbackMethod, targetTCCBean, xid, branchId, CommonFenceConstant.STATUS_ROLLBACKED, status, args);
LOGGER.info("Common fence rollback result: {}. xid: {}, branchId: {}", result, xid, branchId);
return result;
} catch (Throwable t) {
status.setRollbackOnly();
throw new SkipCallbackWrapperException(t);
Expand All @@ -238,13 +242,13 @@ private static boolean insertCommonFenceLog(Connection conn, String xid, Long br
}

/**
* Update TCC Fence status and invoke target method
* Update Common Fence status and invoke target method
*
* @param method target method
* @param targetTCCBean target bean
* @param xid the global transaction id
* @param branchId the branch transaction id
* @param status the tcc fence status
* @param status the common fence status
* @return the boolean
*/
private static boolean updateStatusAndInvokeTargetMethod(Connection conn, Method method, Object targetTCCBean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nullable;

import com.google.common.collect.ImmutableSet;
import io.seata.common.util.CollectionUtils;
import io.seata.common.util.StringUtils;
import io.seata.config.ConfigurationCache;
Expand All @@ -42,6 +43,8 @@
import io.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler;
import io.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
import io.seata.integration.tx.api.interceptor.parser.DefaultInterfaceParser;
import io.seata.integration.tx.api.interceptor.parser.IfNeedEnhanceBean;
import io.seata.integration.tx.api.interceptor.parser.NeedEnhanceEnum;
import io.seata.integration.tx.api.remoting.parser.DefaultRemotingParser;
import io.seata.rm.RMClient;
import io.seata.spring.annotation.scannercheckers.PackageScannerChecker;
Expand All @@ -62,10 +65,13 @@
import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
Expand Down Expand Up @@ -115,6 +121,8 @@ public class GlobalTransactionScanner extends AbstractAutoProxyCreator

private ApplicationContext applicationContext;

private static final Set<String> NEED_ENHANCE_BEAN_NAME_SET = new HashSet<>();


/**
* Instantiates a new Global transaction scanner.
Expand Down Expand Up @@ -281,6 +289,9 @@ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey)
if (PROXYED_SET.contains(beanName)) {
return bean;
}
if (!NEED_ENHANCE_BEAN_NAME_SET.contains(beanName)) {
return bean;
}
interceptor = null;
ProxyInvocationHandler proxyInvocationHandler = DefaultInterfaceParser.get().parserInterfaceToProxy(bean, beanName);
if (proxyInvocationHandler == null) {
Expand Down Expand Up @@ -470,8 +481,68 @@ public void afterPropertiesSet() {
if (initialized.compareAndSet(false, true)) {
initClient();
}

this.findBusinessBeanNamesNeededEnhancement();
}

private void findBusinessBeanNamesNeededEnhancement() {
if (applicationContext instanceof ConfigurableApplicationContext) {
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
ConfigurableListableBeanFactory configurableListableBeanFactory = configurableApplicationContext.getBeanFactory();

String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String contextBeanName : beanNames) {
BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition(contextBeanName);
if (IGNORE_ENHANCE_CHECK_SET.contains(beanDefinition.getBeanClassName())) {
continue;
}
try {
// get the class by bean definition class name
Class<?> beanClass = Class.forName(beanDefinition.getBeanClassName());
// check if it needs enhancement by the class
IfNeedEnhanceBean ifNeedEnhanceBean = DefaultInterfaceParser.get().parseIfNeedEnhancement(beanClass);
if (!ifNeedEnhanceBean.isIfNeed()) {
continue;
}
if (ifNeedEnhanceBean.getNeedEnhanceEnum().equals(NeedEnhanceEnum.SERVICE_BEAN)) {
// the native bean which dubbo, sofa bean service bean referenced
PropertyValue propertyValue = beanDefinition.getPropertyValues().getPropertyValue("ref");
funky-eyes marked this conversation as resolved.
Show resolved Hide resolved
if (propertyValue == null) {
Copy link
Contributor

@Bughue Bughue Jan 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这些逻辑看起来应该和parser强相关,是不是该挪到parser去?虽然这样做会带来一部分重复的代码
This logic seems like it should be strongly related to the parser, so should it be moved to the parser, even though it would be a duplicate piece of code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果引入到parser中,可能会给parser带来beanDefinition的spring依赖,原则上可能不想让parser层引入spring相关的依赖

// the native bean which HSF service bean referenced
propertyValue = beanDefinition.getPropertyValues().getPropertyValue("target");
}
if (propertyValue != null) {
RuntimeBeanReference r = (RuntimeBeanReference) propertyValue.getValue();
if (r != null && StringUtils.isNotBlank(r.getBeanName())) {
NEED_ENHANCE_BEAN_NAME_SET.add(r.getBeanName());
continue;
}
}
// the native bean which local tcc service bean referenced
NEED_ENHANCE_BEAN_NAME_SET.add(contextBeanName);
} else if (ifNeedEnhanceBean.getNeedEnhanceEnum().equals(NeedEnhanceEnum.GLOBAL_TRANSACTIONAL_BEAN)) {
// global transactional bean
NEED_ENHANCE_BEAN_NAME_SET.add(contextBeanName);
}
} catch (ClassNotFoundException e) {
LOGGER.warn("check if need enhance bean error, it can be ignore", e);
}
}
LOGGER.info("The needed enhancement business beans are : {}", NEED_ENHANCE_BEAN_NAME_SET);
}
}

private static final Set<String> IGNORE_ENHANCE_CHECK_SET = ImmutableSet.of(
"io.seata.spring.annotation.GlobalTransactionScanner"
, "io.seata.rm.fence.SpringFenceConfig"
, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
, "org.springframework.context.annotation.internalCommonAnnotationProcessor"
, "org.springframework.context.event.internalEventListenerProcessor"
, "org.springframework.context.event.internalEventListenerFactory"
);


@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ public boolean isService(Object bean, String beanName) {
return DefaultRemotingParser.get().isService(factoryBean, getFactoryBeanName(beanName));
}

@Override
public boolean isService(Class<?> beanClass) throws FrameworkException {
return false;
}

@Override
public RemotingDesc getServiceDesc(Object bean, String beanName) throws FrameworkException {
Object factoryBean = getRemotingFactoryBean(bean, beanName);
Expand Down
Loading
Loading