读完本章,你会对dubbo有个整体的认识。
首先要理解一个概念,本地调用和远程调用。同服务之间的方法调用本地调用。不同服务之间的方法调用就是远程调用。
服务的提供者
先说作为服务的提供者,需要提供对外暴漏的接口,以及实现接口的方法。
作为服务端如何能被消费者找到呢?
方法如何被调用呢?当然是通过数据的传输进行调用了,无论是基于http方式的rpc调用,还是使用tcp方式的调用,都是将消费者端的请求发送到了服务端,对请求的内容做处理,找对要调用的方法,然后执行,执行完把数据返回给消费者端,这就是完整的一次远程调用。 这里数据的传输和处理常用的http方式的tomcat为代表的,tcp处理方式的netty为代表。为了让服务端的可以接受请求,这就需要把自己的IP和端口暴漏出去。 假如通过的是tomcat的方式来暴漏服务,指定启动的端口号,这个端口号就是消费者端要调用的。
tomcat启动之后,需要配置一下处理请求,这里就是处理消费者请求,并且返回处理结果的地方。就是写一个servlet,配置一下拦截规则。
如何找到方法并执行呢?这里就要谈一谈消费者传输数据的内容了。当我们要执行一个方法,必备的内容是,要执行的对象,方法,参数类型,参数值。这四个部分组成。用一个对象来表示就是这个类有这四个属性。 消费者把要调用的对象发送给服务端,服务端根据提供的这些内容来找到对应的方法去执行。 当然仅仅是有这几个内容还是不够的,服务端需要知道具体执行的是哪个类,同一个接口可能有多个实现类,所以这就需要将接口和对应的实现类记录起来,这样在消费者调用对应接口的时候,就可以找到对应的实现类。通过反射的方式执行对应的方法。
这里又引出几个问题?
一个服务如果支持多版本的话,就需要在服务查询的时候把版本号加上。
接下来说说消费者端。
消费者
消费者端要和服务者保持一致,使用相同的协议,服务者端使用了HTTP协议,使用tomcat暴漏服务和处理数据,那么消费者端也必须使用相同的协议。
首先要找到服务的ip,port,要传输的数据,将这些内容发送给服务端。
要传输的数据就是服务提供者端定义的:接口,方法,方法参数类型,方法参数。如果有版本号,加上版本号。
将数据发送出去,接收返回即可,这样一个基本的实现就完成了。当然这只是初步的实现了一个远程调用。
消费者端在调用服务的时候,可以使用代理对象来进行调用,这样具有通用性,而不是通过具体的对象来进行。
完善
对于消费者调用来说,如何根据服务名字来找到对应的IP地址和端口号呢。这就谈到了注册中心,服务端在启动服务的时候,把要提供的服务都写入到注册中心里,这个数据类型就是一个
Map<服务名,List<ip,port>>。 这样消费者端在根据服务名字就可以找到对应的服务地址了。
如果是服务方是集群的怎么办呢,不用担心,我们有负载均衡策略一大堆:轮询,随机等等,这都可以根据自己的需要来实现。
协议的切换
对于协议的切换,最好的方式就是可以动态的指定,通过配置文件的方式更改。那么这就需要用到工厂模式了,根据配置文件中指定的表示,选择出来对应的协议。当然如何保证消费者和服务者端的协议一致性也是一个问题,后面文章中会介绍。
那么如果当前的协议不满足用户的需求,要如何来进行协议的兼容呢。这里就用到了Java的SPI机制。下面文章就来详细谈谈dubbo中的SPI机制。
后续会把完善后手写的dubbo源码公布出来,共同探讨。
容错的机制
消费者调用服务端如果抛异常了,可以使用一个优雅的try,catch来处理。这是最简单的一种错误处理机制,dubbo中有更为复杂和健全的处理机制,也会陆陆续续学习后贴出。