上一篇博文《
部署问题域分析》主要是讲述了平时听到的一些一线研发工程师的直接需求。解决问题的第二步是分析问题,OK,那我们就来看看这些问题的本质~~以下只是我的私人观点,有说得不对的地方欢迎大家批评指正一起讨论~~
部署实质是对线上环境的一种变更
部署需要做到幂等,不管上线多少次,只要是同一个发布包,就应该达到同样的效果
部署的大致流程是在一个中心点触发部署动作,之后在各个目标机器上执行一段部署脚本来搞定整个过程
对于目标机器上执行的这段部署脚本的逻辑,只能说一句话:唯一不变的就是变化本身。。。各个产品服务的部署真TMD千差万别
咱们先从宏观角度来考虑整个流程,其实还是有些共通点的,O(∩_∩)O~
1、准备要上线的服务包,最好有个统一的编译平台,从你代码的版本库中检出,然后构建,最终产出一个source.tar.gz,名称随便起的啦,不过尽量是个整包,不要搞成散文件,因为这个东东是要拿来部署滴,是要有网络传输滴
这里用到了平台的两个功能:
1)、编译,对于依赖比较多的大一点的项目,有个统一的编译的地方是平台化的第一步;
2)、版本化存储产出,对于编译产物一定要保存在一个靠谱的存储上,而且要有版本化,方便历史版本回溯回滚,如果上线的目标机器数量比较多,同时到这个存储上来拉取源包,也要注意一下吞吐量问题。
2、到某个中心点去触发本次部署动作,可以是从命令行,可以是从web页面上,这个动作的触发需要一些部署元信息传入,比如你的服务要部署到哪些机器上,要部署到哪个路径下,要用哪个工作账号来执行部署动作,要上线的服务包在哪里,等等吧,对于像目标机器列表这种信息,纯粹通过命令行参数是搞不定的,一般都是用一个配置文件,或者直接在web上配置。
这里又有一个平台可以接管的公共需求:就是维护服务的元信息,因为这些信息实际变化不频繁,而每次都让用户输入实在是不合适,为了便于统一管理,便于发起上线,最好把这些元信息存储起来,到时候用户触发上线的时候就传入一个全局唯一的服务名即可,具体怎么上线这个服务,去服务元信息库取吧
3、权限判断,这是整个流程中非常重要的一步;谁可以对哪些机器发起变更(这句话的权限描述是面向机器的,如果是云平台就是另一种描述方法了哈),换句话说,就是谁可以发起上线,可以上线到哪些机器上;这里同样可以由平台来解决:
1)认证,他说他是某人,真的么?认证一下,显然,需要一个统一的认证中心
2)他的确是某人,但是他有权限么?噢~去问问权限中心~
4、OK,到此为止,这个穿越了重重阻隔的部署请求可以被实质性响应了,说,我要部署到1万台机器上,每次部署500台(全并发),这500台部署完了之后再部署500台,同样是全并发,直到最后1万台全部完成~~说的有点复杂了哈,一般产品是说,来,部署这20台机器,一台接着一台串行执行,或者说,部署这20台机器,不过需要先部署2台小流量机器,看看效果,如果觉得确实没问题了,再上线剩下的18台。发现问题了么?是的,又到了平台出手的时候了,解决这种任务调度策略问题。有并发控制,有暂停、继续、跳过之类的控制,这点是所有部署场景都需要的一个东东,那么,交给平台来做吧
5、上面说的是调度,调度完了之后就需要去具体执行,ssh上去?写个agent?无论如何,都要提供这种到远程机器执行命令的能力,对于管理的机器数目比较少的情形,用ssh未尝不可,不过对于大量的机器部署,还是搞个agent比较方便(agent编写的难度问题是另一个问题,呵呵),再重复一遍,在整个大的部署流程中,其中很重要的一步是到远程机器执行某个命令
6、走到这就接近尾声了,不过也是灰常重要的一点,即到远程机器上执行的这个命令,或者说这个部署脚本,这是个很高度定制化的东东,由于产品服务不同,部署方式会千差万别,所以……用户自己搞吧,平台只是帮你执行一下你写好的部署脚本,但是却很难帮你部署,否则,平台将会陷入无尽的需求泥淖(画外音:如果所有的发布包都是规范的,其实平台也是可以帮忙搞定的,呵呵)。这里有一点容易被忽视:单机执行的这个部署脚本从哪里来?
在第2步中有讲,需要传给部署系统很多的参数,很多的配置,实际部署脚本本身就可以在这个过程一并传入,把所有的参数也做成配置文件,加上脚本,打成一个包,我姑且称其为部署命令描述符,即只要这个包内的脚本在目标机器run起来,就可以完成部署,它是整个部署过程的入口。
这里有两个问题:
6.1、这个部署脚本在哪里维护?
我之前博文:《 用持续集成的观点来看Maven》有提到,乔帮主说:Everything is code. 这个脚本同样需要有版本控制,可以直接与源码同源,但是有的上线过程就仅仅只是执行一条命令(比如回滚动作,只是换个软链),这样来看,部署脚本没必要和产品发布包打包在一起,虽然他们是在同一个版本库中维护的,呵呵,还是分成cmd.tar.gz(部署命令描述符)和srv.tar.gz(服务发布包)比较好
6.2、所有有部署需求的产品服务都需要自己写这个部署脚本么?
没必要,部署发布team的同学可以给一个默认实现,比如:从某某位置wget srv.tar.gz => stop服务 => 上文件 => start服务,过程中最好是把操作类库化工具化,之后用户想修改默认实现的时候可以灵活组装
O了,到此为止,我们涉及到哪些平台和可以做的点?简单总结一下~
a、编译平台
b、制品存储平台,或者说叫产品库
c、产品库的东西要上线到N台服务器上,啊,是的,如果有个p2p工具就好了,OK,这点有空也可以考虑考虑
d、产品库可能只是在某一个机房有存储,上线是跨机房的,咋办?啊,要是在目标机房有个中转机就更好了,考虑下哦
e、服务元信息库,姑且称为SrvDB
f、认证中心,实际每个公司一般都是有的,很可能早于部署系统就有了
g、权限中心,人可以对哪些机器有什么操作权限
h、调度中心,负责并发控制、失败重试、log管理之类的
i、agent,调度中心的手脚
j、默认部署脚本及常用类库:DeployUtils
嗯,差不多了,我目前是想到这么多
以上的部署思路实际只是针对现有部署需求而搞出来的一个极具灵活性的工具平台,但是,这样真的好么?O(∩_∩)O~不尽然哦,当机器数目超过100K的时候,可能一个好的规范和自动化平台就派上用场了,不过不着急哈,万事总要有个发展的过程,工业社会很久之后才到了信息社会的。
部署实质是对线上环境的一种变更
部署需要做到幂等,不管上线多少次,只要是同一个发布包,就应该达到同样的效果
部署的大致流程是在一个中心点触发部署动作,之后在各个目标机器上执行一段部署脚本来搞定整个过程
对于目标机器上执行的这段部署脚本的逻辑,只能说一句话:唯一不变的就是变化本身。。。各个产品服务的部署真TMD千差万别
咱们先从宏观角度来考虑整个流程,其实还是有些共通点的,O(∩_∩)O~
1、准备要上线的服务包,最好有个统一的编译平台,从你代码的版本库中检出,然后构建,最终产出一个source.tar.gz,名称随便起的啦,不过尽量是个整包,不要搞成散文件,因为这个东东是要拿来部署滴,是要有网络传输滴
这里用到了平台的两个功能:
1)、编译,对于依赖比较多的大一点的项目,有个统一的编译的地方是平台化的第一步;
2)、版本化存储产出,对于编译产物一定要保存在一个靠谱的存储上,而且要有版本化,方便历史版本回溯回滚,如果上线的目标机器数量比较多,同时到这个存储上来拉取源包,也要注意一下吞吐量问题。
2、到某个中心点去触发本次部署动作,可以是从命令行,可以是从web页面上,这个动作的触发需要一些部署元信息传入,比如你的服务要部署到哪些机器上,要部署到哪个路径下,要用哪个工作账号来执行部署动作,要上线的服务包在哪里,等等吧,对于像目标机器列表这种信息,纯粹通过命令行参数是搞不定的,一般都是用一个配置文件,或者直接在web上配置。
这里又有一个平台可以接管的公共需求:就是维护服务的元信息,因为这些信息实际变化不频繁,而每次都让用户输入实在是不合适,为了便于统一管理,便于发起上线,最好把这些元信息存储起来,到时候用户触发上线的时候就传入一个全局唯一的服务名即可,具体怎么上线这个服务,去服务元信息库取吧
3、权限判断,这是整个流程中非常重要的一步;谁可以对哪些机器发起变更(这句话的权限描述是面向机器的,如果是云平台就是另一种描述方法了哈),换句话说,就是谁可以发起上线,可以上线到哪些机器上;这里同样可以由平台来解决:
1)认证,他说他是某人,真的么?认证一下,显然,需要一个统一的认证中心
2)他的确是某人,但是他有权限么?噢~去问问权限中心~
4、OK,到此为止,这个穿越了重重阻隔的部署请求可以被实质性响应了,说,我要部署到1万台机器上,每次部署500台(全并发),这500台部署完了之后再部署500台,同样是全并发,直到最后1万台全部完成~~说的有点复杂了哈,一般产品是说,来,部署这20台机器,一台接着一台串行执行,或者说,部署这20台机器,不过需要先部署2台小流量机器,看看效果,如果觉得确实没问题了,再上线剩下的18台。发现问题了么?是的,又到了平台出手的时候了,解决这种任务调度策略问题。有并发控制,有暂停、继续、跳过之类的控制,这点是所有部署场景都需要的一个东东,那么,交给平台来做吧
5、上面说的是调度,调度完了之后就需要去具体执行,ssh上去?写个agent?无论如何,都要提供这种到远程机器执行命令的能力,对于管理的机器数目比较少的情形,用ssh未尝不可,不过对于大量的机器部署,还是搞个agent比较方便(agent编写的难度问题是另一个问题,呵呵),再重复一遍,在整个大的部署流程中,其中很重要的一步是到远程机器执行某个命令
6、走到这就接近尾声了,不过也是灰常重要的一点,即到远程机器上执行的这个命令,或者说这个部署脚本,这是个很高度定制化的东东,由于产品服务不同,部署方式会千差万别,所以……用户自己搞吧,平台只是帮你执行一下你写好的部署脚本,但是却很难帮你部署,否则,平台将会陷入无尽的需求泥淖(画外音:如果所有的发布包都是规范的,其实平台也是可以帮忙搞定的,呵呵)。这里有一点容易被忽视:单机执行的这个部署脚本从哪里来?
在第2步中有讲,需要传给部署系统很多的参数,很多的配置,实际部署脚本本身就可以在这个过程一并传入,把所有的参数也做成配置文件,加上脚本,打成一个包,我姑且称其为部署命令描述符,即只要这个包内的脚本在目标机器run起来,就可以完成部署,它是整个部署过程的入口。
这里有两个问题:
6.1、这个部署脚本在哪里维护?
我之前博文:《 用持续集成的观点来看Maven》有提到,乔帮主说:Everything is code. 这个脚本同样需要有版本控制,可以直接与源码同源,但是有的上线过程就仅仅只是执行一条命令(比如回滚动作,只是换个软链),这样来看,部署脚本没必要和产品发布包打包在一起,虽然他们是在同一个版本库中维护的,呵呵,还是分成cmd.tar.gz(部署命令描述符)和srv.tar.gz(服务发布包)比较好
6.2、所有有部署需求的产品服务都需要自己写这个部署脚本么?
没必要,部署发布team的同学可以给一个默认实现,比如:从某某位置wget srv.tar.gz => stop服务 => 上文件 => start服务,过程中最好是把操作类库化工具化,之后用户想修改默认实现的时候可以灵活组装
O了,到此为止,我们涉及到哪些平台和可以做的点?简单总结一下~
a、编译平台
b、制品存储平台,或者说叫产品库
c、产品库的东西要上线到N台服务器上,啊,是的,如果有个p2p工具就好了,OK,这点有空也可以考虑考虑
d、产品库可能只是在某一个机房有存储,上线是跨机房的,咋办?啊,要是在目标机房有个中转机就更好了,考虑下哦
e、服务元信息库,姑且称为SrvDB
f、认证中心,实际每个公司一般都是有的,很可能早于部署系统就有了
g、权限中心,人可以对哪些机器有什么操作权限
h、调度中心,负责并发控制、失败重试、log管理之类的
i、agent,调度中心的手脚
j、默认部署脚本及常用类库:DeployUtils
嗯,差不多了,我目前是想到这么多
以上的部署思路实际只是针对现有部署需求而搞出来的一个极具灵活性的工具平台,但是,这样真的好么?O(∩_∩)O~不尽然哦,当机器数目超过100K的时候,可能一个好的规范和自动化平台就派上用场了,不过不着急哈,万事总要有个发展的过程,工业社会很久之后才到了信息社会的。