华为技术架构师分享:微服务架构下代码管理规范

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华为技术架构师分享:微服务架构下代码管理规范相关的知识,希望对你有一定的参考价值。

参考技术A

当下对于代码的管理,主要采用GitLab或GitHub,然而使用git进行代码管理过程中,一般有四种开发模式,分别为主干开发主干发布,主干开发分支发布,分支开发主干发布,分支开发分支发布。四种开发模式各有特色,下面将从针对四种开发模式进行一一说明。

但是针对微服务体系下,代码的管理,一般建议采用分支开发主干发布。

1. 代码管理模式

1.1. 主干开发+主干发布模式

模式特点:所有的操作都在主干上进行操作,随着时间的演进,代码只有一个版本,任何修改,均体现在主干上面,开发过程比较简单。

操作权限:该种模式对于开发人员与项目经理等在代码提交方面,权限相同;

适用场景:该种模式适用于团队规模较小,业务模型明确,且人员技能较高的开发团队。

1.2. 主干开发+分支发布模式

模式特点:所有的操作都在主干上进行操作,随着时间的演进,代码具有多个版本,运行多个版本可并行提供服务。

操作权限:该种模式对于开发人员与项目经理等在代码提交方面,权限相同;

适用场景:该种模式适用于多版本并存,但只维护一个版本的产品,其他版本不进行维护的项目,该种场景较少。

1.3. 分支开发+主干发布模式

模式特点:所有的代码提交都在分支上操作,随着时间的演进,需要构建Release版本时,需要将代码提交到主干上面,平常开发都是在分支上进行,好处可保证主干代码始终可用。

操作权限:该种方式开发人员只具有开发分支权限,无master权限,代码的merge只能由项目经理或有权人完成;

适用场景:该种模式适用于多功能并行开发,按照业务特性或模块进行在分支进行开发,然后在进行合并后进行Release构建发布,业务场景较复杂,且人员素质层次不齐,需要代码review。

1.4. 分支开发+分支发布模式

模式特点:所有的代码提交都在分支上操作,随着时间的演进,需要构建Release版本时,也是直接在分支上进行构建,各分支独立演进,与主分支关系不大,是主干开发主干发布的一个组合使用。

操作权限:该种方式开发人员与项目经理一样,只具有分支上的操作权限,不具有master权限。

适用场景:该模式适用于需求群/项目群的方式进行开发,大家公用同一个代码库,然后共享部门基础代码,然后各分支独立进行演进。

2. 代码管理规范

无规矩不成方圆,微服务架构下,代码的管理一般采用git进行管控,因此,在使用git进行版本控制时,应遵循一些原则及规范。

2.1. 代码管理原则

代码管理的原则,用于确保代码管理过程中不出现原则性错误,出现原则性错误,则会出现许多无用的操作,基本原则如下:

2.2. 代码管理规范

由于微服务一般建议采用分支开发主干发布,因此,本规范主要针对分支开发主干发布模式,具体规范如下:

华为技术专家谈微服务分布式架构的服务配置管理

单体应用只需管理一套配置,而微服务架构后,每个系统都有自己的配置,并且各不相同,有些配置还需要能够动态改变,以动态降级、切流量、扩缩容,那微服务架构下,到底服务配置该如何管理。

本地配置

最简单的,在代码里写配置。

比如下面这段代码用到Hystrix,并且在代码里定义了几个配置:

  • 线程的超时时间是3000ms
  • 熔断器触发的错误比率是60%
@HystrixCommand(fallbackMethod = "getDefaultProductInventoryByCode",
    commandProperties = {
       @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
       @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value="60")
    }
)

public Optional<ProductInventoryResponse> getProductInventoryByCode(String productCode)
{
    ....
}

还有一种方式,就是抽取到配置文件

使配置与代码分离,比如下面这段代码。

@HystrixCommand(commandKey = "inventory-by-productcode", fallbackMethod = "getDefaultProductInventoryByCode")
public Optional<ProductInventoryResponse> getProductInventoryByCode(String productCode)
{
    ...
}

相应的配置可以抽离到配置文件中,配置文件的内容如下:

hystrix.command.inventory-by-productcode.execution.isolation.thread.timeoutInMilliseconds=2000
hystrix.command.inventory-by-productcode.circuitBreaker.errorThresholdPercentage=60

以上方案都相当于把配置存在应用程序的本地。这样如果需要修改配置,就要重新走一遍代码或配置的发布流程。这往往需要一次新的上线发布过程,且权限更繁琐。

倘若能有一个集中管理配置的地方,若要修改配置,只需在这个地方修改一下,线上服务就自动从这个地方同步过去,不需要走代码或配置的发布流程,不就简单多了?

这就是配置中心

设计思想就是把服务的各种配置,如

  • 代码里配置的各种参数
  • 服务降级的开关
  • 依赖的资源等

都集中统一管理。服务启动时,可自动从配置中心中拉取所需配置,且若有配置变更,同样可自动从配置中心拉取最新配置信息,服务无需重新发布。

