今天小编为大家带来的是社区作者 江南一点雨 的文章,让我们一起来学习设计微服务的版本号。
1. 语义化版本控制规范
https://semver.org/lang/zh-CN/
MAJOR(X):这个是主版本号,一般是涉及到不兼容的 API 更改时,这个会变化。 MINOR(Y):这个是次版本号,当我们对 API 进行向后兼容的增强时,这个版本号会变化,换句话说,也就是有新增的功能时,这里会变化。 PATCH(Z):这个是修订号,当我们进行一些 BUG 的修复,然后要发版的时候,这里会发生变化。
使用语义化版本控制的软件必须(MUST)定义公共 API。该 API 可以在代码中被定义或出现于严谨的文档内。无论何种形式都应该力求精确且完整。 标准的版本号必须(MUST)采用 X.Y.Z 的格式,其中 X、Y 和 Z 为非负的整数,且禁止(MUST NOT)在数字前方补零。X 是主版本号、Y 是次版本号、而 Z 为修订号。每个元素必须(MUST)以数值来递增。例如:1.9.1 -> 1.10.0 -> 1.11.0。 标记版本号的软件发行后,禁止(MUST NOT)改变该版本软件的内容。任何修改都必须(MUST)以新版本发行。有的小伙伴可能会说我们的项目处于快速开发阶段,API 不稳定,天天变,要是按照这个要求来得发多少个版本才够用呀!其实,一般 API 快速变化主要有两种情况,一种是项目刚立项的时候,此时主版本号为 0,那么这个时候的 API 就不能算是稳定的 API;另外一种情况则是下个主版本处于快速开发中,但是这种情况一般会有一个新的分支用来管理下个版本的代码,所以和这里的要求实际上并不冲突(具体参见第 4、5 条)。 主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共 API 不应该被视为稳定版。 1.0.0 的版本号用于界定公共 API 的形成。这一版本之后所有的版本号更新都基于公共 API 及其修改内容。那么有的小伙伴可能会纠结什么时候版本号从 0.Y.Z 变为 1.Y.Z 呢?一般来说,当你的项目已经上了生产环境或者说有稳定的 API 提供给别人使用的时候,基本上就可以算是 1.Y.Z 了。 修订号 Z(x.y.Z | x > 0)必须(MUST)在只做了向下兼容的修正时才递增。这里的修正指的是针对不正确结果而进行的内部修改。 次版本号 Y(x.Y.z | x > 0)必须(MUST)在有向下兼容的新功能出现时递增。在任何公共 API 的功能被标记为弃用时也必须(MUST)递增。也可以(MAY)在内部程序有大量新功能或改进被加入时递增,其中可以(MAY)包括修订级别的改变。每当次版本号递增时,修订号必须(MUST)归零。 主版本号 X(X.y.z | X > 0)必须(MUST)在有任何不兼容的修改被加入公共 API 时递增。其中可以(MAY)包括次版本号及修订级别的改变。每当主版本号递增时,次版本号和修订号必须(MUST)归零。 先行版本号可以(MAY)被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。数字型的标识符禁止(MUST NOT)在前方补零。先行版的优先级低于相关联的标准版本。被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。范例:1.0.0-alpha、1.0.0-alpha.1、1.0.0-0.3.7、1.0.0-x.7.z.92。 版本编译信息可以(MAY)被标注在修订版或先行版本号之后,先加上一个加号再加上一连串以句点分隔的标识符来修饰。标识符必须(MUST)由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止(MUST NOT)留白。当判断版本的优先层级时,版本编译信息可(SHOULD)被忽略。因此当两个版本只有在版本编译信息有差别时,属于相同的优先层级。范例:1.0.0-alpha+001、1.0.0+20130313144700、1.0.0-beta+exp.sha.5114f85。 版本的优先层级指的是不同版本在排序时如何比较。 只有数字的标识符以数值高低比较。 有字母或连接号时则逐字以 ASCII 的排序来比较。 数字的标识符比非数字的标识符优先层级低。 若开头的标识符都相同时,栏位比较多的先行版本号优先层级比较高。
例如:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0。判断优先层级时,必须(MUST)把版本依序拆分为主版本号、次版本号、修订号及先行版本号后进行比较(版本编译信息不在这份比较的列表中)。 由左到右依序比较每个标识符,第一个差异值用来决定优先层级:主版本号、次版本号及修订号以数值比较。例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。 当主版本号、次版本号及修订号都相同时,改以优先层级比较低的先行版本号决定。例如:1.0.0-alpha < 1.0.0。
2. 微服务中的版本号
理想情况下,我们应该只进行向后兼容的更新。
必须进行不兼容的升级。
spring:
application:
name: gateway
cloud:
nacos:
discovery:
password: nacos
username: nacos
server-addr: a.b.c.d:8848
namespace: public
gateway:
discovery:
locator:
# enabled: true
lower-case-service-id: true
routes:
- id: v1_provider
uri: lb://provider
predicates:
- Path=/p/**
- Header=Accept,.*;?version=1\.0(|;.*)
filters:
- StripPrefix=1
server:
port: 8082
首先记得关闭服务自动发现,否则通过默认的服务名进行代理就不会经过我们配置的过滤器了。 然后我们手动配置服务转发,上面的配置基本上都是常规配置,跟版本号相关的配置是 Header=Accept,.*;?version=1\.0(|;.*),这个配置就是对请求头提出要求,首先前面的 Accept 表示这里是要判断请求头中的 Accept 字段,然后后面紧跟着的是 value(两者之间用 , 隔开),这个 value 是一个正则表达式 .*;?version=1\.0(|;.*),意思就是在 version=1.0 之前和之后可以有任意字符串,只要 value 中包含 version=1.0 就算匹配上了。只有匹配上了,才会进行请求转发,否则不会进行请求转发。 最后,我们在发送请求的时候,设置如下请求头即可: