一、初识Dubbo
1.1为什么Dubbo性能高
- 高性能要从底层的原理说起,既然是-一个RPC框架,主要干的就是远程过程(方法)调用,那么提升性能就要从最关键、最耗时的两个方面入手:序列化和网络通信。
- 序列化:我们学习Java网络开发的时候知道,本地的对象要在网络上传输,必须要实现Serializable接口,也就是必须序列化。我们序列化的方案很多: xml、 json、 二进制流…其中效率最高的就是二进制流(因为计算机就是二进制的)。然而Dubbo采用的就是效率最高的二进制。
- 网络通信:不同于HTTP需要进行7步走(三次握手和四次挥手),Dubbo 采用Socket通信机制,一步到位,提升了通信效率,并且可以建立长连接,不用反复连接,直接传输数据
1.2别的RPC框架
- gRPC
- Thrift
- HSF
- …
1.3dubbo的前世今生
dubbo之前一直都作为Alibaba公司内部使用的框架
- 2011年,dubbo被托管到了GitHub上(开源)
- 2014年11月发布2.4.11版本后宣布停止更新。此后–段时间很多公司开源了自己基于Dubbo.的变种版本(例如当当网的Dubbo x,网易考拉的Dubbo K)
- 2017年SpringCloud横空出世,Dubbo感觉到压力后连续更新了几个版本.
- 2018年1月,阿里公司联合当当网将Dubbo和DubboX合并,发布了2.6版本
- 2018年除夕夜阿里将Dubbo贡献给了Apache 基金会
- 2018除夕夜至今,Apache维护和更新Dubbo
二、Dubbo框架
2.1概述
Apache Dubbo 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案、服务治理方案
官网:https://dubbo.apache.org/zh/
2.2基本架构
2.2.1简单说明
(1)Provider暴露服务方称之为“服务提供者”。
服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
(2)Consumer调用远程服务方称之为“服务消费者”。
服务消费者向注册中心获取服务提供者地址列表 , 并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
(3)Registry服务注册与发现的中心目录服务称之为“服务注册中心”
注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
(4)Monitor统计服务的调用次调和调用时间的日志服务称之为“服务监控中心”
监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
2.2.2调用关系说明
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
2.3支持的协议
支持多种协议: dubbo,hessian , rmi , http, webservice , thrift , memcached , redis。dubbo官方推荐使用dubbo协议。dubbo协议默认端口20880
使用dubbo协议,spring 配置文件加入:
<dubbo:protocol name= " dubbo" port= “20880” />
2.4 dubbo健壮性
(1)监控中心宕掉不影响使用,只是丢失部分采样数据
(2)数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
(3)注册中心对等集群,任意一台宕掉后,将自动切换到另一台
(4)注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
(5)服务提供者无状态,任意一台宕掉后,不影响使用
(6)服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
2.5 dubbo伸缩性
(1)注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
(2)服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者
三、ssm简单实现dubbo
Dubbo采用全spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载.
下列实现方式使用官方推荐的项目结构实现:
- 接口独立工程(entity、service)
- 服务提供者工程(serviceImpl),实现接口工程中的业务接口
- 服务消费者工程(controller),实现消费服务提供者提供的业务接口
3.1接口项目
-
创建一个普通maven项目
-
新建service包和entity包
-
编写entity层
public class User implements Serializable { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
-
编写service层
public interface SomeService{ /** * * @param msg * @return */ String hello(String msg); /** * * @param id * @return */ User queryUser(Integer id); }
-
项目架构
3.2提供者项目
-
新建一个web的maven项目
-
引入依赖
这里需要引入接口的依赖
建议spring的依赖版本与我的一致,否则可能会出现错误
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- dubbo--> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.0</version> </dependency> <!-- spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.19.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.19.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.19.RELEASE</version> </dependency> <!-- 接口--> <dependency> <groupId>com.lzj.dubbo</groupId> <artifactId>001-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.19.RELEASE</version> </dependency>
-
编写serviceimpl层
@Component public class SomeServiceImpl implements SomeService { @Override public String hello(String msg) { return "hello"+msg; } @Override public User queryUser(Integer id) { User user = new User(); user.setId(id); user.setName("lzj-"+id); return user; } }
-
编写dubbo配置文件
dubbo-link-provider.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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 扫描包的注解--> <context:component-scan base-package="com.lzj.service.impl"/> <!-- 声明服务提供者名称,保证它的唯一性,它是dubbo内部使用的唯一标识--> <dubbo:application name="002-link-provider"/> <!-- 指定dubbo的协议名称和端口号 name 指定协议名称,官方推荐dubbo port 协议的端口号,默认为20880 --> <dubbo:protocol name="dubbo" port="20880"/> <!-- 暴露服务:dubbo:service interface 暴露服务的接口全限定名 ref 引用接口在spring容器中的标识名称 registry 使用直连方式,不适用组成,值:N/A --> <dubbo:service interface="com.lzj.service.SomeService" ref="someServiceImpl" registry="N/A"/> <!-- 加载接口实现类--> <!-- <bean id="someServiceImpl" class="com.lzj.service.impl.SomeServiceImpl"/>--> </beans>
-
编写web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 监听器--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-link-provider.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
-
项目架构
3.3消费者项目
-
新建一个web的maven项目
-
引入依赖
也需要加入接口的依赖
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.19.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.19.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.19.RELEASE</version> </dependency> <dependency> <groupId>com.lzj.dubbo</groupId> <artifactId>001-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.19.RELEASE</version> <scope>test</scope> </dependency>
-
编写controller层
@Controller public class SomeController { @Autowired private SomeService someService; @RequestMapping("/hello") public String hello(Model model){ //调用远程接口服务 String lzj = someService.hello("lzj"); model.addAttribute("hello",lzj); return "hello"; } @RequestMapping("/detail") public String user(Model model,Integer id){ User user = someService.queryUser(1); model.addAttribute("user",user); return "detail"; } }
-
编写dubbo配置文件
dubbo-link-consumer.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 http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--声明服务消费者名称,保证它的唯一性,它是dubbo内部服务名称的唯一标识--> <dubbo:application name="003-link-consumer"/> <!--引用远程接口 id 远程接口服务的代理对象名称 interface 接口的全限定类名 url 调用远程接口服务的url地址 registry 直连方式,不使用注册中心,值:N/A --> <dubbo:reference id="someService" interface="com.lzj.service.SomeService" url="dubbo://localhost:20880" registry="N/A"/> </beans>
-
编写springmvc配置文件
springmvc.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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 注解驱动 mvc--> <mvc:annotation-driven/> <!-- 扫描包--> <context:component-scan base-package="com.lzj.controller"/> <!-- 视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀--> <property name="prefix" value="/"/> <!-- 后缀--> <property name="suffix" value=".jsp"/> </bean> </beans>
-
编写web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-link-consumer.xml,classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
webapp目录下新建两个jsp文件
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>${hello}</h1> </body> </html>
detail.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>${user.id}</h1> <h1>${user.name}</h1> </body> </html>
-
项目架构
3.4测试
-
给提供者和消费者两个web项目配置tomcat(注:两个项目的以下两个端口号需要不同)
提供者:
消费者
-
两个项目的tomcat配置完成后,按照顺序执行tomcat(提供者->消费者)
-
进行测试访问
测试一:
测试二:
四、注册中心-Zookeeper
4.1 概述
官方文档:https://dubbo.apache.org/zh/docs/references/registry/zookeeper/
Zookeeper是 Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用
流程说明:
- 服务提供者启动时: 向
/dubbo/com.foo.BarService/providers
目录下写入自己的 URL 地址 - 服务消费者启动时: 订阅
/dubbo/com.foo.BarService/providers
目录下的提供者 URL 地址。并向/dubbo/com.foo.BarService/consumers
目录下写入自己的 URL 地址 - 监控中心启动时: 订阅
/dubbo/com.foo.BarService
目录下的所有提供者和消费者 URL 地址。
支持以下功能:
- 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
- 当注册中心重启时,能自动恢复注册数据,以及订阅请求
- 当会话过期时,能自动恢复注册数据,以及订阅请求
- 当设置
<dubbo:registry check="false" />
时,记录失败注册和订阅请求,后台定时重试 - 可通过
<dubbo:registry username="admin" password="1234" />
设置 zookeeper 登录信息 - 可通过
<dubbo:registry group="dubbo" />
设置 zookeeper 的根节点,不配置将使用默认的根节点。 - 支持
*
号通配符<dubbo:reference group="*" version="*" />
,可订阅服务的所有分组和所有版本的提供者
注册中心工作方式
4.2 下载Zookeeper
linux和windows的压缩包是同一个
版本选择下载地址:https://archive.apache.org/dist/zookeeper/
4.2.1 下载zookeeper
-
进入官网:https://zookeeper.apache.org/
-
按照以下操作点击
-
我选择下载的版本是3.5.9
-
如果需要下下载其它版本(就是我前面提到的版本选择下载地址)
-
linux和window是是同一个压缩包,下载后解压即可
4.3 安装配置zookeeper
4.3.1 windows下
运行zookeeper需要java环境
-
解压压缩包,打开下载的文件(管理员模式打开),运行/bin/zkServer.cmd,初次运行时可能会报错,因为没有zoo.cfg
也有可能遇到闪退的问题!
闪退的解决方案:右键编辑zkServer.cmd文件,在末尾添加pauser(如果右键不能点击编辑,可以将文件的后缀名改为txt,然后修改完后再改回cmd)
-
修改zoo.cfg配置文件
将conf文件夹下面的zoo_sample.cfg复制一份改名为zoo.cfg即可。
需要添加
admin.serverPort=9001
(也可以设置成其它端口号),避免启动时占用tomcat的端口号8080注意几个重要位置:
dataDir=./ 临时数据存储的目录(可写相对路径)
clientPort=2181 zookeeper的端口号
修改完成后再次启动zookeeper
-
打开zkCli.cmd进行测试(在打开zkCli.cmd前,要先将zkServer.cmd打开)
ls /:列出zookeeper根下保存的所有节点
create –e /lzj123:创建一个lzj节点,值为123
get /lzj:获取/lzj节点的值
4.3.2 Linux下
需要java环境
基本操作操作与windows下一致,只是需要使用命令行进行操作
- 将压缩包放到对应位置
- 解压文件
- tar zxvf FileName.tar.gz
- 修改zoo.zfg配置文件
- cp zoo_sample.cfg zoo.cfg
- vim zoo.cfg
- 添加
admin.serverPort=9001
- 进行测试启动
- ./zkServer.sh start
- 检查是否启动成功
- pe -ef | grep zook
五、ssm简单实现dubbo+zookeeer
5.1 接口工程
-
创建一个普通maven项目
-
新建service包和entity包
-
编写entity层
public class User implements Serializable { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
-
编写service层
public interface SomeService{ /** * * @param msg * @return */ String hello(String msg); /** * * @param id * @return */ User queryUser(Integer id); }
-
项目架构
5.2 服务提供者工程
-
新建一个web的maven项目
-
引入依赖
这里需要引入接口的依赖
dubbo的版本必须为2.6.2不能为低版本,因为低版本dubbo依赖支持的zookeeper依赖名称不是我写的这个
建议spring的依赖版本与我的一致,否则可能会出现错误
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <!-- dubbo--> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.19.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.19.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.19.RELEASE</version> </dependency> <!-- 接口工程--> <dependency> <groupId>com.lzj.dubbo</groupId> <artifactId>001-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- zookeeper注册中心依赖--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.19.RELEASE</version> <scope>test</scope> </dependency>
-
编写serviceimpl层
@Component public class SomeServiceImpl implements SomeService { public String hello(String msg) { return "hello dubbo zookeeper"+msg; } public User queryUser(Integer id) { User user = new User(); user.setId(id); user.setName("zk-dubbo-"+id); return user; } }
-
编写dubbo配置文件
dubbo-zk-provider.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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--扫描注解--> <context:component-scan base-package="com.lzj.service.impl"/> <!-- 声明服务提供者名称--> <dubbo:application name="004-zk-provider"/> <!-- 指定协议及端口号--> <dubbo:protocol name="dubbo" port="20880"/> <!-- 指定注册中心--> <dubbo:registry address="zookeeper://localhost:2181"/> <!-- 暴露服务--> <dubbo:service interface="com.lzj.service.SomeService" ref="someServiceImpl" timeout="3000"/> <!-- 加载接口实现类--> <!-- <bean id="someServiceImpl" class="com.lzj.service.impl.SomeServiceImpl"/>--> </beans>
-
编写web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 监听器--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-zk-provider.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
-
项目架构
5.3 服务消费者工程
-
新建一个web的maven项目
-
引入依赖
需要加入接口工程的依赖
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- dubbo--> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.19.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.19.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.19.RELEASE</version> </dependency> <!-- 接口工程--> <dependency> <groupId>com.lzj.dubbo</groupId> <artifactId>001-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- zookeeper注册中心依赖--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.19.RELEASE</version> <scope>test</scope> </dependency>
-
编写controller层
@Controller public class SomeController { @Autowired private SomeService someService; @RequestMapping("/hello") public String hello(Model model){ //调用远程接口服务 String lzj = someService.hello("lzj"); model.addAttribute("hello",lzj); return "hello"; } @RequestMapping("/detail") public String user(Model model,Integer id){ User user = someService.queryUser(1); model.addAttribute("user",user); return "detail"; } }
-
编写dubbo配置文件
dubbo-zk-consumer.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 http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 声明服务消费者名称--> <dubbo:application name="005-zk-consumer"/> <!-- 指定注册中心--> <dubbo:registry address="zookeeper://localhost:2181"/> <!-- 引用远程接口服务--> <dubbo:reference id="someService" interface="com.lzj.service.SomeService"/> </beans>
-
编写springmvc配置文件
springmvc.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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 注解驱动 mvc--> <mvc:annotation-driven/> <!-- 扫描包--> <context:component-scan base-package="com.lzj.controller"/> <!-- 视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀--> <property name="prefix" value="/"/> <!-- 后缀--> <property name="suffix" value=".jsp"/> </bean> </beans>
-
编写web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-zk-consumer.xml,classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
webapp目录下新建两个jsp文件
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>${hello}</h1> </body> </html>
detail.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>${user.id}</h1> <h1>${user.name}</h1> </body> </html>
-
项目架构
5.4 测试
-
给提供者和消费者两个web项目配置tomcat(注:两个项目的以下两个端口号需要不同)
提供者:
消费者
-
启动zookeeper
-
两个项目的tomcat配置完成后,按照顺序执行tomcat(提供者->消费者)
-
如果出现8080端口号被占用的情况,就是你的zoo.cfg中没有修改端口,可以往前面翻下我的zookeeper安装配置说明
-
进行测试访问
测试一:
测试二:
六、dubbo的配置
6.1 配置原则
在服务提供者配置访问参数,因为服务提供者更了解服务的各种参数
6.2 关闭检查
dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true.通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
**例1:**关闭某个服务的启动时检查
<dubbo:reference interface=“com.foo.BarService” check=“false” />
**例2:**关闭注册中心启动时检查
<dubbo:registry check=“false” />
默认启动服务时检查注册中心存在并已运行。注册中心不启动会报错。
6.3 重试次数
消费者访问提供者,如果访问失败,则切换重试访问其它服务器,但重试会带来更长延迟。访问时间变长,用户的体验较差。多次重新访问服务器有可能访问成功。可通过retries="2"来设置重试次数(不含第一次)。
重试次数配置如下
<dubbo:service retries="2"/>
或
<dubbo:reference retries="2"/>
6.4 超时时间
由于网络或服务端不可靠,会导致调用出现- - 种不确定的中间状态(超时)。为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。
timeout
:调用远程服务超时时间(毫秒)
消费端
<dubbo:consumer timeout="5000" />
或
<dubbo:server interface="com.foo.BarService" timeout="2000" />
服务端
<dubbo:provider timeout="5000" />
或
<dubbo:provider interface="com.foo.BarService" timeout="2000"/>
6.5 版本号
每个接口都应定义版本号,为后续不兼容升级提供可能。当一个接口有不同的实现,项目早期使用的一个实现类,之 后创建接口的新的实现类。区分不同的接口实现使用version。
七、监控中心(dubbo-admin)
Dubbo的使用,其实只需要有注册中心,消费者,提供者这三个就可以使用了,但是并不能看到有哪些消费者和提供者,为了更好的调试,发现问题,解决问题,因此引入dubbo-admin。通过dubbo-admin 可以对消费者和提供者进行管理。可以在dubbo应用部署做动态的调整,服务的管理。
7.1 Window下安装Dubbo-admin
注意:dubbo-admin可能会使用20880端口,所以在编写生产者的时候要修改生产者的dubbo的端口号
是一个监控管理后台,查看我们注册了哪些服务,哪些服务被消费了
dubbo本身并不是一个服务软件。它其实就是一个jar包,能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。
但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序dubbo-admin,不过这个监控即使不装也不影响使用。
安装步骤:
-
下载dubbo-admin
https://github.com/apache/dubbo-admin
左侧选择master后在code中下载zip
-
进入解压后的目录,进入\dubbo-admin-server\src\main\resources
该目录下有一个application.properties,双击打开该文件
由于dubbo-admin后台服务端口默认为8080,可能会与tomcat的端口产生冲突,所以我们需要在application.properties中修改默认端口
修改方法:在文件末尾加入server.port=7001,即将其默认端口修改为7001
其它需要修改的可以参考如下:(我的话是只修改了端口号就可以了)
server.port=7001 spring.velocity.cache=false spring.velocity.charset=UTF-8 spring.velocity.layout-url=/templates/default.vm spring.messages.fallback-to-system-locale=false spring.messages.basename=i18n/message spring.root.password=root spring.guest.password=guest dubbo.registry.address=zookeeper://127.0.0.1:2181
-
项目目录下cmd中打包dubbo-admin(第一次打包过程可能有点慢)
mvn clean package -Dmaven.test.skip=true
-
打包完成后,会生成如图的jar包,可能不是这个名字
-
进入\dubbo-admin-distribution\target\下可以找到这个jar包(应该就在这个位置,如果不在这个位置,可以去其它文件夹的target目录下找一找)
-
执行 \dubbo-admin-distribution\target\ 下的dubbo-admin-0.3.0.jar(前提:zookeeper的服务一定要打开,即运行zkServer.cmd)
打开cmd在该路径下运行:
java -jar dubbo-admin-0.3.0.jar
-
执行完毕,我们去访问一下http://localhost:7001/,这时候我们需要输入登录账户和密码,我们都是默认的root,如果需要修改的话,可以在第二步的properties中修改,然后重新打包
7.2运行dubbo-admin应用
- 先启动注册中心
- 执行提供者项目
- 执行dubbo-admin的jar包
- 执行消费者项目
- 游览器中输入localhost:7001访问监控中心控制台(默认用户名和密码都是root)