Dubbo入门案例_服务消费者配置
创建消费者项目
创建子模块
选择组件
服务消费者模块引入父项目
<!-- 引入父项目依赖 -->
<parent>
<groupId>com.tong</groupId>
<artifactId>dubbo-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目加入模块
<modules>
<!-- 订单服务生产者 -->
<module>dubbo-provider</module>
<!-- 用户服务消费者 -->
<module>dubbo-consumer</module>
</modules>
添加依赖
<!-- 整合dubbo -->
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.0.0</version>
</dependency>
<!-- zookeeper客户端 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.7</version>
</dependency>
Dubbo入门案例_服务消费者代码编写
编写用户实体类
/**
* 用户模型
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
//用户id
private Long id;
// 用户名字
private String name;
}
编写用户接口
/**
* 用户接口
*/
public interface IUserService {
//根据用户id查询订单详情
CommonResult<Order> findByUserId(Long id);
}
编写用户接口实现类
@Service
public class UserServiceImpl implements
IUserService {
//引入订单服务
private IOrderService iOrderService;
/**
* 根据用户id查询订单
* @param id 用户id
* @return
*/
@Override
public CommonResult<Order> findByUserId(Long id) {
CommonResult commonResult = new CommonResult();
commonResult.setCode(200);
commonResult.setMessage("查询成功");
//远程调用
CommonResult<Order> orderCommonResult = iOrderService.findByUserId(id);
commonResult.setData(orderCommonResult);
return commonResult;
}
}
编写用户控制层
/**
* 用户控制层
*/
@RestController
public class UserController {
@Autowired
private IUserService iUserService;
/**
* 根据用户ID查询用户订单详情
* @param userId 用户id
* @return
*/
@GetMapping("findByUserId")
public CommonResult findByUserId(Long userId){
return iUserService.findByUserId(userId);
}
}
加入Dubbo配置
# 端口号
server.port=8080
# 1. 配置项目名称
spring.dubbo.application.name=user-service
# 2. 配置注册中心地址
spring.dubbo.registry.address=zookeeper://19
2.168.66.100
spring.dubbo.registry.port=2181
# 3. 指定dubbo使用的协议、端口
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=20881
# 4. 指定注册到zk上超时时间,ms
spring.dubbo.registry.timeout=10000
# 5. 配置Dubbo包扫描
spring.dubbo.scan=com.tong.service
加入消费服务注解
/**
*
* @Autowired : 本地注入
*
* 1. 从zookeeper注册中心获取IOrderService访问的url。
* 2. 进性远程调用RPC。
* 3. 将结果封装为一个代理对象,给这个变量赋值。
*
*/
@Reference// 远程注入
private IOrderService iOrderService;
验证接口
http://localhost:8080/findByUserId?userId=1
Dubbo入门案例_IDEA开启Dashboard
普通的Run面板
Run Dashboard面板
修改配置文件
在.idea/workspace.xml 文件中找到
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
添加配置
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
<option name="configurationTypes">
<set>
<option value="SpringBootApplicationConfigurationType" />
</set>
</option>
</component>
Dubbo高级特性_序列化协议安全
为什么需要序列化
网络传输的数据必须是二进制数据,但调用方请求的出入参数都是对象。
总结:
序列化就是将对象转换成二进制数据的过程,而反序列就是反 过来将二进制转换为对象的过程。
序列化反序列过程
流程: 不妨借用个例子帮助你理解,比如发快递,我们要发一个需要 自行组装的物件。发件人发之前,会把物件拆开装箱,这就好 比序列化;这时候快递员来了,不能磕碰呀,那就要打包,这就 好比将序列化后的数据进行编码,封装成一个固定格式的协议;
过了两天,收件人收到包裹了,就会拆箱将物件拼接好,这就好比是协议解码和反序列化。
实时效果反馈
1. Dubbo技术中网络传输的数据必须是____。
A 二进制数据
B 十进制数据
C 流
D 对象
Dubbo高级特性_地址缓存
地址缓存
注册中心挂了,服务是否可以正常访问?
答案:因为dubbo服务消费者在 第一次调用时 , 会将服务提供方地址缓存到本地 ,以后 在调用则不会访问注册中心。服务提供者地址发生变化时,注册中心会通服务消费者。
演示
关闭注册中心
./zkServer.sh stop
远程调用服务
http://localhost:8080/findByUserId?userId=1
实时效果反馈
1. Dubbo技术注册中心挂了,服务是否可以正常访问____。
A 可以
B 不可以
C 时好时坏
Dubbo高级特性_超时时间与配置覆盖关系
超时机制
问题:
- 服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一 直等待下去。
- 在某个峰值时刻,大呈的请求都在同时请求服务消费者,会造成线程的大呈堆积,势必会造 成雪崩。
- dubbo利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。
配置超时时间
服务生产者端
使用timeout属性配置超时时间,默认值1000,单位毫秒。
@Service(timeout = 3000) //当前服务3秒超时
public class OrderServiceImpl implements IOrderService {
修改服务提供者制造延迟
@Override
public CommonResult<Order> findByUserId(Long userId) throws InterruptedException {
CommonResult commonResult = new CommonResult();
// 返回结果编码
commonResult.setCode(200);
// 返回结果描述信息
commonResult.setMessage("查询成功");
// 返回结果集
//TODO 模拟数据库操作 突然数据库操作很慢
Thread.sleep(4000);
Order order = new Order();
order.setId(1L);
order.setUserId(1L);
order.setPrict(121.1);
order.setMobile("18588888888");
order.setAddress("北京市海淀区中关村");
order.setPay_method(1);
commonResult.setData(order);
return commonResult;
}
消费端
@Reference(timeout = 2000)// 远程注入
private IOrderService iOrderService;
报错
com.alibaba.dubbo.remoting.TimeoutException:
Waiting server-side response timeout
com.alibaba.dubbo.remoting.exchange.support.D
efaultFuture.get(DefaultFuture.java:107) ~
[dubbo-2.5.3.jar:2.5.3]
com.alibaba.dubbo.remoting.exchange.support.D
efaultFuture.get(DefaultFuture.java:84) ~
[dubbo-2.5.3.jar:2.5.3]
com.alibaba.dubbo.rpc.protocol.dubbo.DubboInv
oker.doInvoke(DubboInvoker.java:96) ~[dubbo-2.5.3.jar:2.5.3]
超时设置的优先级
上面有提到dubbo支持多种场景下设置超时时间,也说过超时是针对消费端的。那么既然超时是针对消费端,为什么服务端也可以设 置超时呢?
总结:
这其实是一种策略,其实服务端的超时配置是消费端的缺省配 置,即如果服务端设置了超时,任务消费端可以不设置超时时 间,简化了配置。另外针对控制的粒度,Dubbo支持了接口级 别也支持方法级别,可以根据不同的实际情况精确控制每个方 法的超时时间。
实时效果反馈
1. Dubbo技术中给服务设置超时时间解决___问题。
A 安全性
B 速度
C 响应慢
D 服务雪崩
2. Dubbo技术中如何设置服务的超时时间。
A @service(time=1000)
B @service(timeout=3000)
C @Reference(time=1000)