京东高级开发分享:《记一次 Java 动态代理实践》!

导语: 在Java生态中,我们经常直接或者间接的用到动态代理,比如通过动态代理调用远程服务,再比如通过动态代理实现解耦。本文结合京东服务框架JSF,讲述京东使用动态代理进行抽象的一次实践,以达到升级数据库访问层的目的。

刘世杰,京东商城Java高级开发工程师,一直从服务端研发工作,目前主要负责京东海外站商品主数据基础服务。个人喜欢读源码,注重细节,有些许代码洁癖。对高可用、高性能、高并发方面的技术保持持续关注。

1. 背景

最近在做数据库(MySQL)方面的升级改造。现状是数据库同时被多个应用直连,存在了一些问题:

有大量的重复代码,维护成本较高,也不优雅;

出现SQL语句质量的问题无法很快定位到是哪个应用导致的;

数据库调用方过于分散,不便于统一控制,比如部分业务数据的读写、屏蔽等;

业务的发展,有的表数据量已经到了一定的规模,几百万到几千万不等,数据库存储拆分是必须要进行的事情。

解决问题的方式很简单,就是把各应用中与此业务相关的dao层抽象成为一个单独应用(以下称为internal-rpc-app),进行统一管理。

2. 具体实现

具体的业务应用与internal-rpc-app的内部通信使用公司内部具有服务治理功能的RPC框架JSF,JSF是一款稳定高效的框架,它对服务治理的粒度是接口,接口通过Spring做服务的发布和调用配置。每个接口对应一个数据表的CURD及特殊业务。

2.1 标准版本 1.0

2.1.1. 接口注册申请

注册接口: com.jd.xx.BizRpcService1

注册接口: com.jd.xx.BizRpcService2

注册接口: com.jd.xx.BizRpcService3

......

注册接口: com.jd.xx.BizRpcServiceN

2.1.2. 服务提供方配置

......

2.1.3. 客户端调用方配置

......

2.1.4 小结

此版本实现了我们的最初的目的,但是有一个不太好的地方,就是配置的工作量太高,前面有说到JSF框架的治理维度是接口。这也意味着,每次新增接口都要提交申请操作,同时要在consumer和provider做相对应的配置,几个还好,如果数据表有几十个上百个,重复的工作量就很大。同时内部接口也不需要做太细粒度的服务治理。于是有了第二版,主要目的是简化大量重复配置。

2.2 优化调用体验版本2.0

2.2.1 内部实现 - 客户端

首先定义调用API:

BizRpcService1 bizRpcService1 = InternalPrxoyServices.BizRpcService1;

bizRpcService1.method1(param1, param2);

InternalPrxoyServices 关键代码:

BizProxyRpcService1 关键代码:

BaseProxyService 关键代码:

京东高级开发分享:《记一次 Java 动态代理实践》!_第1张图片

InternalRpcService 接口定义:

2.2.2 内部实现-服务端

服务端实现比较简单,直接根据接口传过来当serviceName、methodName、objects即可定位到具体service到方法,直接执行即可。

2.2.3 小结

到这里,我们通过静态代理实现了具体的目标,通过实现具体的接口类。我们不再需要定义过多的配置了,客户端调用也变得简单明了。

那么,结束了吗?并没有,在解决了大量配置的问题的同时,因为要写大量的代理类,又引入了新的工作量。

2.3 最终版本3.0

在这一版,我们很自然的引入了动态生成代理。

2.3.1 客户端具体实现

因为引入了动态代理,所以要重新改写 InternalPrxoyServices :

ProxyServiceFactory 关键代码:

InternalRpcProxy 关键代码:

2.4 小结

至此,已经解决了2.2.3提到的大量创建代理类的问题。 当然我们还做了很多文章中没有提及的事情,比如:

通过声明哪些接口可以走动态代理

方法重名、客户端接口合法性等校验

将method存入缓存

3. 总结

通过建立独立的应用,解决了前面数据库被多应用读写所产生的问题,通过开发了统一接口解决了服务端和客户端配置过多的问题。代码经过一步步抽象后,最终发现实现了一个简单的RPC雏形,只不过通信层是基于公司的JSF框架。 这引发了一些框架方面的思考:

是否应该去掉人工审批类似的流程?

是否应该允许更灵活的发布服务?比如:根据注解自动扫描发布服务、根据注解自动获取服务。

这不是技术问题,而是怎么权衡的问题。

福利:

1、具有1-5工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的。

2、在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的。

3、如果没有工作经验,但基础非常扎实,对java工作机制,常用设计思想,常用java开发框架掌握熟练的。

4、觉得自己很牛B,一般需求都能搞定。但是所学的知识点没有系统化,很难在技术领域继续突破的。

5、java高级架构群:725633148 备注好信息!

6、Java高级大牛直播讲解知识点,分享知识,多年工作经验的梳理和总结 带着大家全面 科学地建立自己的技术体系和技术认知!

京东高级开发分享:《记一次 Java 动态代理实践》!_第2张图片
京东高级开发分享:《记一次 Java 动态代理实践》!_第3张图片
京东高级开发分享:《记一次 Java 动态代理实践》!_第4张图片
京东高级开发分享:《记一次 Java 动态代理实践》!_第5张图片
京东高级开发分享:《记一次 Java 动态代理实践》!_第6张图片
京东高级开发分享:《记一次 Java 动态代理实践》!_第7张图片
京东高级开发分享:《记一次 Java 动态代理实践》!_第8张图片

最后:觉得有收获的点点关注转发收藏一波

以上课程体系是我总结出来并且是比较全面的Java架构师必学的课程题系图,此图分为七大板块,每个专题每个知识点都对应着我们平常在工作中用到的技术要点,如果你们想提升自己的技术,想学习以上的技术要点,你们可以加群获取,在此我向大家推荐一个交流学习群:725633148。里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。

你可能感兴趣的:(京东高级开发分享:《记一次 Java 动态代理实践》!)