Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring源码解析之声明式事务处理

Spring源码解析之声明式事务处理

作者头像
I Teach You 我教你
发布于 2023-07-18 10:03:40
发布于 2023-07-18 10:03:40
24000
代码可运行
举报
运行总次数:0
代码可运行

我们看看 Spring 中的事务处理的代码,使用 Spring 管理事务有声明式和编程式两种方式,声明式事务处理通过 AOP 的实现把事物管理代码作为方面封装来横向插入到业务代码中,使得事务管理代码和业务代码解藕。在这种方式我们结合 IoC 容器和 Spirng 已有的FactoryBean 来对事务管理进行属性配置,比如传播行为,隔离级别等。其中最简单的方式就是通过配置 TransactionProxyFactoryBean来实现声明式事物;在整个源代码分析中,我们可以大致可以看到 Spring 实现声明式事物管理有这么几个部分:

  • 对在上下文中配置的属性的处理,这里涉及的类是 TransactionAttributeSourceAdvisor,这是一个通知器,用它来对属性值进行处理,属性信息放在 TransactionAttribute 中来使用,而这些属性的处理往往是和对切入点的处理是结合起来的。对属性的处理放在类TransactionAttributeSource 中完成。
  • 创建事物的过程,这个过程是委托给具体的事物管理器来创建的,但 Spring 通过 TransactionStatus 来传递相关的信息。
  • 对事物的处理通过对相关信息的判断来委托给具体的事物管理器完成。

我们下面看看具体的实现,在 TransactionFactoryBean 中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBean implements FactoryBean, BeanFactoryAware { 
 2    //这里是 Spring 事务处理而使用的 AOP 拦截器,中间封装了 Spring 对事务处理的代码来支持声明式事务处理的实现 
 3    private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor(); 
 4
 5    private Pointcut pointcut; 
 6
 7    //这里 Spring 把 TransactionManager 注入到 TransactionInterceptor 中去 
 8    public void setTransactionManager(PlatformTransactionManager transactionManager) { 
 9        this.transactionInterceptor.setTransactionManager(transactionManager); 
10    } 
11
12    //这里把在 bean 配置文件中读到的事务管理的属性信息注入到 TransactionInterceptor 中去 
13    public void setTransactionAttributes(Properties transactionAttributes) { 
14        this.transactionInterceptor.setTransactionAttributes(transactionAttributes); 
15    } 
16
17    ...中间省略了其他一些方法...
18
19    //这里创建 Spring AOP 对事务处理的 Advisor 
20    protected Object createMainInterceptor() { 
21        this.transactionInterceptor.afterPropertiesSet(); 
22        if (this.pointcut != null) { 
23            //这里使用默认的通知器 
24            return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor); 
25        }else { 
26            // 使用上面定义好的 TransactionInterceptor 作为拦截器,同时使用 TransactionAttributeSourceAdvisor 
27            return new TransactionAttributeSourceAdvisor(this.transactionInterceptor); 
28        } 
29    } 
30} 

那什么时候 Spring 的 TransactionInterceptor 被注入到 Spring AOP 中成为 Advisor 中的一部分呢?我们看到在TransactionProxyFactoryBean 中,这个方法在 IOC 初始化 bean 的时候被执行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1public void afterPropertiesSet() { 
 2    ...
 3    //TransactionProxyFactoryBean 实际上使用 ProxyFactory 完成 AOP 的基本功能。 
 4    ProxyFactory proxyFactory = new ProxyFactory(); 
 5
 6    if (this.preInterceptors != null) { 
 7        for (int i = 0; i < this.preInterceptors.length; i++) { 
 8            proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.preInterceptors[i])); 
 9        } 
