什么是多版本
当一个接口的实现出现不兼容升级时,我们可以用版本号过渡,版本号不同的服务相互间不引用。
那么我们应该如何进行版本迁移呢?我们可以采取以下步骤:
- 在低压力时间段,先升级一半提供者为新版本
- 再将所有消费者升级为新版本
- 然后将剩下的一半提供者升级为新版本
我们可以利用 Dubbo 的多版本实现灰度发布。
实现
我们在服务提供者中为当前服务指定一个版本号,例如在下面的例子中我们指定版本号为 1.0.0
package edu.szu.producer.serviceImpl;
import com.alibaba.dubbo.config.annotation.Service;
import edu.szu.api.service.NameService;
import org.springframework.stereotype.Component;
@Component
@Service(version = "1.0.0")
public class NameServiceImpl implements NameService {
@Override
public String updateName(String name) {
System.out.println("这是1.0.0版本的调用");
return "旧版本的名称:" + name;
}
}
现在业务进行了迭代,服务的实现也更新换代,在新服务中,我们将其版本号指定为 2.0.0
package edu.szu.producer.serviceImpl;
import com.alibaba.dubbo.config.annotation.Service;
import edu.szu.api.service.NameService;
import org.springframework.stereotype.Component;
@Component
@Service(version = "2.0.0")
public class NameServiceImpl2 implements NameService {
@Override
public String updateName(String name) {
System.out.println("这是2.0.0版本的调用");
return "新版本的名称:" + name;
}
}
在消费者中,我们可以指定使用提供者的哪一个版本的服务,如果指定使用 1.0.0 版本就会使用 1.0.0 版本的服务,如果指定使用 2.0.0 版本就会使用 2.0.0 版本的服务,如果我们想随机选择服务的话可以在版本号的选择中指定使用 *。
package edu.szu.consumer.serviceImpl;
import com.alibaba.dubbo.config.annotation.Reference;
import edu.szu.api.service.NameService;
import edu.szu.consumer.service.ChangeService;
import org.springframework.stereotype.Component;
@Component
public class ChangeServiceImpl implements ChangeService {
@Reference(version = "*")
NameService nameService;
@Override
public String change(String name) {
return nameService.updateName(name);
}
}
测试
我们进行几次远程调用,在控制台上查看结果,发现结果如下:
可以发现,因为我们在消费者的版本控制中指定使用了 *,所以消费者既会调用 1.0.0 版本的服务,也会调用 2.0.0 版本的服务。