背景
时光荏苒,进入阿里中间件团队曾经快两年工夫了。这期间,有幸参加了第四届中间件性能挑战赛的题目组,筹备了以“Dubbo Mesh”为主题的初赛题;和团队一起发展了 Dubbo 线下 meetup 流动;将阿里多年双 11 积攒的中间件基础设施最佳实际和方法论,通过阿里云的商业化产品,为宽广开发者和企业提供服务。很庆幸能有这样一段难忘的经验。回想起来,能进入中间件团队,和我当初的一个 Github 我的项目还有关系。明天把该我的项目分享给大家。
Q: 什么是中间件团队?
A: 阿里巴巴中间件技术部,是世界顶尖的 Java 技术团队之一,起源于淘宝平台架构组,是跟随着阿里电商业务和双十一成长起来的技术团队,解决简单的业务场景、飞速的业务增长、高并发的大促洪峰、层出不穷的稳定性问题。产品包含高分布式 RPC 服务框架、高牢靠分布式消息中间件、分布式数据层、海量数据存储、实时计算、零碎性能优化、架构高可用等几大畛域的多个产品,这些产品撑持阿里巴巴团体(淘宝、天猫、聚划算、1688、菜鸟)的所有交易和非交易业务零碎,坦然安稳度过双十一 917 亿交易成交的挑战。咱们开源的中间件组件 Dubbo、Rocketmq、Nacos、tengine、Seata 等都被很多企业和集体在应用。
来自中间件的邀请
2019 年的时候,我率领团队对后端架构进行了微服务重构。选型时应用了 Dubbo 框架。得益于 Dubbo 的高性能,应用简略和高扩展性,微服务革新很顺利,公司的业务也越来越稳固。我对 Dubbo 也产生了浓重的趣味,心愿能够更深刻地理解这个优良的 RPC 框架。我钻研了下 Dubbo 的源码,本人从零开始编写了一个 mini 版的 Dubbo。
恰好时值阿里又重启了 Dubbo 我的项目,且成为 Apache 的孵化我的项目(编写文本时已正式成为 Apache 我的项目)。Dubbo 新的官网有一个“Wanted: who’s using dubbo”页面,我也留下了本人的信息,来给 Dubbo 点个赞。其中蕴含了 mini 版 Dubbo 的我的项目地址。
其实是很随便的一个行动,没想到会产生前面的故事。一个小时后,我收到了一封邮件:
这是一封来自中间件团队 Dubbo 负责人的邮件。过后感觉挺意外的,也很欣慰。中间件团队始终是我认为技术和影响力都很强的团队,如果能够退出该团队,是一个很好的机会。
于是接下来就是例行的投简历,面试流程。要吐槽下阿里的面试流程,前后历时快两个月了,一共有五轮,真的是持久战呀。面试的时候,面试官问了一些对于 mini Dubbo 的问题。后果还不错,很幸运的通过了面试,正式退出中间件的 Dubbo 团队。起初听我的老板说,当初是因为对我的 mini Dubbo 我的项目感兴趣,才有了面试邀约。
iris
mini 版 Dubbo 的我的项目地址为:https://github.com/vangoleo/iris-java。我给它取名为 iris。
iris 是一个轻量级,微内核加插件机制,基于 Java 的 RPC 框架。提供服务注册,发现,负载平衡,反对 API 调用,Spring 集成和 Spring Boot starter 应用。
有如下个性:
- 网络通信: Netty4。
- 注册核心: 可扩大,已反对 etcd。
- 动静代理: byte-buddy。
- 序列化: Protobuff(Protostuff)。
- 能够脱离 Spring,提供 API 调用。本人实现了 IoC 容器。
- 集成 Spring,提供 XML,Java 配置。
- 提供 Spring Boot Starter(开发该我的项目时,Dubbo 官网还不反对 Spring Boot Starter)。
- 提供 SPI 机制,实现微内核加插件的架构。实现可扩大,开发者能够为 iris 开发组件,以插件的模式集成到 iris 中。插件的加载应用另一个微容器框架见 coco 我的项目。该我的项目 fork 于阿里的 cooma。
阐明:iris 齐全是我集体学习的我的项目,麻雀虽小,五脏俱全,涵盖了 RPC 框架的基本功能。它只是实现了从 0 到 1,然而从 1 到 100 还有很多的事件须要去做。
如何应用
iris 反对以下应用形式:
- 原生 API 模式,不依赖 Spring, 非 Spring 我的项目也能够应用。
- Spring 配置形式,和 Spring 很好的集成。
- Spring Boot 配置形式,提供了一个 spring boot starter,以主动配置,疾速启动。
API 应用
Iris 外围代码不依赖 Spring,可脱离 Spring 应用。
第一步 :启动 etcd 注册核心
编写一个接口 IHelloService
public interface IHelloService {String hello(String name);
}
第二步:编写一个 IHelloService 的实现
public class HelloService implements IHelloService {
@Override
public String hello(String name){return "Hello," + name;}
}
第三步:启动 Server
IRegistry registry = new EtcdRegistry("http://127.0.0.1:2379");
RpcServer server = new RpcServer(registry)
.port(2017)
.exposeService(IHelloService.class,new HelloService());
server.run();
第四步:启动 client
RpcClient client = new RpcClient(registry);
IHelloService helloService = client.create(IHelloService.class);
String s = helloService.hello("leo");
System.out.println(s); // hello, leo
第五步 :试着进行 server
因为服务没有 provider,client 报错找不到 provider
第六步:启动 server
Server 启动后,会去 etcd 注册核心注册服务,client 端马上失常工作。
Spring 配置形式
第一步 :编写服务提供者
服务提供者,应用自定义注解 @Service 来裸露服务,通过 interfaceClass 来指定服务的接口。该 @Service 注解是 iris 提供的,并非 Spring 的注解。
@Service(interfaceClass = IHelloService.class)
public class HelloService implements IHelloService {
@Override
public String hello(String name) throws Exception {return "hello" + name;}
}
第二步 :编写服务消费者
服务使用者,通过 @Reference 来援用近程服务,就像应用本地的 SpringBean 一样。背地的 SpringBean 封装和 Rpc 调用对开发者通明。应用体验和 Dubbo 是一样的。
public class Baz {@Reference(interfaceClass = IHelloService.class)
private IHelloService helloService;
public void hello(String name) throws Exception {System.out.println(helloService.hello(name));
}
}
第三步 :配置 Spring Bean
配置服务提供者,本例子应用 XML 配置,应用 Java Code 配置也能够。
<bean id="registry" class="com.leibangzhu.iris.registry.EtcdRegistry">
<constructor-arg name="registryAddress" value="http://127.0.0.1:2379"></constructor-arg>
</bean>
<bean id="server" class="com.leibangzhu.iris.server.RpcServer">
<constructor-arg name="registry" ref="registry"></constructor-arg>
</bean>
<bean id="serviceAnnotationBeanPostProcessor" class="com.leibangzhu.iris.spring.ServiceAnnotationBeanPostProcessor"></bean>
<bean id="helloService" class="com.leibangzhu.iris.spring.HelloService"></bean>
第四步:配置服务消费者,本例子应用 XML 配置,应用 Java Code 配置也能够。
<bean id="registry" class="com.leibangzhu.iris.registry.EtcdRegistry">
<constructor-arg name="registryAddress" value="http://127.0.0.1:2379"></constructor-arg>
</bean>
<bean id="client" class="com.leibangzhu.iris.client.RpcClient">
<constructor-arg name="registry" ref="registry"></constructor-arg>
</bean>
<bean id="referenceAnnotationBeanPostProcessor" class="com.leibangzhu.iris.spring.ReferenceAnnotationBeanPostProcessor"></bean>
<bean id="foo" class="com.leibangzhu.iris.spring.Baz"></bean>
Spring Boot 配置
应用原生的 Spring 配置还是有些繁琐,能够应用 Spring Boot 来取得更好的开发体验。
第一步:编写服务提供者
@Service(interfaceClass = IHelloService.class)
public class HelloService implements IHelloService {
@Override
public String hello(String name) throws Exception {return "Hello," + name + ", from com.leibangzhu.iris.springboot.HelloService";}
}
第二步:编写服务消费者
@Component
public class Foo {@Reference(interfaceClass = IHelloService.class)
private IHelloService helloService;
public String hello(String name) throws Exception {return helloService.hello(name);
}
}
第三步:在 application.properties 文件中配置服务提供者
iris.registry.address=http://127.0.0.1:2379
iris.server.enable=true
iris.server.port=2017
iris.annotation.package=com.leibangzhu.iris.springboot
第四步:在 application.properties 文件中配置服务消费者
iris.registry.address=http://127.0.0.1:2379
iris.client.enable=true
应用 SpringBoot 时,不许再手动配置相干的 spring bean,Iris 提供的 spring boot starter 会主动配置好这些 spring bean。