作者 | java_keith
来源|阿里巴巴云原生公众号

很久没有写技术分享博客,因为发现一个好的工具确实有点忍不住分享一下,毕竟独乐乐不如众乐乐。> 这里需要说的主角就是 Artahs。> Arthas 使用文档很详细,我这里主要记录一下使用 Arthas 的一点总结。

使用背景

在一个大的团队里面,会因为很多历史原因或客观因素导致技术栈并不统一,我们就遇到这么一个问题。老项目是使用 Dubbo 框架的 Dubbo 协议进行服务交互,有新的项目是使用 Springcloud 体系的 Feignclient 框架的 Http 协议进行交互。那么就需要解决两个问题。

  • 问题 1 是 Dubbo 服务需要支持 Dubbo 协议又需要支撑 Http 协议。

  • 问题 2 是 Feignclient 框架能够无损调用 Dubbo 服务的 Http 协议(无损指的是 Dubbo 对 Feignclient 调用方能够做到服务动态感知,负载均衡不需要做二次开发)。

解决思路

有了以上的目标,我们就需要想办法解决问题。解决第一个问题倒是比较容易,Dubbo 本身就提供的 Http 协议暴漏。也就是将老工程 Dubbo 升级、配置两种协议问题一就这么解决了。

但是针对问题 2,我们可以罗列一下遇到的问题。Dubbo 注册使用的是 zk 注册中心,Springcloud 工程使用 Eureka 注册中心。这里顺带也要赞美一下 Feignclient 框架,Feignclient 接入服务的门槛很低,这样兼容了很多语言、环境等带来的差异,也就是说只要是 http 协议的接口 Feignclient 就能调用。到这里实际上通过 Feignclient 直接调用 Dubbo 服务暴漏的 Http 协议接口是能够走的通,只不过没法做到负载均衡,失败转移等能力。说了这么多总结一下吧。

  • 现在通过 Feignclient 直连 Dubbo 框架工程的 Http 协议能够正常执行。

  • 分布式环境下需要解决直连的弊端(无法负载均衡,无法失败转移,无法动态扩容等等) 好在通过分析了 Eureka 源码以后打开了另一个大门,Eureka 实际上是独立的组件,而且提供手动注册服务的能力(即使没有修改源码就有了)。现在解决思路就是在 Dubbo 工程里面引入 Eureka 组件,手动将服务注册到 Eureak 以便 Feignclient 能够无损调用。

主角(Arthas)登场

为了将 Dubbo 框架工程提供注册 Eureka 的能力,并且能够做到优雅上线和下线。我们主要是借助了 Dubbo 的 Spi 扩展能力中的 Container 扩展。代码如下:

class EurekaDubboContainer implements Container {...}

有了以上代码还需要做一件重要的事情,就是声明 Container 的全路径。META-INF/dubbo/org.apache.dubbo.container.Container:xxx=com.xxx.XxxContainer,当时我们配置这里的代码 spring=com.xxx.EurekaDubboContainer,当所有准备好了以后我们启动工程,发现无异常输出,进程完美。但是 Deignclient 怎么也无法调用。最主要是启动过程中没有任何异常输出,经过大量论证后,就在快绝望的时候,我发现了 Arthas,Arthas 可以查看内存中对象属性值以及执行对象的方法,我欣喜若狂。通过之前对 Dubbo 注册过程源码分析:

com.alibaba.dubbo.common.extension.ExtensionLoader#loadFile
} catch (Throwable t) {IllegalStateException e = new IllegalStateException("Failed to load extension class(interface: " + type + ", class line: " + line + ") in " + url + ", cause: " + t.getMessage(), t);exceptions.put(line, e);
}

在 Dubbo 启动过程,会从 Jar 包中扫描配置的 META-INF 中配置的 Container,在加载的时候这个异常是直接存放在了 Loader 类的域中,猜测可能是为了解决 Container 隔离所以异常并没有抛出。当前主要目标还是分析为啥我定义的扩展容易没有启动。部署 Arthas 以后我开始了分析之路。

  • sc -d *.EurekaDubboContainer 发现类已经正常加载,说明有被 Load 加载。

  • jad *.EurekaDubboContainer 发现加载的类代码也是在正常(排除包不对的可能)。

  • ognl ‘#loader=@com.alibaba.dubbo.container.Main@loader,#loader.cachedInstances’ 这里发现了问题,如果是正常被 Load 的 Container 会被存在到 ExtensionLoader 的 CachedInstances 域中(默认的 Spring,log4j存在),但是我自定义的 Container 竟然没找到。

  • ognl ‘#loader=@com.alibaba.dubbo.container.Main@loader,#loader.exceptions’ 这里发现了之所有没有加载成功的原因,在 Exceptions 中有声明。

通过以上分析,问题非常明显了,在 META-INF 中指定的 Key 重复了。还是没深入理解 Dubbo 中的 Spi 文档上的‘xxx’是自定义的意思。到这里修改 Key 以后一切按照计划执行。

结束

通过一波操作,我们发现从技术角度出发,其实没有解决不了的问题,只是需要多想一想,多想想办法总可以找到的。包括使用 Arthas 上 Ognl 如何查看 Load 实例中的非静态域,直接获取是无法获取的,因为没有存在在 Arthas 上下文中,所以变通一下思路:通过 Main 的静态域获取实例,再通过实例变量获取非静态域的值。技术没有终止,愿你我一同进步。为开源贡献微薄的力量。若对细节有兴趣的朋友,可留言交流。

