背景
时光荏苒,进入阿里中间件团队曾经快两年工夫了。这期间,有幸参加了第四届中间件性能挑战赛的题目组,筹备了以“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"; }}
第二步:编写服务消费者
@Componentpublic 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:2379iris.server.enable=trueiris.server.port=2017iris.annotation.package=com.leibangzhu.iris.springboot
第四步:在application.properties文件中配置服务消费者
iris.registry.address=http://127.0.0.1:2379iris.client.enable=true
应用SpringBoot时,不许再手动配置相干的spring bean,Iris提供的spring boot starter会主动配置好这些spring bean。