Arthas 定位 Dubbo 手动注册 Eureka 异常
作者 | 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 异常相关推荐
- 如何使用Arthas定位线上 Dubbo 线程池满异常
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「Kirito的技术分享」 前言 本文是 ...
- Arthas | 定位线上 Dubbo 线程池满异常
作者 | 徐靖峰 阿里云高级开发工程师 前言 Dubbo 线程池满异常应该是大多数 Dubbo 用户都遇到过的一个问题,本文以 Arthas 3.1.7 版本为例,介绍如何针对该异常进行诊断,主要使 ...
- 实战演练:MySQL手动注册binlog文件造成主从同步异常
m 墨墨导读:本文是作者用MySQL数据库手动注册binlog文件造成主从同步异常后,详述整个分析与解决的过程. 云和恩墨大讲堂线上分享:<weblogic 优化> 时间:2019年7月3 ...
- 04_服务注册Eureka
一.服务注册Eureka基础 1. 微服务的注册中心 注册中心可以说是微服务架构中的"通讯录",它记录了服务和服务地址的映射关系.在分布式架构中, 服务会注册到这里,当服务需要调用 ...
- 微服务系列:服务发现与注册-----Eureka(面试突击!你想了解的Eureka都在这里.持续更新中......)
1.什么是落地SOA(面向服务架构)? SOA面向服务架构,是一种架构思想,是跨语言和平台的.SOA宗旨简单明了,根据项目服务完成架构搭建,以服务为基准点完成组件化和模块化.提供服务是项目的基本内容, ...
- 源码分析Dubbo服务注册与发现机制RegistryDirectory)
RegistryDirectory,基于注册中心的服务发现,本文将重点探讨Dubbo是如何实现服务的自动注册与发现.从上篇文章,得知在消息消费者在创建服务调用器(Invoker)[消费者在初始时]时需 ...
- 微服务 注册中心的作用_微服务架构Dubbo之注册中心(Zookeeper)
注册中心简介 在微服务架构中,注册中心是核心的基础服务之一.在微服务架构流行之前,注册中心就已经开始出现在分布式架构的系统中.Dubbo是一个在国内比较流行的分布式框架,被大量的中小型互联网公司所采用 ...
- 手动删除eureka多余服务
本文记录一下如何手动删除eureka注册中心多余服务的方法. 使用postman 调用delete接口删除服务,详细信息如下:
- Spring 手动注册bean
一般情况下,我们Spring应用中的bean都是通过注解或者xml注入到容器中的,有些情况下我们可能想手动往容器中注入bean,即编程方式注入bean. 本文所使用源码包版本:spring-beans ...
最新文章
- 23种设计模式的基本介绍
- 上汽接入Momenta飞轮,成为中国第一个落地RoboTaxi的车企
- 内核 kmap_atomic分析
- BZOJ 4388 [JOI2012春季合宿]Invitation (线段树、二叉堆、最小生成树)
- 递归 递归的案例 递归的案例
- 大话ion系列(三)
- c语言从入门到精通ppt,C语言从入门到精通第1章.ppt
- hive遍历_从Hive中的stored as file_foramt看hive调优
- PyTorch实现的李沐《动手学深度学习》,登上GitHub热榜,获得1000+星
- linux主备网卡切换脚本,Keepalived主备切换时执行脚本
- SqlServer两表之间:根据一个表的字段更新另一个表的字段
- Spark2.2(三十九):如何根据appName监控spark任务,当任务不存在则启动(任务存在当超过多久没有活动状态则kill,等待下次启动)...
- 拓端tecdat|把握出租车行驶的数据脉搏 :出租车轨迹数据给你答案!
- nas 和 远程文件夹同步_群晖NAS同步文件夹功能打开有什么需要注意的?
- zepto 清除html,Zepto的使用
- Linux 系统的安全加固
- Python3 post请求上传文件
- 北京科技计算机类好不好,北京信息科技大学怎么样 在全国排名多少好不好
- cf登录服务器未响应,大神详解win7系统玩cf未响应的图文方法
- [BAPI]如何读取采购订单PO审批状态数据-[BAPI_PO_GETRELINFO]
热门文章
- 4.等待链表与调度链表
- MySQL客户端和服务器端工具集
- 【Web】HTTPS 引入http资源,混合内容
- 1、CSS 定位 (Positioning)
- 1.4 super关键字详解
- Java非线程安全问题的解决方法
- ACM入门之【分块习题】
- linux 命令 单词,linux中常用的命令相对应的单词
- 在C盘和D盘执行php 结果不同,window_双系统电脑给C盘扩容后导致D盘Win10引导项丢失该怎么办?,为了写个经验,特意把C盘用无 - phpStudy...
- unittest 多个测试文件只开一次浏览器_接口测试平台代码实现75: 多接口用例15