架构设计91-闲聊03-01.记一次Dubbo升级

简介: 架构设计91-闲聊03-01.记一次Dubbo升级

架构设计系列文章,请参见连接。

背景

公司有一批15年左右实现的中台服务,当时使用的是JDK1.7+Gradle3.7实现的。这套微服务现在还是公司的业务主力,经过5年做左右的积累这些服务已经复杂的不可修改了。基于此公司准备对这批服务进行重构。重构的第一步肯定是进行技术升级。

过程

在进行技术升级的时候,公司对微服务进行技术升级的时候规划了几个步骤:

  1. 升级JDK。将JDK从1.7升级到1.8。
  2. 升级Dubbo。将Dubbo从2.5.3升级到2.7.3
  3. 升级到Spring Cloud。
  4. 使用容器管理服务。
  5. 上云原生应用。

做好计划之后,进行具体的升级工作:

  • 进行JDK的升级

修改Gradle的build文件中的Jdk版本到

    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8

然后进行编译,编译完发不到测试环境都挺顺利的。在测试环境上运行起来之后就发现:

java.lang.ClassNotFoundException: javassist.ClassPath

调查发现Dubbo2.5.3使用的org.javassist的包版本是3.15.0-GA。而这个版本在JDK1.8上不可运行。这出发了一个不可接受的问题,Dubbo2.5.3不可以在JDK1.8上运行。一般开源的服务都会对不同的JDK版本进行适配与支持,现在Dubbo2.5.3已经突破了底线了。

既然发现了这个问题,那就把第二步要做的升级Dubbo的事情一起做了吧。对Dubbo进行升级,升级到2.7.3版本:

  1. 修改gradle的build文件中的Dubbo到2.7.3:
com.alibaba:dubbo:2.5.3   -> org.apache.dubbo:dubbo:2.7.3
  1. 修改Dubbo的xml配置文件中
http://code.alibabatech.com/schema/dubbo -> http://dubbo.apache.org/schema/dubbo

http://code.alibabatech.com/schema/dubbo/dubbo.xsd -> http://dubbo.apache.org/schema/dubbo/dubbo.xsd
  1. 修改Dubbo配置中的。因为logger从下升级的话可能不可使用,所以需要使用制定logger。
<dubbo:application name="uc" logger="slf4j"/>
  1. 修改代码中使用dubbo的代码
com.alibaba.dubbo.common.utils.StringUtils
com.alibaba.dubbo.common.utils.CollectionUtils

到此就可以跑起来了。然后升级的服务和其他的服务之间的rpc通信也没有断。所以在这个过程中可以看到dubbo版本之间是可以兼容的。

在跑了两天之后发现一个问题,在做一个业务的时候无缘无故的发生了rollback问题。所有的异常在代码中都已经try-catch了,为什么会发生rollback问题呀。而且还是在两个服务通过rpc之间传递了rollback异常:

[DubboServerHandler-0.0.0.0:20880-thread-305] [ERROR] [o.a.d.r.f.ExceptionFilter$ExceptionListener] - [ [DUBBO] Got unchecked and undeclared exception which called by 0.0.0.0. service: cn.thinkjoy.uc.service.business.IUserService, method: saveUser, exception: org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only, dubbo version: 2.7.3, current host: 0.0.0.0]
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:720) ~[spring-tx-4.1.0.RELEASE.jar:4.1.0.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:496) ~[spring-tx-4.1.0.RELEASE.jar:4.1.0.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276) ~[spring-tx-4.1.0.RELEASE.jar:4.1.0.RELEASE]
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) ~[spring-tx-4.1.0.RELEASE.jar:4.1.0.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.16.RELEASE.jar:4.3.16.RELEASE]
        at com.sun.proxy.$Proxy70.saveUser(Unknown Source) ~[na:na]

无奈只能去查看Spring Tx的代码,发现与异常对应的点为UnexpectedRollbackException的位置:

    @Override
    public final void commit(TransactionStatus status) throws TransactionException {
        if (status.isCompleted()) {
            throw new IllegalTransactionStateException(
                    "Transaction is already completed - do not call commit or rollback more than once per transaction");
        }

        DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
        if (defStatus.isLocalRollbackOnly()) {
            if (defStatus.isDebug()) {
                logger.debug("Transactional code has requested rollback");
            }
            processRollback(defStatus);
            return;
        }
        if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
            if (defStatus.isDebug()) {
                logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
            }
            processRollback(defStatus);
            // Throw UnexpectedRollbackException only at outermost transaction boundary
            // or if explicitly asked to.
            if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
                throw new UnexpectedRollbackException(
                        "Transaction rolled back because it has been marked as rollback-only");
            }
            return;
        }

        processCommit(defStatus);
    }

那就是只能说记录了在业务流程中发生了异常,那就需要进一步查看上面打印出来的异常。rollback之前还是有一个异常的:

org.apache.dubbo.rpc.RpcException: No provider available from registry 127.0.0.1:2181 for service xx.XXX.xxx on consumer 0.0.0.0 use dubbo version 2.7.3, please check status of providers(disabled, not registered or in blacklist).

