互联网开发3--Dubbo框架

时间:2022-09-01 20:57:59

产生背景

互联网系统,随着业务的扩展会需要开发各种服务。在多服务的情况下,通常做法是配置服务的URL,然后远程调用。
当服务很多时,URL的管理就变得越来越困难;服务之间的依赖关系变得错综复杂,架构师整理各个服务之间的依赖关系也越来越困难;访问量的日益增长,服务的承受能力也需要进一步优化;
Dubbo可以解决以上问题,但不止这些问题哈。

Dubbo简介

Dubbo是一个分布式服务框架,组成如下:
提供者Provider: 暴露服务的服务提供方。
消费者Consumer: 调用远程服务的服务消费方。
注册中心Registry: 服务注册与发现的注册中心。
监控中心Monitor: 统计服务的调用次调和调用时间的监控中心。
服务容器Container: 服务运行容器。
工作流程:
1. 服务容器负责启动,加载,运行服务提供者。
2. 服务提供者配置注册中心URL地址,服务提供者在启动时向注册中心注册自己提供的服务。
3. 服务消费者配置注册中心URL地址,在启动时向注册中心订阅自己所需的服务。
4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

使用示例

以springMVC集成Dubbo为例子哈。

1. 安装zookeeper注册中心

下载zookeeper安装文件,启动bat命令即可完成zookeeper的启动。启动之前需要改zoo.cfg文件里的几个配置:
tickTime=2000;这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔(单位毫秒),也就是每个 tickTime 时间就会发送一个心跳。
dataDir=../data;顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
clientPort=2181;这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

2. 安装启动Dubbo-admin管理工具

下载dubbo-admin-2.4.1.war包然后进行解压,清理tomcat/webapps/ROOT目录里的东西,然后将解压后的文件复制到ROOT目录里。打开dubbo.properties文件,配置注册中心的地址和管理员的账号、密码。启动tomcat,浏览器地址访问:http://ip:端口,出现账号密码页面,输入dubbo.properties文件里配置的即可,dubbo管理页面如下:
互联网开发3--Dubbo框架
到此,dubbo管理页面配置完事。

3. 配置服务提供者

以springMVC框架为例。
(1)保存dubbo.xsd到项目。这个文件里面定义了dubbo配置的一些标签,该文件可以在网上下载到。导入后如下图:
互联网开发3--Dubbo框架
(2)定义dubbo对应的spring文件,比如文件叫spring-remote.xml,文件配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
classpath:dubbo.xsd"
>


<dubbo:application name="susong51-service"/>

<dubbo:registry address="zookeeper://172.18.40.12:2181"/>
<dubbo:protocol name="dubbo" port="20886" payload="52428800" />
<dubbo:service interface="com.thunisoft.susong51.platform.service.message.IMessageService" ref="messageService" timeout="30000" />
<dubbo:service interface="com.thunisoft.susong51.platform.service.task.ITaskService" ref="taskService" timeout="30000" />

</beans>
  • 文件里引入dubbo.xsd,才能用dubbo的配置标签;
  • dubbo:application标签,用来定义注册中心zookeeper里显示的应用名字;不同服务可以重名,应用的名字没啥大用,仅仅是用来在dubbo-admin页面查询服务而已。如下图:
    互联网开发3--Dubbo框架

登录dubbo-admin管理页面,【服务治理】–【应用】就能看到注册的应用有哪些。

  • dubbo:registry标签用来定义zookeeper中心的访问地址,比如访问地址如下:zookeeper://172.18.40.12:2181。

  • dubbo:protocol标签用来指定dubbo的注册协议,端口等信息;特别说明:zookeeper保存服务的URL格式是【服务所在的ip+dubbo注册端口+服务完整包名】。如下图:
    互联网开发3--Dubbo框架
    标签里定义的注册端口是20886,所以服务的URL里端口也是20886.

  • dubbo:service标签用来定义注册的服务。interface属性指定服务的接口,ref属性指定该服务的某个具体实现类,值就用spring定义的那个bean名字。注册某接口实现类为服务提供者,并不影响这个bean的正常使用,其他模块仍然可以照常使用这个bean。

