服务发现思想及原理

头一听这个名词觉得很高级,其实理解了原理思想和他的应用就觉得不是那么高深。下面听我娓娓道来。

没有服务发现情况下

首先看下面这个单服务器模式:
服务发现思想及原理
多服务器版:
客户端与服务器连接有一个基本的要求,不管是长连接还是短连接,客户端都需要知道服务器的ip和port。
如果服务器很多,你要把所有的服务器配置都写在配置文件中。
如果增删服务器,那你还要去刷新客户端的配置文件,怎么刷新呢?如果是长连接,那么可以由服务器发送,但是如果是短连接呢?
可以实现,但是很复杂。
服务发现思想及原理

加入服务发现

服务发现思想及原理
服务发现基本原理:
在客户端和服务器之间加了一个“注册中心”,可以把他一个服务中介。
所有服务器在启动时,都需要在“注册中心”进行注册,把这个服务器能提供的服务和这个服务对应的ip和port都发给注册中心,由注册中心来统计并保存。客户端需要资源时,向注册中心来请求服务器的地址。注册中心根据原先的统计,把对应的服务器地址发送给客户端。客户端根据这个地址信息,可以和服务器完成通信。
要明确的是:
服务器和注册中心长连接+短连接,短连接是为了服务器的注册,长连接是为了保持监控。
客户端和注册中心短连接。
客户端和服务器短连接。

优点
光从这个原理来看,就很好地解决了上面说的俩个问题。多配置的问题和服务器增删的问题。
因为现在的客户端不关心服务器,他配置只有注册中心的地址,我只需要从注册中心来获取对应的服务器地址信息即可,这就实现了客户端的零配置
再谈服务器的增删问题。首先我们让服务器和注册中心保持长连接,这样可以保持实时的通信。服务器异常掉线时,注册中心可以检查到。并根据检查的内容,可以删除注册中心中对应保存的服务。当新增一个服务器时,通过服务器的注册,注册中心可以马上检查到,并可以马上交给客户端使用。
再说服务发现更加秒的应用:

  1. 负载均衡。之前说到,客户端要向注册中心来请求服务器的地址。客户端是根据需要的服务来请求,所以,注册中心可能会发给客户端不止一个服务器。这些服务器都提供了这个服务。这时为了减轻服务器的负担,就需要从这一系列地址中拿出合适的来连接。可以使用轮询,也可以是使用随机访问,也可以对健康状况进行实时监控(这项较难)。
  2. 服务器的在线升级。因为客户端拿到的地址是不止一个的,所以他有多重选择,而这时,我们可以对其中的某一个服务器进行升级,客户端连接不上正在升级的服务器,那么就可以换另一个。这其实也算是一种容错的机制

基本的实现思路

首先,从注册中心出发,他集成了3个服务器。一个是与服务提供者保持长连接的服务器,用一个线程和一个服务器保持通信。另一个RMI服务器保持短连接,用来接收服务器的注册信息。所以需要提供给服务器的API就是一个注册,注册的信息应该包括服务器的ip,这个服务的port以及这个服务的名称(就是一个接口名)。最后一个服务器是和客户端保持的短连接,之前已经讲到。
那么注册中心应该用怎样的数据结构来存放服务器提供的服务?
我们给出俩个关系,Map<String,List<地址封装类>>。第一个String保存的是接口的名称,也就是说这个池子保存的是 提供一个服务的所有服务器的地址信息。当客户端需要获得服务时,直接根据服务名称返回这个list给客户端。
还需要再给一个关系:一个服务器他提供的所有服务。给出这个关系是方便某个服务器掉线时,我们删掉这个服务器的所有服务。

上面基本讲完服务器和注册中心之间的关系。

注册中心和客户端的关系更加复杂。有一个大问题,客户端和注册中心的连接时短链接,假如我一次已经拿到了一堆服务器的地址,那么我该何时进行第二次连接来刷新这些地址。这些地址可能早就因为服务器的掉线失效了。
所以我们要考虑客户端刷新的问题,基本的解决思路:每隔一定的时间和注册中心连接来刷新,当某发现某一个地址失效时,也刷新一次。

再讲俩个实现负载均衡的思路

  1. 轮询的方式。用循环链表保存所有的地址值,并记录当前节点,每次从循环链表来获取时,先让当前节点往后走一,在获取。
  2. 随机数的方式,产生一个随机数,用这个随机数和保存的地址列表的容量取余,这个下标上得值作为返回值返回。