dubbo笔记

多版本问题

官方说明多版本解决办法http://dubbo.apache.org/zh-cn/docs/user/demos/multi-versions.html

服务提供方当实现一个接口,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。

服务提供方在实现方法的注解里添加版本信息

import java.util.Arrays;
import java.util.List;

import org.apache.dubbo.config.annotation.Service;

import com.yhy.gmall.bean.UserAddress;
import com.yhy.gmall.service.UserService;

//版本1
@Service(version = "1")
public class UserServiceImpl implements UserService {

	@Override
	public List<UserAddress> getUserAddressList(String userId) {
		System.out.println("UserServiceImpl.....old...");
		UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y");
		UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N");

		return Arrays.asList(address1, address2);
	}

}
import java.util.Arrays;
import java.util.List;

import org.apache.dubbo.config.annotation.Service;

import com.yhy.gmall.bean.UserAddress;
import com.yhy.gmall.service.UserService;

//版本2
@Service(version = "2")
public class UserServiceImpl2 implements UserService {

	@Override
	public List<UserAddress> getUserAddressList(String userId) {
		System.out.println("UserServiceImpl.....new...");
		UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y");
		UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N");

		return Arrays.asList(address1, address2);
	}

}

消费者

在注解里添加版本信息,可以是提供方写的版本1或2;也可以是*,随机选取。

import java.util.List;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

import com.yhy.gmall.bean.UserAddress;
import com.yhy.gmall.service.OrderService;
import com.yhy.gmall.service.UserService;

@Service
public class OrderServiceImpl implements OrderService {

        //*代表随机选取一个版本
	@Reference(version = "*")
	UserService userService;

	@Override
	public List<UserAddress> initOrder(String userId) {
		System.out.println("用户id:" + userId);
		// 1、查询用户的收货地址
		List<UserAddress> addressList = userService.getUserAddressList(userId);
		for (UserAddress userAddress : addressList) {
			System.out.println(userAddress.getUserAddress());
		}
		return addressList;
	}
}

然后运行程序N次,发现打印的结果却是每次不一样

UserServiceImpl.....new...
UserServiceImpl.....old...
UserServiceImpl.....new...
UserServiceImpl.....old...
UserServiceImpl.....old...
UserServiceImpl.....new...
UserServiceImpl.....new...
UserServiceImpl.....new...
UserServiceImpl.....old...
UserServiceImpl.....new...

注意:如果加上超时时间,调用服务方的方法超出了指定时间(比如3秒)且消费者指定服务版本为*(随机),则会在重复调用两次(因为),因为出错,默认远程服务调用重试次数为2,所以总共,控制台打印三次。

本地存根

这篇介绍本地存根可以:https://zhuanlan.zhihu.com/p/98422736 

官方文档:http://dubbo.apache.org/zh-cn/docs/user/demos/local-stub.html

在远程调用服务提供者的实现之前,如果需要做一些参数验证、缓存、判断、小功能等等,满足要求再调用服务提供者的远程服务,则我们可以通过编写一个本地存根来实现这种功能,就是类似aop环绕功能。

比如对上面的案例,调用UserService实现类之前做一些参数校验,就可以使用这个办法。

1.编写一个本地存根方法,这个方法一般都写在api公用模块里,boot-user-service-provider在依赖gmall-interface

public class UserServiceStub implements UserService {

	private final UserService userService;

	public UserServiceStub(UserService userService) {
		this.userService = userService;
	}

	@Override
	public List<UserAddress> getUserAddressList(String userId) {
		System.out.println("本地存根。。。。。。。。。。。");
		if (userId != null) {
			return userService.getUserAddressList(userId);
		}
		return null;
	}

}

2.在调用方法处,声明使用本地存根,注解方式就在@Reference里面添加stub属性,值为类全限定名。

@Service
public class OrderServiceImpl implements OrderService {

	@Reference(timeout = 3000, version = "*", stub = "com.yhy.gmall.service.UserServiceStub")
	UserService userService;

	@Override
	public List<UserAddress> initOrder(String userId) {
		System.out.println("用户id:" + userId);
		// 1、查询用户的收货地址
		List<UserAddress> addressList = userService.getUserAddressList(userId);
		for (UserAddress userAddress : addressList) {
			System.out.println(userAddress.getUserAddress());
		}
		return addressList;
	}
}

3.然后调用,查看结果,可以看到存根,先被调用,确认userId不为空才进入远程方法。

用户id:56133
本地存根。。。。。。。。。。。
北京市昌平区宏福科技园综合楼3层
深圳市宝安区西部硅谷大厦B座3层(深圳分校)

不能远程调用带泛型参数的方法

比如消费者(控制层调用服务层)使用了mybatis plus中的带泛型参数的方法

default T getOne(Wrapper<T> queryWrapper)
@Reference
private AdminService adminService;

@RequestMapping(value = "/info", method = RequestMethod.GET)
    @ResponseBody
    public Object getAdminInfo(HttpServletRequest request) {
    Admin umsAdmin = adminService.getOne(new QueryWrapper<Admin>().eq("username", userName));
}

就无法 调用会报错

com.alibaba.dubbo.remoting.RemotingException: Fail to decode request due to: RpcInvocation [methodName=getOne, parameterTypes=[class com.baomidou.mybatisplus.core.conditions.Wrapper], arguments=null, attachments={path=com.yhy.gmall.ums.service.AdminService, input=1847, dubbo=2.6.2, version=0.0.0}]

但是调用不带泛型参数的就行

default T getById(Serializable id)

解决办法,封装起来调用,用的mp,所以封装mapper的调用

@Service
@Component
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {   
 @Override
    public Admin getUserInfo(String userName) {
        return adminMapper.selectOne(new QueryWrapper<Admin>().eq("username",userName));
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值