10    } 
11
12    //这里是 Spring 加入通知器的地方 
13    //有两种通知器可以被加入 DefaultPointcutAdvisor 或者 TransactionAttributeSourceAdvisor 
14    //这里把 Spring 处理声明式事务处理的 AOP 代码都放到 ProxyFactory 中去,怎样加入 advisor 我们可以参考 ProxyFactory 的父类 AdvisedSupport() 
15    //由它来维护一个 advice 的链表,通过这个链表的增删改来抽象我们对整个通知器配置的增删改操作。 
16    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor())); 
17
18    if (this.postInterceptors != null) { 
19        for (int i = 0; i < this.postInterceptors.length; i++) { 
20            proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.postInterceptors[i])); 
21        } 
22    } 
23
24    proxyFactory.copyFrom(this); 
25
26    //这里创建 AOP 的目标源 
27    TargetSource targetSource = createTargetSource(this.target); 
28    proxyFactory.setTargetSource(targetSource); 
29
30    if (this.proxyInterfaces != null) { 
31        proxyFactory.setInterfaces(this.proxyInterfaces); 
32    }else if (!isProxyTargetClass()) { 
33        proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass())); 
34    } 
35
36    this.proxy = getProxy(proxyFactory); 
37} 

Spring 已经定义了一个 transctionInterceptor 作为拦截器或者 AOP advice 的实现,在 IOC 容器中定义的其他属性比如transactionManager 和事务管理的属性都会传到已经定义好的 TransactionInterceptor 那里去进行处理。以上反映了基本的 Spring AOP的定义过程,其中 pointcut 和 advice 都已经定义好,同时也通过通知器配置到 ProxyFactory 中去了。

下面让我们回到 TransactionProxyFactoryBean 中看看 TransactionAttributeSourceAdvisor 是怎样定义的,这样我们可以理解具体的属性是怎样起作用,这里我们分析一下类 TransactionAttributeSourceAdvisor:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor { 
 2    //和其他 Advisor 一样,同样需要定义 AOP 中的用到的 Interceptor 和 Pointcut 
 3    //Interceptor 使用传进来的 TransactionInterceptor 
 4    //而对于 pointcut,这里定义了一个内部类,参见下面的代码 
 5    private TransactionInterceptor transactionInterceptor; 
 6
 7    private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut(); 
 8
 9    ...
10
11//定义的 PointCut 内部类 
12private class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { 
13    ...
14    //方法匹配的实现,使用了 TransactionAttributeSource 类 
15    public boolean matches(Method method, Class targetClass) { 
16        TransactionAttributeSource tas = getTransactionAttributeSource(); 
17        //这里使用 TransactionAttributeSource 来对配置属性进行处理 
18        return (tas != null && tas.getTransactionAttribute(method, targetClass) != null); 
19    } 
20    ...省略了 equal,hashcode,tostring 的代码 
21} 

这里我们看看属性值是怎样被读入的:AbstractFallbackTransactionAttributeSource 负责具体的属性读入任务,我们可以有两种读入方式,比如 annotation 和直接配置.我们下面看看直接配置的读入方式,在 Spring 中同时对读入的属性值进行了缓存处理,这是一个decorator 模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1public final TransactionAttribute getTransactionAttribute(Method method, Class targetClass) { 
 2    //这里先查一下缓存里有没有事务管理的属性配置,如果有从缓存中取得 TransactionAttribute 
 3    Object cacheKey = getCacheKey(method, targetClass); 
 4    Object cached = this.cache.get(cacheKey); 
 5    if (cached != null) { 
 6        if (cached == NULL_TRANSACTION_ATTRIBUTE) { 
 7            return null; 
 8        }else { 
 9            return (TransactionAttribute) cached; 
10        } 
11    }else { 
12        // 这里通过对方法和目标对象的信息来计算事务缓存属性 
13        TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass); 
14        //把得到的事务缓存属性存到缓存中,下次可以直接从缓存中取得。 
15        if (txAtt == null) { 
16            this.cache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE); 
17        }else { 
18            ...
19            this.cache.put(cacheKey, txAtt); 
20        } 
21        return txAtt; 
22    } 
23} 

