目录
- 1.概述
- 1.1.什么是 Dubbo ?
- 1.2.Dubbo 架构
- 2.Dubbo 快速入门
- 2.1.Zookeeper 安装
- 2.2.创建项目
- 2.3.代码实现
- 2.3.1.dubbo-service 模块
- 2.3.2.dubbo-web 模块
- 2.4.本地启动
- 2.5.使用 Dubbo 实现 PRC
- 2.5.1.修改 dubbo-service 模块
- 2.5.2.修改 dubbo-web 模块
- 2.5.3.启动 dubbo-service 和 dubbo-web
- 2.5.4.代码改进
- 3.Dubbo 高级特性
- 3.1.dubbo-admin
- 3.1.1.概述
- 3.1.2.安装
- 3.1.3.启动
- 3.2.序列化
- 3.2.1.概述
- 3.2.2.案例
- 3.3.地址缓存
- 3.4.超时
- 3.4.1.概述
- 3.4.2.解决方案
- 3.5.重试
- 3.6.多版本
- 3.7.负载均衡
- 3.8.集群容错
- 3.9.服务降级
本文笔记整理来自黑马视频https://www.bilibili.com/video/BV1VE411q7dX?p=1,相关资料可在视频评论区进行获取。
1.概述
1.1.什么是 Dubbo ?
(1)Dubbo 是阿里巴巴公司开源的一个高性能、轻量级的 Java RPC 框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。
RPC,即 Remote Procedure Call,指远程过程调用。有非常多的协议和技术来都实现了RPC的过程。比如:HTTP REST风格,Java RMI规范、WebService SOAP 协议、Hession 等等。
(2)Dubbo 官网:http://dubbo.apache.org。
1.2.Dubbo 架构
(1)Dubbo 架构如下图所示:
(2)上图中的节点角色说明如下:
Provider | 暴露服务的服务提供方 |
---|---|
Container | 服务运行容器 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
2.Dubbo 快速入门
2.1.Zookeeper 安装
(1)Dubbo 官方推荐使用 Zookeeper 作为注册中心,Zookeeper 的官方地址为 https://zookeeper.apache.org/,可以从中下载其安装包,这里使用的版本为 3.5.6:
(2)Dubbo在 CentOS 7.7 中的安装步骤如下:
- 将下载的安装包放到 /opt/zookeeper 目录下(也可自行设置);
- 在 /opt/zookeeper 目录下解压该安装包,解压命令如下:
tar -zxvf apache-zookeeper-3.5.6-bin.tar.gz
- 进入到 conf 目录拷贝一个 zoo_sample.cfg,重命名为 zoo.cfg:
# 进入到 conf 目录
cd /opt/zookeeper/apache-zookeeper-3.5.6-bin/conf/
# 拷贝
cp zoo_sample.cfg zoo.cfg
- 修改 zoo.cfg:
# 打开目录
cd /opt/zooKeeper/
# 创建 zooKeeper 存储目录
mkdir zkdata
# 修改 zoo.cfg 后,保存并退出
vim /opt/zooKeeper/apache-zooKeeper-3.5.6-bin/conf/zoo.cfg
(3)启动 Zookeeper
cd /opt/zookeeper/apache-zookeeper-3.5.6-bin/bin/
# 启动 ZooKeeper
./zkServer.sh start
# 关闭 ZooKeeper
./zkServer.sh stop
(4)查看 ZooKeeper 状态,ZooKeeper 启动成功后,standalone 代表 ZooKeeper 没有搭建集群,现在是单节点。
# 查看 ZooKeeper 状态
./zkServer.sh status
2.2.创建项目
① 在 IDEA 中创建名为 dubbo-pro 的空项目;
② 在 dubbo-pro 创建两个名为 dubbo-service 和 dubbo-web 的模块:
③ dubbo-service 模块的 pom.xml 如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<dubbo.version>2.7.4.1</dubbo.version>
<zookeeper.version>4.0.0</zookeeper.version>
</properties>
<dependencies>
<!-- servlet3.0规范的坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--spring的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${zookeeper.version}</version>
</dependency>
</dependencies>
</project>
④ dubbo-web 模块的 pom.xml 如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>dubbo-web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<dubbo.version>2.7.4.1</dubbo.version>
<zookeeper.version>4.0.0</zookeeper.version>
</properties>
<dependencies>
<!-- servlet3.0规范的坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--spring的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<!--依赖 service 模块-->
<dependency>
<groupId>com.itheima</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--tomcat插件-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8000</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.3.代码实现
- 创建服务提供者 Provider 模块;
- 创建服务消费者 Consumer 模块;
- 在服务提供者模块编写 UserServiceImpl 提供服务;
- 在服务消费者中的 UserController 远程调用 UserServiceImpl 提供的服务;
- 分别启动两个服务,测试;
下面先在本地实现 service 和 web 模块:
2.3.1.dubbo-service 模块
UserService .java
package com.itheima.service;
public interface UserService {
public String sayHello();
}
UserServiceImpl.java
package com.itheima.service.impl;
import com.itheima.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Override
public String sayHello() {
return "Hello, dubbo!";
}
}
log4j.properties
# DEBUG < INFO < WARN < ERROR < FATAL
# Global logging configuration
log4j.rootLogger=info, stdout,file
# My logging configuration...
# log4j.logger.com.tocersoft.school=DEBUG
# log4j.logger.net.sf.hibernate.cache=debug
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=../logs/iask.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %m%n
applicationContext.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://dubbo.apache.org/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://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.itheima.service" />
</beans>
2.3.2.dubbo-web 模块
UserController.java
package com.itheima.controller;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/sayHello")
public String sayHello() {
return userService.sayHello();
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Springmvc -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
log4j.properties
# DEBUG < INFO < WARN < ERROR < FATAL
# Global logging configuration
log4j.rootLogger=info, stdout,file
# My logging configuration...
# log4j.logger.com.tocersoft.school=DEBUG
# log4j.logger.net.sf.hibernate.cache=debug
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=../logs/iask.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %m%n
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:dubbo="http://dubbo.apache.org/schema/dubbo"
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 http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.itheima.controller"/>
</beans>
2.4.本地启动
(1)将 dubbo-service 模块进行安装:
(2)通过 tomcat 插件启动 dubbo-web:
(3)在浏览器中输入:
http://localhost:8000/user/sayHello.do
结果如下:
2.5.使用 Dubbo 实现 PRC
2.5.1.修改 dubbo-service 模块
(1)修改 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
<!--改为 war-->
<packaging>war</packaging>
...
<!--加入 tomcat 插件,端口号设置为 9000-->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>9000</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
(2)修改 UserServiceImpl.java
package com.itheima.service.impl;
import com.itheima.service.UserService;
import org.apache.dubbo.config.annotation.Service;
//下面两个注解所属的包不一样,第一个是 Spring 中的,第二个是 dubbo 中的
//@Service //将该类的对象创建出来,然后放到 Spring 的 Ioc 容器中,即 bean 的定义
@Service //将这个类提供的方法(服务)对外发布,将访问的地址 ip、端口、路径注册到注册中心(ZooKeeper)中
public class UserServiceImpl implements UserService {
@Override
public String sayHello() {
return "Hello, dubbo!";
}
}
(3)修改配置文件 applicationContext.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://dubbo.apache.org/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://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--<context:component-scan base-package="com.itheima.service" />-->
<!--dubbo 的配置-->
<!--1.配置项目的名称,唯一-->
<dubbo:application name="dubbo-service"/>
<!--2.配置注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.1.8:2181"/>
<!--3.配置 dubbo 包扫描-->
<dubbo:annotation package="com.itheima.service.impl" />
</beans>
(4)添加 web.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
(5)通过 tomcat 插件启动 dubbo-service
2.5.2.修改 dubbo-web 模块
(1)在 pom.xml 中去掉 web 模块对 service 模块的依赖,即注释掉下面的代码:
<!--依赖 service 模块-->
<dependency>
<groupId>com.itheima</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
(2)注释之后,UserController.java 找不到 com.itheima.service.UserService.java
解决办法:在 dubbo-service 模块新建一个 UserService.java(应与 dubbo-service 中的一致):
package com.itheima.service;
public interface UserService {
public String sayHello();
}
(3)注释掉 web.xml 的 Spring 相关配置
<!-- spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
(4)修改 UserController.java
package com.itheima.controller;
import com.itheima.service.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
/*
@Reference:
1.从 zookeeper 注册中心获取 userService 的访问 url
2.进行远程调用 RPC
3.将结果封装为一个代理对象,给变量赋值
*/
//@Autowired // Spring 中的注解,本地注入
@Reference // dubbo 中的注解,远程注入
private UserService userService;
@RequestMapping("/sayHello")
public String sayHello() {
return userService.sayHello();
}
}
(5)修改配置文件 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:dubbo="http://dubbo.apache.org/schema/dubbo"
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 http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.itheima.controller"/>
<!--dubbo的配置-->
<!--1.配置项目的名称,唯一-->
<dubbo:application name="dubbo-web" >
<dubbo:parameter key="qos.port" value="33333"/>
</dubbo:application>
<!--2.配置注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.1.8:2181"/>
<!--3.配置dubbo包扫描-->
<dubbo:annotation package="com.itheima.controller" />
</beans>
2.5.3.启动 dubbo-service 和 dubbo-web
(1)启动 dubbo-service
(2)启动 dubbo-web
(3)在浏览器中输入:
http://localhost:8000/user/sayHello.do
结果如下之前的本地调用一致:
2.5.4.代码改进
(1)如下图所示,为了减少代码冗余,我们可以将接口抽取出来,存放到 dubbo-interface 模块中,然后再让 dubbo-service 和 dubbo-web 依赖其即可。
(2)创建 dubbo-interface 模块
(3)将 dubbo-service 中的 UserService.java 接口复制到 dubbo-interface,注意全类名需要一样。
package com.itheima.service;
public interface UserService {
public String sayHello();
}
(4)让 dubbo-service 和 dubbo-web 依赖 dubbo-interface,即在它们的 pom.xml 中加入下面的依赖:
<dependency>
<groupId>com.itheima</groupId>
<artifactId>dubbo-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
(5)将 dubbo-interfacee 模块进行安装:
(6)启动 dubbo-service 和 dubbo-web,浏览器中输入
http://localhost:8000/user/sayHello.do
结果如下之前的一致:
3.Dubbo 高级特性
3.1.dubbo-admin
3.1.1.概述
- dubbo-admin 管理平台,是图形化的服务管理页面;
- 从注册中心中获取到所有的提供者 / 消费者进行配置管理;
- 路由规则、动态配置、服务降级、访问控制、权重调整、负载均衡等管理功能;
- dubbo-admin 是一个前后端分离的项目。前端使用 Vue,后端使用 Springboot;
- 安装 dubbo-admin 其实就是部署该项目;
3.1.2.安装
(1)修改 dubbo-admin-server 中的 application.properties,即将 zookeeper 的 IP 地址改为与实际情况一样的。
# centers in dubbo2.7
admin.registry.address=zookeeper://192.168.1.8:2181
admin.config-center=zookeeper://192.168.1.8:2181
admin.metadata-report.address=zookeeper://192.168.1.8:2181
(2)构建项目(需要在 windows 下安装 Maven 和 node.js):使用 Windows PowerShell 打开该项目的根目录,执行下面的命令:
mvn clean package
最后安装结束后的情况如下图所示,安装过程可能长,需耐心等待。
3.1.3.启动
(1)在 Windows PowerShell 中运行 dubbo-admin-distribution\target 目录下的 dubbo-admin-0.1.jar
即执行如下命令:
java -jar .\dubbo-admin-0.1.jar
(2)在 Windows PowerShell 中的 dubbo-admin-ui 目录下执行如下指令:
npm run dev
(3)在浏览器中输出如下地址,即可看到 dubbo-admin 的主页
http://localhost:8081
点击服务查询后,输入用户名和密码(初始时均为 root),登录即可:
3.2.序列化
3.2.1.概述
- dubbo 内部已经将序列化和反序列化的过程内部封装了;
- 我们只需要在定义 pojo 类时实现 Serializable 接口即可;
- 一般会定义一个公共的 pojo 模块,让生产者和消费者都依赖该模块;
3.2.2.案例
(1)新建一个名为 dubbo-pojo 的模块。
(2)定义一个 pojo 类 User:
package com.itheima.pojo;
import java.io.Serializable;
/**
* 注意!!!
* 将来所有的pojo类都需要实现Serializable接口
*/
public class User implements Serializable {
private int id;
private String username;
private String password;
public User() {
}
public User(int id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
(3)在 dubbo-interface 模块中的 pom.xml 添加如下对 dubbo-pojo 模块的依赖:
<dependencies>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>dubbo-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
然后在 UserService.java 添加一个查询用户的抽象方法:
//查询用户
public User findUserById(int id);
(4)在 dobbo-service 模块中的 UserServiceImpl.java 中添加相应的实现方法:
@Override
public User findUserById(int id) {
//模拟查询 User 对象
User user = new User(1,"zhangsan","123");
return user;
}
(5)在 dubbo-web 模块中的 UserController.java 中添加如下方法:
@RequestMapping("/find")
public User find(int id){
return userService.findUserById(id);
}
(6)重新对 dubbo-interface 模块和 dubbo-pojo 模块进行安装,并且启动 dubbo-service 模块和 dubbo-web 模块。然后在浏览器中输入:
http://localhost:8000/user/find.do?id=1
其结果如下:
3.3.地址缓存
3.4.超时
3.4.1.概述
3.4.2.解决方案
(1)dubbo 利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。
(2)使用 timeout 属性配置超时时间,默认值 1000,单位是毫秒。
(3)修改 dubbo-service 模块中的 UserServiceImpl.java,即在服务方进行设置:
@Service(timeout = 3000, retries = 0)
public class UserServiceImpl implements UserService {
...
}
也可在请求方设置:
public class UserController {
//@Autowired // Spring 中的注解,本地注入
// dubbo 中的注解,远程注入
@Reference(timeout = 1000)
private UserService userService;
...
}
注:由于服务方更清楚某个服务的预计时长,因此建议在服务方设置 timeout。
3.5.重试
设置如下:
@Service(timeout = 3000, retries = 2)
public class UserServiceImpl implements UserService {
...
}
3.6.多版本
(1)在 dubbo-service 模块中新建 UserServiceImpl2.java 并设置 version:
@Service(version = "v2.0")
public class UserServiceImpl2 implements UserService {
public String sayHello() {
return "hello dubbo hello!~";
}
public User findUserById(int id) {
System.out.println("new....");
//查询User对象
User user = new User(1,"zhangsan", "123");
return user;
}
}
(2)设置 UserServiceImpl .java 中的 version
@Service(version = "v1.0")
public class UserServiceImpl implements UserService {
...
}
(3)在 UserController.java 中注入 UserService 时选择需要的版本即可。
@RestController
@RequestMapping("/user")
public class UserController {
...
@Reference(version = "v2.0")
private UserService userService;
...
}
3.7.负载均衡
(1)在多个服务方设置 weight,下面演示一个:
@Service(weight = 100)
public class UserServiceImpl implements UserService {
...
}
(2)在请求方设置负载均衡策略:
@RestController
@RequestMapping("/user")
public class UserController {
@Reference(loadbalance = "random")
private UserService userService;
...
}
3.8.集群容错
在多个服务方设置集群容错模式,下面演示一个:
@RestController
@RequestMapping("/user")
public class UserController {
@Reference(cluster = "failover")
private UserService userService;
...
}
3.9.服务降级
(1)服务降级是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
(2)在多个服务方设置服务降级模式,下面演示一个:
@RestController
@RequestMapping("/user")
public class UserController {
//不再调用 userService 的服务
@Reference(mock = "force:return null ")
private UserService userService;
...
}