Arthas 有奖征文正在进行中!

为了让更多开发者开始用上 Arthas 这个 Java 诊断神器,今年 3 月 26 日,Arthas 社区联合 JetBrains 推出 Arthas 有奖征文活动:**聊聊这些年你和 Arthas 之间的那些事儿。**活动已进行至第七期,点击链接即可参与:http://alibabacloud.mikecrm.com/9khcRrs,欢迎大家踊跃投稿,参与即有可能获奖!

Arthas 定位 Dubbo 手动注册 Eureka 异常相关推荐

  1. 如何使用Arthas定位线上 Dubbo 线程池满异常

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「Kirito的技术分享」 前言 本文是 ...

  2. Arthas | 定位线上 Dubbo 线程池满异常

    作者 | 徐靖峰  阿里云高级开发工程师 前言 Dubbo 线程池满异常应该是大多数 Dubbo 用户都遇到过的一个问题,本文以 Arthas 3.1.7 版本为例,介绍如何针对该异常进行诊断,主要使 ...

  3. 实战演练:MySQL手动注册binlog文件造成主从同步异常

    m 墨墨导读:本文是作者用MySQL数据库手动注册binlog文件造成主从同步异常后,详述整个分析与解决的过程. 云和恩墨大讲堂线上分享:<weblogic 优化> 时间:2019年7月3 ...

  4. 04_服务注册Eureka

    一.服务注册Eureka基础 1. 微服务的注册中心 注册中心可以说是微服务架构中的"通讯录",它记录了服务和服务地址的映射关系.在分布式架构中, 服务会注册到这里,当服务需要调用 ...

  5. 微服务系列:服务发现与注册-----Eureka(面试突击!你想了解的Eureka都在这里.持续更新中......)

    1.什么是落地SOA(面向服务架构)? SOA面向服务架构,是一种架构思想,是跨语言和平台的.SOA宗旨简单明了,根据项目服务完成架构搭建,以服务为基准点完成组件化和模块化.提供服务是项目的基本内容, ...

  6. 源码分析Dubbo服务注册与发现机制RegistryDirectory)

    RegistryDirectory,基于注册中心的服务发现,本文将重点探讨Dubbo是如何实现服务的自动注册与发现.从上篇文章,得知在消息消费者在创建服务调用器(Invoker)[消费者在初始时]时需 ...

  7. 微服务 注册中心的作用_微服务架构Dubbo之注册中心(Zookeeper)

    注册中心简介 在微服务架构中,注册中心是核心的基础服务之一.在微服务架构流行之前,注册中心就已经开始出现在分布式架构的系统中.Dubbo是一个在国内比较流行的分布式框架,被大量的中小型互联网公司所采用 ...

  8. 手动删除eureka多余服务

    本文记录一下如何手动删除eureka注册中心多余服务的方法. 使用postman 调用delete接口删除服务,详细信息如下:

  9. Spring 手动注册bean

    一般情况下,我们Spring应用中的bean都是通过注解或者xml注入到容器中的,有些情况下我们可能想手动往容器中注入bean,即编程方式注入bean. 本文所使用源码包版本:spring-beans ...

最新文章

  1. 23种设计模式的基本介绍
  2. 上汽接入Momenta飞轮,成为中国第一个落地RoboTaxi的车企
  3. 内核 kmap_atomic分析
  4. BZOJ 4388 [JOI2012春季合宿]Invitation (线段树、二叉堆、最小生成树)
  5. 递归 递归的案例 递归的案例
  6. 大话ion系列(三)
  7. c语言从入门到精通ppt,C语言从入门到精通第1章.ppt
  8. hive遍历_从Hive中的stored as file_foramt看hive调优
  9. PyTorch实现的李沐《动手学深度学习》,登上GitHub热榜,获得1000+星
  10. linux主备网卡切换脚本,Keepalived主备切换时执行脚本
  11. SqlServer两表之间:根据一个表的字段更新另一个表的字段
  12. Spark2.2(三十九):如何根据appName监控spark任务,当任务不存在则启动(任务存在当超过多久没有活动状态则kill,等待下次启动)...
  13. 拓端tecdat|把握出租车行驶的数据脉搏 :出租车轨迹数据给你答案!
  14. nas 和 远程文件夹同步_群晖NAS同步文件夹功能打开有什么需要注意的?
  15. zepto 清除html,Zepto的使用
  16. Linux 系统的安全加固
  17. Python3 post请求上传文件
  18. 北京科技计算机类好不好,北京信息科技大学怎么样 在全国排名多少好不好
  19. cf登录服务器未响应,大神详解win7系统玩cf未响应的图文方法
  20. [BAPI]如何读取采购订单PO审批状态数据-[BAPI_PO_GETRELINFO]

热门文章

  1. 4.等待链表与调度链表
  2. MySQL客户端和服务器端工具集
  3. 【Web】HTTPS 引入http资源,混合内容
  4. 1、CSS 定位 (Positioning)
  5. 1.4 super关键字详解
  6. Java非线程安全问题的解决方法
  7. ACM入门之【分块习题】
  8. linux 命令 单词,linux中常用的命令相对应的单词
  9. 在C盘和D盘执行php 结果不同,window_双系统电脑给C盘扩容后导致D盘Win10引导项丢失该怎么办?,为了写个经验,特意把C盘用无 - phpStudy...
  10. unittest 多个测试文件只开一次浏览器_接口测试平台代码实现75: 多接口用例15