别急,基本的处理在 computeTransactionAttribute()中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1private TransactionAttribute computeTransactionAttribute(Method method, Class targetClass) { 
 2    //这里检测是不是 public 方法 
 3    if(allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { 
 4        return null; 
 5    } 
 6
 7    Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); 
 8
 9    // First try is the method in the target class. 
10    TransactionAttribute txAtt = findTransactionAttribute(findAllAttributes(specificMethod)); 
11    if (txAtt != null) { 
12        return txAtt; 
13    } 
14
15    // Second try is the transaction attribute on the target class. 
16    txAtt = findTransactionAttribute(findAllAttributes(specificMethod.getDeclaringClass())); 
17    if (txAtt != null) { 
18        return txAtt; 
19    } 
20
21    if (specificMethod != method) { 
22        // Fallback is to look at the original method. 
23        txAtt = findTransactionAttribute(findAllAttributes(method)); 
24        if (txAtt != null) { 
25            return txAtt; 
26        } 
27        // Last fallback is the class of the original method. 
28        return findTransactionAttribute(findAllAttributes(method.getDeclaringClass())); 
29    } 
30    return null; 
31} 

经过一系列的尝试我们可以通过 findTransactionAttribute()通过调用 findAllAttribute()得到 TransactionAttribute 的对象,如果返回的是 null,这说明该方法不是我们需要事务处理的方法。

在完成把需要的通知器加到 ProxyFactory 中去的基础上,我们看看具体的看事务处理代码怎样起作用,在TransactionInterceptor 中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1public Object invoke(final MethodInvocation invocation) throws Throwable { 
 2    //这里得到目标对象 
 3    Class targetClass = (invocation.getThis() != null ? invocation.getThis().getClass() : null); 
 4
 5    //这里同样的通过判断是否能够得到 TransactionAttribute 来决定是否对当前方法进行事务处理,有可能该属性已经被缓存, 
 6    //具体可以参考上面对 getTransactionAttribute 的分析,同样是通过 TransactionAttributeSource 
 7    final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass); 
 8    final String joinpointIdentification = methodIdentification(invocation.getMethod()); 
 9
10    //这里判断我们使用了什么 TransactionManager 
11    if (txAttr == null || !(getTransactionManager() instanceof CallbackPreferringPlatformTransactionManager)) { 
12        // 这里创建事务,同时把创建事务过程中得到的信息放到 TransactionInfo 中去 
13        TransactionInfo txInfo = createTransactionIfNecessary(txAttr, joinpointIdentification); 
14        Object retVal = null; 
15        try { 
16            retVal = invocation.proceed(); 
17        }catch (Throwable ex) { 
18            // target invocation exception 
19            completeTransactionAfterThrowing(txInfo, ex); 
20            throw ex; 
21        }finally { 
22            cleanupTransactionInfo(txInfo); 
23        } 
24        commitTransactionAfterReturning(txInfo); 
25        return retVal; 
26    }else { 
27        // 使用的是 Spring 定义的 PlatformTransactionManager 同时实现了回调接口,我们通过其回调函数完成事务处理,就像我们使用编程式事务处理一样。 
28        try { 
29            Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr, new TransactionCallback() { 
30                public Object doInTransaction(TransactionStatus status) { 
31                    //同样的需要一个 TransactonInfo 
32                    TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status); 
33                    try { 
34                        return invocation.proceed(); 
35                    } 
36                    ...这里省去了异常处理和事务信息的清理代码 
37                }); 
38                ...
39            } 
40        } 

这里面涉及到事务的创建,我们可以在 TransactionAspectSupport 实现的事务管理代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1protected TransactionInfo createTransactionIfNecessary(TransactionAttribute txAttr, final String joinpointIdentification) { 
 2    // If no name specified, apply method identification as transaction name. 
 3    if (txAttr != null && txAttr.getName() == null) { 
 4        txAttr = new DelegatingTransactionAttribute(txAttr) { 
 5            public String getName() { 
 6                return joinpointIdentification; 
 7            } 
 8        }; 
 9    } 
10
11    TransactionStatus status = null; 
12    if (txAttr != null) { 
13        //这里使用了我们定义好的事务配置信息,有事务管理器来创建事务,同时返回 TransactionInfo 
14        status = getTransactionManager().getTransaction(txAttr); 
15    } 
16    return prepareTransactionInfo(txAttr, joinpointIdentification, status); 
17} 