查看代码发现:

        try {
            XXX.xxxx(xxx, xxx);
        } catch (RpcException e) {
            LOGGER.error("调用异常" + xxx, e);
        }

为啥这个异常捕获没有捕获到。调查发现:RpcException的import是com.alibaba.dubbo.rpc.RpcException。但现在使用的是org.apache的dubbo。所以获取到,导致异常从这段代码的方法中抛出到外部。修改catch中的捕获变为Throwable就解决了问题。

总结

Dubbo对于底层运行环境的依赖过于的强,导致升级jdk的时候必须升级Dubbo版本。如果不同的Dubbo版本之前序列化和反序列化出现问题,那就可以不用玩了。如果利用一些Dubbo的特性在过程中传输一些上下文信息,那也不要玩了。

升级一个jdk牵扯出来这么多dubbo的事情为啥感觉这么不能接受呢。因为同样的环境下我们还用了spring 4.1.0,然后升级完jdk之后spring没有任何反应者多爽呢。

目录
相关文章
|
2月前
|
存储 监控 安全
360 企业安全浏览器基于阿里云数据库 SelectDB 版内核 Apache Doris 的数据架构升级实践
为了提供更好的日志数据服务,360 企业安全浏览器设计了统一运维管理平台,并引入 Apache Doris 替代了 Elasticsearch,实现日志检索与报表分析架构的统一,同时依赖 Doris 优异性能,聚合分析效率呈数量级提升、存储成本下降 60%....为日志数据的可视化和价值发挥提供了坚实的基础。
360 企业安全浏览器基于阿里云数据库 SelectDB 版内核 Apache Doris 的数据架构升级实践
|
2月前
|
存储 缓存 关系型数据库
鱼和熊掌如何兼得?一文解析RDS数据库存储架构升级
阿里云RDS率先推出新型存储类型通用云盘,提供低延迟、低成本、高持久性的用户体验。
鱼和熊掌如何兼得?一文解析RDS数据库存储架构升级
|
2月前
|
Cloud Native 关系型数据库 分布式数据库
阿里云瑶池助力九州通B2B电商平台,完成100%云原生架构升级
九州通数字化转型,通过引入阿里云云原生数据库PolarDB,云原生内存数据库Tair等产品,完美支撑了医药电商平台数据库100%云原生化,实现了统一、高效、标准化和可跟踪的B2B医药平台。
418 4
|
2月前
|
Dubbo Cloud Native 网络协议
【Dubbo3技术专题】「服务架构体系」第一章之Dubbo3新特性要点之RPC协议分析介绍
【Dubbo3技术专题】「服务架构体系」第一章之Dubbo3新特性要点之RPC协议分析介绍
55 1
|
2月前
|
Dubbo Java 应用服务中间件
阿里巴巴资深架构师深度解析微服务架构设计之SpringCloud+Dubbo
软件架构是一个包含各种组织的系统组织,这些组件包括Web服务器,应用服务器,数据库,存储,通讯层),它们彼此或和环境存在关系。系统架构的目标是解决利益相关者的关注点。
|
7天前
|
消息中间件 Java 测试技术
Java中的软件架构重构与升级策略
Java中的软件架构重构与升级策略
|
2月前
|
存储 Cloud Native 对象存储
AutoMQ:如何基于阿里云计算与存储产品实现云原生架构升级
AutoMQ[1] 是新一代基于共享存储架构实现的云原生 Kafka。得益于其存算分离的共享存储架构,通过和阿里云合作,深度使用阿里云可靠、先进的云服务如对象存储OSS、块存储 ESSD、弹性伸缩ESS以及抢占式实例实现了相比 Apache Kafka 10倍的成本优势并且提供了自动弹性的能力。
84069 25
AutoMQ:如何基于阿里云计算与存储产品实现云原生架构升级
|
8天前
|
缓存 Devops 微服务
微服务01好处,随着代码越多耦合度越多,升级维护困难,微服务技术栈,异步通信技术,缓存技术,DevOps技术,搜索技术,单体架构,分布式架构将业务功能进行拆分,部署时费劲,集连失败如何解决
微服务01好处,随着代码越多耦合度越多,升级维护困难,微服务技术栈,异步通信技术,缓存技术,DevOps技术,搜索技术,单体架构,分布式架构将业务功能进行拆分,部署时费劲,集连失败如何解决
|
2月前
|
弹性计算 运维 监控
【阿里云弹性计算】从物理机到阿里云ECS:企业IT架构转型升级之路
【5月更文挑战第29天】随着云计算兴起,企业正转向阿里云ECS以应对传统物理机的挑战。本文详述了这一转型过程,包括现状评估、迁移计划制定、测试环境搭建、应用数据迁移及后期监控优化。转型升级可提升资源利用率,降低运维成本,加快业务响应,并增强数据安全。示例代码展示了使用阿里云Python SDK创建ECS实例的过程。
162 1
|
2月前
|
存储 弹性计算 Cloud Native
AutoMQ:如何基于阿里云计算与存储产品实现云原生架构升级
AutoMQ:如何基于阿里云计算与存储产品实现云原生架构升级