什麼是多版本
當一個接口的實現出現不兼容升級時,我們可以用版本號過渡,版本號不同的服務相互間不引用。
那麼我們應該如何進行版本遷移呢?我們可以採取以下步驟:
- 在低壓力時間段,先升級一半提供者爲新版本
- 再將所有消費者升級爲新版本
- 然後將剩下的一半提供者升級爲新版本
我們可以利用 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 版本的服務。