配置中心一般包含如下功能:

  • 配置注册
  • 配置反注册
  • 配置查看
  • 配置变更订阅

那配置中心的这些功能是如何实现的呢?

配置存储结构

一般配置中心存储配置按Group存的,同类配置放在一个Group下,以K, V键值对存储

配置注册

配置中心对外提供接口/config/service?action=register完成配置的注册功能,需要传递的参数包括配置对应的分组Group,以及对应的Key、Value。

比如调用下面接口请求就会向配置项global.property中添加Key为reload.locations、Value为/data1/confs/system/reload.properties的配置。

curl "http://ip:port/config/service?action=register" 
-d "group=global.property&key=reload.locations&value=/data1/confs/system/reload.properties"

配置反注册

配置中心对外提供接口config/service?action=unregister,传递参数包括配置对象的分组Group、对应的Key。
比如调用下面的接口请求就会从配置项global.property中把Key为reload.locations的配置删除。

curl "http://ip:port/config/service?action=unregister" -d
"group=global.property&key=reload.locations"

配置查看

配置中心对外提供接口config/service?action=lookup,需传参配置对象的分组Group、对应的Key。
比如调用下面的接口请求就会返回配置项global.property中Key为reload.locations的配置值。

curl "http://ip:port/config/service?	
	action=lookup&group=global.property&key=reload.locations"

配置变更订阅

配置中心对外提供接口config/service?action=getSign来完成配置变更订阅接口,客户端本地会保存一个配置对象的分组Group的sign值,同时每隔一段时间去配置中心拉取该Group的sign值,与本地保存的sign值做对比。一旦配置中心中的sign值与本地的sign值不同,客户端就会从配置中心拉取最新的配置信息。比如调用下面的接口请求就会返回配置项global.property中Key为reload.locations的配置值。

curl "http://ip:port/config/service?
	action=getSign&group=global.property"

配置中心便于我们管理服务的配置信息,并且如果要修改配置信息,只需要同配置中心交互,应用程序会通过订阅配置中心的配置,自动完成配置更新。

哪些场景适合使用配置中心呢?

资源服务化

应用规模不大时,所依赖的资源如Redis缓存或者RabbitMQ消息队列的数量不多,对应IP可直接写在配置。

但随公司赚到钱后,所依赖资源数量也开始骤增,比如上千个。这时就经常会遇到个别节点不可用,若还采用本地配置,就需要去更改本地配置,把不可用的IP改成可用IP,然后发布新的配置,太麻烦了!

可采用资源服务化,把对应缓存统统归为一类配置,然后若有个别机器不可用,只需在配置中心把对应IP换成可用的IP,应用程序会自动同步到本机,也无须发布。

业务动态降级

微服务架构下,拆分的服务越多,出现故障的概率就越大,因此需要有对应的服务治理手段,比如要具备动态降级能力,在依赖的服务出现故障的情况下,可以快速降级对这个服务的调用,从而保证不受影响。为此,服务消费者可以通过订阅依赖服务是否降级的配置,当依赖服务出现故障的时候,通过向配置中心下达指令,修改服务的配置为降级状态,这样服务消费者就可以订阅到配置的变更,从而降级对该服务的调用。

分组流量切换

为保证异地多活以及本地机房调用,一般服务提供者的部署会按照IDC维度进行部署,每个IDC划分为一个分组。此时,若一个IDC出现故障,可以把故障IDC机房的调用切换到其他正常IDC。为此,服务消费者可以通过订阅依赖服务的分组配置,当依赖服务的分组配置发生变更时,服务消费者就对应的把调用切换到新的分组,从而实现分组流量切换。

开源配置中心选型

  • Spring Cloud Config
    Spring Cloud中使用的配置中心组件,只支持Java语言,配置存储在git中,变更配置也需要通过git操作,如果配置中心有配置变更,需要手动刷新。
    Spring Cloud Config作为配置中心的功能比较弱,只能通过git命令操作,而且变更配置的话还需要手动刷新,如果不是采用Spring Cloud框架,不建议选择。

  • Apollo
    携程开源的分布式配置中心,支持Java和.Net语言,客户端和配置中心通过HTTP长连接实现实时推送,并且有统一的管理界面来实现配置管理。
    Apollo功能强大,在国内许多互联网公司内部都有大量应用,其中Apollo对Spring Boot的支持比较好,如果应用本身采用的是Spring Boot开发的话,集成Apollo更容易。

以上是关于华为技术架构师分享:微服务架构下代码管理规范的主要内容,如果未能解决你的问题,请参考以下文章

微服务直播Apache大佬联手华为云中间件领域总架构师开讲啦!

PPT | 从架构到组件,深挖istio如何连接管理和保护微服务2.0?

PPT | 从架构到组件,深挖istio如何连接管理和保护微服务2.0?

唯品会滴滴沪江架构师,关于微服务粒度高可用持续交互的实践分享交流(下)

华为架构师揭秘微服务架构(单体架构与微服务架构对比)

华为技术专家谈微服务分布式架构的服务配置管理