一种可行的云服务架构实现

本人很懒,只想说重点。


一直在公司负责一些基础框架及基础服务的编写,这写东西的特点是业务无关性属性较重,需求稳定且明确,一套框架或服务能给更条业务线使用,如分布式分布式定时任务服务、分布式全文搜索服务、分布式图片存取服务、分布式邮件发送服务、分布式短信发送服务、分布式地理位置服务等等等等。


问题:

基于传统的多环境各用一套配置的作法优点是简单明确,但缺点是多个环境都需要部署一套基础服务,即使代码完全一样只是配置有所不同而矣。比如一个全文搜索服务,拿es来说,各环境的cluster nodes和索引源就各不一样(不然索引文件会冲突),如果以目前成熟的Spring Profile作多环境配置区分,那么各个环境的配置不一样(比如开发环境是config-dev.properties,测试环境是config-test.properties,alpha环境为config-alpha.properties,beta环境为。。。),那么全文搜索服务需要针对各环境都部署一套。如果再加上各业务线呢,比如我们公司有5条业务线,但都会用到这些基础服务,假设内网环境为3个(test, alpha, beta),那么总共需要部署5*3=15套基础服务,这还只是一个全文搜索服务,再加上各基础服务数量,比如10个基础服务,这就总共需要有5*3*10=150个服务!!而且以后每增加一条业务线或每增加一个环境,这些基础服务都需要增量部署,这对于运维来说简直是灾难。


尝试现成的开源解决方案:

也许有人的本能反应是通过配置中心来解决,但目前互联网上的开源比如淘宝的diamond和百度的disconf它们主要致力于更新而不是增删,也就是说所有的变量要在事先确定。它们的应用场合的基本前提是确定了已有的变量,它们的应用目的主要是为了调参,比如一个timeout变量本来是5s,后经系统监控或其他方式决定将timeout调成3s才最合适。但对于增删变量的需求,它们无法很好满足。而事实上我现在说的需求就是增删可能会比较频繁的,比如增加一条业务线的一个环境,你事先没法知道是哪条业务线的哪个环境,又比如删掉一条业务线的一个环境,你也无法预先得知,这时候我们该怎么办呢?


单容器动态多实例方案:

拿最简单的数据库来说吧,传统方案会针对于多环境各配置一个db url,db user, db pwd等,这些数据是写在多环境的配置文件里的。并且容器启动的时候会静态加载这个配置拿到一个DataSource,于是对于N个环境的不同db配置,需要N个容器来启动实现物理隔离,这种方式也就回到了一开始的问题。

有一种可行的单容器动态多实例方案能解决上述问题,还是拿数据库来说吧,该容器通过一个“新配置中心”(它可以是在一个db、一个文件系统、zkp等等)读取已知的各个环境,并且动态地创建相应的DataSource来接受各个环境的请求。当增加一条业务线的一个环境时,我们可以动态地创建这个环境的DataSource;当删除一条业务线的一个环境时,我们可以动态地销毁这个环境的DataSource;当更新一条业务线的一个环境时我们可以动态地销毁这个环境的DataSource然后再创建这个环境的新的DataSource。按照这种作法,我们就可以支持一套基础服务部署就能支撑N条业务*M个环境了。

拿之前假设的数据,就可以从5*3*10=150个服务减到固定10个服务,如果以一个服务一台机器(物理机或虚拟机)来说,我们就可以将服务器机器台数从150台直线减到10台,并且一直维持10台的数量。


目前我们公司就是这么做的,大大节省了服务器数量以及运维成本。从设计的架构来看,这就是一种云服务,调用者只需申请一个全局唯一的app id就能享用基础服务,比如我们有一条业务线叫c2c电商,它需要增加一个内部环境gamma,那么这个app id就可以是c2c-gamma。首先申请者需要通过我们的admin管理界面配置好各基础服务的信息,点击申请完成后,我们的消息中心就会扩播这条消息到我们的各个有关联的基础服务,然后我们的基础服务就可以通过新配置中心拿到这个c2c-gamma的服务配置然后动态地启用它。

你可能感兴趣的:(架构)