背景

时光荏苒,进入阿里中间件团队曾经快两年工夫了。这期间,有幸参加了第四届中间件性能挑战赛的题目组,筹备了以“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。