首先通过 TransactionManager 得到需要的事务,事务的创建根据我们定义的事务配置决定,在AbstractTransactionManager 中给出一个标准的创建过程,当然创建什么样的事务还是需要具体的PlatformTransactionManager 来决定,但这里给出了创建事务的模板:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { 
 2    Object transaction = doGetTransaction(); 
 3    ...
 4
 5    if (definition == null) { 
 6        //如果事务信息没有被配置,我们使用 Spring 默认的配置方式 
 7        definition = new DefaultTransactionDefinition(); 
 8    } 
 9
10    if (isExistingTransaction(transaction)) { 
11        // Existing transaction found -> check propagation behavior to find out how to behave. 
12        return handleExistingTransaction(definition, transaction, debugEnabled); 
13    } 
14
15    // Check definition settings for new transaction. 
16    //下面就是使用配置信息来创建我们需要的事务;比如传播属性和同步属性等 
17    //最后把创建过程中的信息收集起来放到 TransactionStatus 中返回; 
18    if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { 
19        throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout()); 
20    } 
21
22    // No existing transaction found -> check propagation behavior to find out how to behave. 
23    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) { 
24        throw new IllegalTransactionStateException( 
25        "Transaction propagation 'mandatory' but no existing transaction found"); 
26    }else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || 
27        definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || 
28        definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { 
29        //这里是事务管理器创建事务的地方,并将创建过程中得到的信息放到 TransactionStatus 中去,包括创建出来的事务 
30        doBegin(transaction, definition); 
31        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); 
32        return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null); 
33    }else { 
34        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); 
35        return newTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null); 
36    } 
37} 

接着通过调用 prepareTransactionInfo 完成事务创建的准备,创建过程中得到的信息存储在 TransactionInfo 对象中进行传递同时把信息和当前线程绑定;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1protected TransactionInfo prepareTransactionInfo(TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) { 
 2    TransactionInfo txInfo = new TransactionInfo(txAttr, joinpointIdentification); 
 3    if (txAttr != null) { 
 4        ...
 5        // 同样的需要把在 getTransaction 中得到的 TransactionStatus 放到 TransactionInfo 中来。 
 6        txInfo.newTransactionStatus(status); 
 7    }else { 
 8        ...
 9    } 
10
11    // 绑定事务创建信息到当前线程 
12    txInfo.bindToThread(); 
13    return txInfo; 
14} 

将创建事务的信息返回,然后看到其他的事务管理代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1protected void commitTransactionAfterReturning(TransactionInfo txInfo) { 
2    if (txInfo != null && txInfo.hasTransaction()) { 
3        if (logger.isDebugEnabled()) { 
4            logger.debug("Invoking commit for transaction on " + txInfo.getJoinpointIdentification()); 
5        } 
6        this.transactionManager.commit(txInfo.getTransactionStatus()); 
7    } 
8} 

