1、升级原则
- 隔离性:v1升级到v2时,相互独立,互不不干扰。
- 稳定性:服务不停止,完成升级。接口保持畅通。
2、具体实现
2.1 eureka项目
搭建eureka,网上很多,就省略了。
2.2 feign接口项目
2.2.1 依赖
<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>
<parent>
<groupId>com.spring.cloud.pro</groupId>
<artifactId>com.spring.cloud.pro</artifactId>
<version>1.0.0.RELEASE</version>
</parent>
<artifactId>com.spring.cloud.pro.facade</artifactId>
<description>接口</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
2.2.2 接口定义
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.spring.pro.model.User;
/**
* @Title: UserFacade.java
* @ProjectName com.spring.cloud.pro.facade
* @Description:
* @author ybwei
* @date 2019年1月11日 下午4:18:09
*/
@FeignClient("eureka-provider${version}") //name等于服务提供者的spring.application.name
public interface UserFacade {
/**
* @Description:
* @Param: @param id
* @Param: @return
* @Param: @throws Exception
* @return: User
* @Author: ybwei
* @Date: 2019年1月11日 下午4:20:59
*/
@GetMapping("/getUser")
public User getUser(@RequestParam("id") Integer id) throws Exception;
}
import lombok.Data;
/**
* @Title: User.java
* @ProjectName com.spring.cloud.pro.facade
* @Description:
* @author ybwei
* @date 2019年1月11日 下午4:18:49
*/
@Data
public class User {
private Integer id;
private String name;
private Integer age;
}
2.3 生产者
2.3.1 依赖
<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>
<parent>
<groupId>com.spring.cloud.pro</groupId>
<artifactId>com.spring.cloud.pro</artifactId>
<version>1.0.0.RELEASE</version>
</parent>
<artifactId>com.spring.cloud.provider</artifactId>
<version>1.0.1.RELEASE</version>
<description>服务提供者</description>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>com.spring.cloud.pro.facade</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.3.2 application.yml配置
version: '@project.version@' #项目版本
server:
port: 8083
spring:
application:
name: eureka-provider${version}
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
hystrix:
command:
default:
execution:
timeout:
enabled: false #hystrix禁止超时设置
2.3.3 代码
package com.spring.pro.controller;
import org.springframework.web.bind.annotation.RestController;
import com.spring.pro.facade.UserFacade;
import com.spring.pro.model.User;
/**
* @Title: UserController.java
* @ProjectName com.spring.cloud.provider
* @Description:
* @author ybwei
* @date 2019年1月11日 下午4:25:19
*/
@RestController
public class UserController implements UserFacade {
@Override
public User getUser(Integer id) throws Exception {
User user=new User();
user.setId(id);
user.setName("李四");
user.setAge(21);
return user;
}
}
2.4 消费者
2.4.1 依赖
<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>
<parent>
<groupId>com.spring.cloud.pro</groupId>
<artifactId>com.spring.cloud.pro</artifactId>
<version>1.0.0.RELEASE</version>
</parent>
<artifactId>com.spring.cloud.pro.consumer</artifactId>
<version>1.0.1.RELEASE</version>
<description>消费者</description>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>com.spring.cloud.pro.facade</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.4.2 application.yml配置
version: '@project.version@' #项目版本
server:
port: 8084
spring:
application:
name: eureka-consumer${version}
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
feign:
hystrix:
enabled: true #启用hystrix
hystrix:
command:
default:
execution:
timeout:
enabled: false #hystrix禁止超时设置
2.4.3 代码
package com.spring.pro.controller;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.spring.pro.facade.UserFacade;
import com.spring.pro.model.User;
/**
* @Title: UserController.java
* @ProjectName com.spring.cloud.pro.consumer
* @Description:
* @author ybwei
* @date 2019年1月11日 下午4:27:14
*/
@RestController
public class UserController {
@Resource
private UserFacade userFacade;
@GetMapping("/getUser")
public User getUser(Integer id) throws Exception {
return userFacade.getUser(id);
}
}
3、说明
3.1 核心逻辑
消费者调用的的生产者是spring.application.name+版本号。
3.2 升级过程
当系统进行从v1升级到v2:
- 项目的生产者、消费者项目版本号升级。v1升为v2。项目的生产者、消费者项目版本号保持一致。
- 生产者的50%升级到v2版本。如果全部升级,v1版本消费者都会失败。
- 消费者全部升级到v2版本。
- 生产者全部升级到v2版本。
注意:示例中生产者、消费者项目使用的pom.xml中的版本号,也可以使用常量(如1.0),只要保持两者一致即可。
3.3 适用场景
- 接口v1版本与v2版本不兼容时,app强制更新,适用。
- 接口v1版本与v2版本兼容,app不需要更新,适用。
3.4 版本控制
3.4.1 命名规范
参考软件版本命名规范
3.4.2 注意
多团队开发时,版本号尽量由一个人来控制,避免冲突。同一天上线,为统一版本号。不同时间上线为不同版本号。