4. 配置服务消费者

定义dubbo的spring文件,比如该文件叫spring-remote.xml,配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
classpath:dubbo.xsd"
>


<dubbo:application name="susong51-platform"/>

<dubbo:registry address="zookeeper://172.18.40.12:2181"/>
<dubbo:reference id="myMessageService" interface="com.thunisoft.susong51.platform.service.message.IMessageService" check="false"/>
<dubbo:reference id="myTaskService" interface="com.thunisoft.susong51.platform.service.task.ITaskService" check="false"/>

</beans>

给应用取个名,不取的话,zookeeper貌似会自己给应用取个名;
配置zookeeper的访问地址;
配置调用的远程接口服务们。dubbo:reference标签里的id属性,指定该服务bean名字。这样,系统的各个业务模块就可以像引用其他spring的bean那样,引用这个服务了。

Dubbo总结

(1) Dubbo的注册中心通常选用Zookeeper。Dubbo原先是基于数据库的注册中心,没采用Zookeeper。Zookeeper是一个分布式的服务框架,采用树型的目录结构数据存储,能做到集群管理数据 ,因此能很好的作为Dubbo服务的注册中心。Dubbo能与Zookeeper做到集群部署,当提供者出现断电等异常停机时,Zookeeper注册中心能自动删除提供者信息,当提供者重启时,能自动恢复注册数据,以及订阅请求。
(2)zookeeper保存服务提供者的URL路径为:服务所在的ip+dubbo注册端口+服务完整包名。对于互联网项目,可能会一台机器部署多个这个项目的war包,这时,如果不配置

<dubbo:protocol name="dubbo" port="20886" payload="52428800" />

端口port加以区分的话,注册服务时会冲突。指定不同的注册端口,就不会了。比如,在同一台机器部署了多个susong51-service项目,这个项目是服务的提供者。每个项目配置不同的dubbo注册端口20885和20886,在dubbo-admin管理页面查看如下:
应用:
互联网开发3--Dubbo框架

服务:
互联网开发3--Dubbo框架

位于不同的注册端口上:
互联网开发3--Dubbo框架
只要保证注册的端口不同就可以,就不会冲突了。
(3)同一个系统,如何配置多个zookeeper注册中心,用来获得不同系统提供的对外服务?
在这种情况下,多个不同的系统可以使用同一个zookeeper注册中心注册服务,只要配置的dubbo端口不要冲突就行了,服务消费方配置一个zookeeper中心地址就行了。当同一个ip下的不同端口,注册了同一个接口作为提供者,dubbo页面会给出warning提示,有相同的服务注册了;
(4)同一个服务接口,有不同的实现类要作为服务提供者暴漏给消费者们,该如何配置注册呢?
(5)spring框架定义dubbo消费者,默认是懒加载的。使用远程服务的bean时,消费者才会注册到zokeeper里。如果只是在配置文件里配置消费者服务,但是并没有其他的bean去使用这个服务的话,是先不会创建实例的,这时在dubbo-admin页面是看不到消费者的。
(6)暴漏的接口服务里,有一个绝对路径比如“d:/data”,那么这个路径是在zookeeper上还是在提供者服务上,还是在消费者服务上?
如下图:
互联网开发3--Dubbo框架

服务提供者zsfy-service,服务的代码里有“d:/data”的绝对路径,比如用来存放上传的材料等文件。
服务消费者zsfy远程调用zookeeper里的服务,实现上传功能。那么实际上传的材料是存在了机器1,还是机器2,还是机器3,4,5呢?
通过本地验证,存在了机器1里。所以,通常服务提供者不要部署多个,部署一个就好。这样就不会发生上传的材料会物理隔离,以及重复注册服务的问题了。