通过 transactionManager 对事务进行处理,包括异常抛出和正常的提交事务,具体的事务管理器由用户程序设定。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) { 
 2    if (txInfo != null && txInfo.hasTransaction()) { 
 3        if (txInfo.transactionAttribute.rollbackOn(ex)) { 
 4            ...
 5            try { 
 6                this.transactionManager.rollback(txInfo.getTransactionStatus()); 
 7            } 
 8            ...
 9        } else { 
10            ...
11            try { 
12                this.transactionManager.commit(txInfo.getTransactionStatus()); 
13            } 
14            ...
15        } 
16
17        protected void commitTransactionAfterReturning(TransactionInfo txInfo) { 
18        if (txInfo != null && txInfo.hasTransaction()) { 
19            ...
20            this.transactionManager.commit(txInfo.getTransactionStatus()); 
21        } 
22    } 

Spring 通过以上代码对 transactionManager 进行事务处理的过程进行了 AOP 包装,到这里我们看到为了方便客户实现声明式的事务处理,Spring 还是做了许多工作的。如果说使用编程式事务处理,过程其实比较清楚,我们可以参考书中的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1TransactionDefinition td = new DefaultTransactionDefinition(); 
 2TransactionStatus status = transactionManager.getTransaction(td); 
 3try{ 
 4    ...//这里是我们的业务方法 
 5}catch (ApplicationException e) { 
 6    transactionManager.rollback(status); 
 7    throw e 
 8} 
 9transactionManager.commit(status); 
10...

我们看到这里选取了默认的事务配置 DefaultTransactionDefinition,同时在创建事物的过程中得到 TransactionStatus,然后通过直接调用事务管理器的相关方法就能完成事务处理。

声明式事务处理也同样实现了类似的过程,只是因为采用了声明的方法,需要增加对属性的读取处理,并且需要把整个过程整合到 Spring AOP 框架中和 IoC 容器中去的过程。

下面我们选取一个具体的 transactionManager - DataSourceTransactionManager 来看看其中事务处理的实现: 同样的通过使用 AbstractPlatformTransactionManager 使用模板方法,这些都体现了对具体平台相关的事务管理器操作的封装,比如commit:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1public final void commit(TransactionStatus status) throws TransactionException { 
 2    ...
 3    DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status; 
 4    if (defStatus.isLocalRollbackOnly()) { 
 5        ...
 6        processRollback(defStatus); 
 7        return; 
 8    } 
 9    ...
10    processRollback(defStatus); 
11    ...
12} 
13
14processCommit(defStatus); 
15} 

通过对 TransactionStatus 的具体状态的判断,来决定具体的事务处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1private void processCommit(DefaultTransactionStatus status) throws TransactionException { 
 2    try { 
 3        boolean beforeCompletionInvoked = false; 
 4        try { 
 5            triggerBeforeCommit(status); 
 6            triggerBeforeCompletion(status); 
 7            beforeCompletionInvoked = true; 
 8            boolean globalRollbackOnly = false; 
 9            if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) { 
10                globalRollbackOnly = status.isGlobalRollbackOnly(); 
11            } 
12            if (status.hasSavepoint()) { 
13                ...
14                status.releaseHeldSavepoint(); 
15            } else if (status.isNewTransaction()) { 
16                ...
17                doCommit(status); 
18            } 
19            ...
20        } 

这些模板方法的实现由具体的 transactionManager 来实现,比如在 DataSourceTransactionManager:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1protected void doCommit(DefaultTransactionStatus status) { 
 2    //这里得到存在 TransactionInfo 中已经创建好的事务 
 3    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); 
 4
 5    //这里得到和事务绑定的数据库连接 
 6    Connection con = txObject.getConnectionHolder().getConnection(); 
 7    ...
 8    try { 
 9        //这里通过数据库连接来提交事务 
10        con.commit(); 
11    } 
12    ...
13} 
14
15protected void doRollback(DefaultTransactionStatus status) { 
16    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); 
17    Connection con = txObject.getConnectionHolder().getConnection(); 
18    if (status.isDebug()) { 
19        logger.debug("Rolling back JDBC transaction on Connection [" + con + "]"); 
20    } 
21    try { 
22        //这里通过数据库连接来回滚事务 
23        con.rollback(); 
24    } catch (SQLException ex) { 
25        throw new TransactionSystemException("Could not roll back JDBC transaction", ex); 
26    } 
27} 

我们看到在 DataSourceTransactionManager 中最后还是交给 connection 来实现事务的提交和 rollback。整个声明式事务处理是事务处理在 Spring AOP 中的应用,我们看到了一个很好的使用 Spring AOP 的例子,在 Spring 声明式事务处理的源代码中我们可以看到:

  1. 怎样封装各种不同平台下的事务处理代码
  2. 怎样读取属性值和结合事务处理代码来完成既定的事务处理策略
  3. 怎样灵活的使用 SpringAOP 框架。

如果能够结合前面的 Spring AOP 的源代码来学习,理解可能会更深刻些。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/07/29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C++中gRPC:从小白入门到大神精通
在当今分布式系统盛行的时代,高效的通信机制是构建健壮、可扩展软件的关键。gRPC作为一个高性能、开源的远程过程调用(RPC)框架,在C++开发领域中扮演着重要角色。无论是开发微服务架构,还是构建大规模分布式系统,掌握gRPC都能让你的开发工作事半功倍。接下来,让我们一起开启从gRPC小白到大神的学习之旅。
码事漫谈
2025/02/07
8570
C++中gRPC:从小白入门到大神精通
实战|Service Mesh微服务架构实现服务间gRPC通信
大家好!我是"无敌码农"!在前面的文章<<干货|如何步入Service Mesh微服务架构时代>>中介绍了基于Kubernetes及Istio如何一步一步把Service Mesh微服务架构玩起来!在该文章中,我们演示了一个非常贴近实战的案例,这里回顾下该案例的结构,如下图所示:
用户5927304
2021/04/14
1.8K0
Locust完成gRPC协议的性能测试
对于分布式系统而言,不同的服务分布在不同的节点上,一个服务要完成自己的功能经常需要调用其他服务的接口,比如典型的微服务架构。通常这种服务调用方式有两种,一种是发送HTTP请求的方式,另一种则是RPC的方式,RPC是Remote Procedure Call(远程过程调用)的简称,可以让我们像调用本地接口一样使用远程服务。gRPC是一个由 google 推出的、高性能、开源、通用的 rpc 框架。它是基于 HTTP2 协议标准设计开发,默认采用 Protocol Buffers 数据序列化协议,支持多种开发语言。ProtoBuf buffer 是一种数据表达方式,以.proto 结尾的数据文件,可以类比 json、xml 等。
Criss@陈磊
2021/06/10
2K0
Locust完成gRPC协议的性能测试
Rust使用gRPC
需要先安装protoc(Protocol Buffers Compiler),可据此Protobuf Compiler Installation[1]下载
fliter
2024/01/09
2780
Rust使用gRPC
Grpc介绍 — ProToBuf基本使用
RPC(Remote Procedure Call)远程过程调用,关注笔者的同学应该知道之前笔者出过关于Thrift对应的问题,这次主要来说的是Google开源的Grpc,和Thrift有很大的区别Grpc是基于HTTP2.0并且依赖protobuf,为什么又推出关于grpc的文章呢?请大家继续往下看。
喵了个咪233
2019/05/26
1.6K0
gRPC 知多少
当下,基于“微服务”的技术架构体系几乎主宰了整个业务市场,尤其是在云原生生态的拥抱下。无论是基于传统虚拟机生态还是云原生容器生态的现代微服务体系结构中,我们可以根据微服务的交互及通信风格将其划分为两大类:面向外部的微服务和面向内部的微服务。
Luga Lee
2021/11/22
1.4K0
gRPC 知多少
聊聊高性能 RPC框架 gRPC
RPC、gRPC、Thrift、HTTP,大家知道它们之间的联系和区别么?这些都是面试常考的问题,今天带大家先搞懂 RPC 和 gRPC。
码猿技术专栏
2023/05/01
1.9K0
聊聊高性能 RPC框架 gRPC
5分钟学会 gRPC
我猜测大部分长期使用 Java 的开发者应该较少会接触 gRPC,毕竟在 Java 圈子里大部分使用的还是 Dubbo/SpringClound 这两类服务框架。
crossoverJie
2022/10/27
4080
5分钟学会 gRPC
搞懂gRPC支持HTTP进行双协议通信
2)通过 Protocol Buffers 提供强类型接口定义和高效的二进制序列化,减少数据体积;
闫同学
2025/04/18
2470
搞懂gRPC支持HTTP进行双协议通信
protobuf 为经络,gRPC为骨架
以来,数据结构的重要性在任何软件项目中都是毋庸置疑的。但数据结构往往又是最难相处的:
tyrchen
2020/07/23
1.1K0
Go - 关于 proto 文件的一点小思考?
ProtoBuf 是一套接口描述语言(IDL),通俗的讲是一种数据表达方式,也可以称为数据交换格式。
新亮
2021/11/29
4060
Spring Boot+gRPC构建微服务并部署到Istio(详细教程)
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/06/20
2.7K0
Spring Boot+gRPC构建微服务并部署到Istio(详细教程)
从源码透析gRPC调用原理
gRPC是如何work的,清楚的理解其调用逻辑,对于我们更好、更深入的使用gRPC很有必要。因此我们必须深度解析下gRPC的实现逻辑,在本文中,将分别从客户端和服务端来说明gRPC的实现原理。
netkiddy
2018/08/19
18.6K1
从源码透析gRPC调用原理
gRPC 基础概念详解
作者:jasonzxpan,腾讯 IEG 运营开发工程师 gRPC (gRPC Remote Procedure Calls) 是 Google 发起的一个开源远程过程调用系统,该系统基于 HTTP/2 协议传输,本文介绍 gRPC 的基础概念,首先通过关系图直观展示这些基础概念之间关联,介绍异步 gRPC 的 Server 和 Client 的逻辑;然后介绍 RPC 的类型,阅读和抓包分析 gRPC 的通信过程协议,gRPC 上下文;最后分析 grpc.pb.h 文件的内容,包括 Stub 的能力、
腾讯技术工程官方号
2021/07/12
4.2K0
Grpc对象转proto代码工具
虽然Grpc.Tools可以将proto文件自动生成代理类,但是proto文件得手敲,还容易出错,如果接口比较复杂,定义比较多,这就很头疼了
用户8604107
2021/07/02
7260
gRPC java 实战:通过 maven 插件自动根据 proto 文件生成 java 代码
在调研 gRPC java 时遇到一个问题,根据官方文档,没有办法一次性就把示例跑成功。
hugo_lei
2021/08/16
8.2K0
gRPC java 实战:通过 maven  插件自动根据 proto 文件生成 java 代码
springcloud集成grpc(一)
是谷歌开源的一个高性能的、通用的RPC框架。和其他RPC一样,客户端应用程序可以直接调用远程服务的方法,就好像调用本地方法一样。它隐藏了底层的实现细节,包括序列化(XML、JSON、二进制)、数据传输(TCP、HTTP、UDP)、反序列化等,开发人员只需要关自业务本身,而不需要关注RPC的技术细节。
一笠风雨任生平
2019/08/02
3.2K0
【每周一库】- Tonic 基于Rust的gRPC实现
gRPC的rust实现,高性能,开源,为移动设备与HTTP/2准备的通用RPC框架
MikeLoveRust
2020/07/28
1.6K0
gRPC的使用
gRPC是由google开发的,是一款语言中立、平台中立、开源的RPC(Remote Procedure Call,远程过程调用)框架。
xcbeyond
2020/04/01
2.2K0
gRPC的使用
rpc框架之gRPC 学习 - hello world
grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的rpc五花八门,国内比较著名的有百度的sofa-pbrpc,但是遗憾的是soft-pbrpc没有对应的java实现版本。rgpc还有一个独立的官网:http://www.grpc.io/,目前已经支持的语言有 C, C++, Java, Go, Node.js, Python, Ruby, Objective-C
菩提树下的杨过
2018/01/18
2.1K0
rpc框架之gRPC 学习 - hello world
相关推荐
C++中gRPC:从小白入门到大神精通
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验