王渊命:QingCloud微服务实践全解析
2017年1月16日周二晚8点30分,青云QingCloud 容器平台负责人王渊命带来了主题为“基础设施服务的微服务化”的交流。以下是主持人小媛子整理的问题精华,记录了老王和读者间问答的精彩片段。
问:能说说创业小公司在微服务架构设计中的经验吗?在保证有限人力和敏捷开发的前提下,怎么设计一套自己的微服务体系?
答:说实话,微服务现在框架以及注册中心以及生态的成熟度还没有达到开箱即用的地步,如果是初创公司,首先要确保有人能把控整个系统,否则贸然上微服务适得其反。
我觉得上微服务要先回答几个问题:
为什么要上微服务?是为了解决当前的研发交付效率问题还是为了方便以后的扩展或者变更?前者的紧迫性大于后者。如果仅仅是后者的话,个人建议等业务模式验证后再进行微服务拆分,而不是创业初期就立刻使用微服务模式。
团队对新技术的接纳度如何?能否随着微服务技术的演进而跟进。微服务要伴随着自动化持续交付,以及服务管理和治理工具(主要是解决大量微服务的管理问题),而当前这些系统都在快速演进,需要有精力持续跟进。
综合说一下,建议初创团队谨慎采用微服务,不过可以借鉴思路。比如先从自动化持续交付做起,然后再上线容器编排,再搞服务拆分以及治理。
如果以上都搞定的情况下,自己设计微服务体系,首先是选择一个注册中心 etcd, zookeeper, consul, eureka 等。个人其实是比较看好 consul, eureka 这样专门的服务注册中心的,因为现在微服务最大的一个问题是注册中心的服务元数据格式没有标准。其次选择一种远程通讯协议和框架。拆分自己的业务其实是相对简单的,可以根据数据的隔离以及团队结构进行拆分。
问:1)一个创业公司,项目已经上线,怎么进行微服务切分?2)目前我的每个service功能比较多,类似这样的服务功能做的比较臃肿。感觉到做不下去了。如果不分,以后每个service功能更庞大。3)如果不拆的话,数据库不方便做分库方案。如果拆分了,那么牵扯多库操作微服务之间怎么进行事务控制。如果拆分了,那么牵扯多库操作微服务之间怎么保证事务一致性。
答: 1)这个可以参考前一个问题,先要思考为什么要切分,不要为微服务化而微服务化,然后再思考怎么切分。切分之前可以先进行一些技术改造,方便切分。比如避免模块间直接共享后端存储,模块间的互相依赖和调用至少要上升到service层面,不允许跨service直调用dao。等这些都做完了,拆分就是把service之间的依赖变成远程模式即可。
基础运维层面,我觉得如果当前没有太多精力的话,还是可以等一等各云厂商的方案。比如我们的现在基于IaaS的应用调度方案,还有即将推出的k8s服务。
2)这个我觉得是架构设计上的问题,可以不用着急拆成独立部署的服务,可以先拆成互相依赖的lib。如果独立拆分为lib都困难,那拆成独立部署的service更困难。
3)微服务的拆分可以先做架构设计上的逻辑拆分,再做服务实体拆分。
大多数情况下其实不需要跨服务的事务的,如果需要,就要思考服务是否拆的合理。如果是真需要,那可以考虑通过其他的机制实现分布式事务,不过这个复杂度就会高些了。但其实大多数场景你需要的可能不是分布式事务,只是需要一个分布式锁而已。
问:需要多表关联查询的时候怎么处理,及事务怎么控制?
答:数据库分库方案和微服务没多大关系。如果当前多个模块之间有数据共享的话,建议先消除数据共享。
如果拆分成微服务,肯定要消除多表关联查询的,除非多个表属于同一个服务。实际上拆分了微服务后,原来的多表关联查询是需要通过代码逻辑实现的。这样虽然增加了复杂度,但好处是可以很好的利用缓存。
问:请问服务拆分,是数据先拆还是架构先拆,为什么?
答:你说的数据先拆是消除数据共享么?建议是先消除数据共享再做架构拆分。
问:请问QingCloud的IaaS是完全自主研发的吗?为什么没有使用openstack cloudstack一类的? 应用zookeeper etcd的层 是实现的IaaS相关功能吗? QingCloud IaaS的微服务划分粒度是多少,能否举个具体例子?
答:是自主研发。openstack在公有云多租户情况下瓶颈较多,并且功能演进不容易掌控。文章里说的etcd、metad是指我们给用户提供的服务元数据服务,和我们的IaaS层没有关系。
问:请问QingCloud使用什么语言及相关库或框架开发?是不是应该按业务模块划分数据库?
答:主要使用python。框架使用了zeromq等。是的。
问:看到一种说法,微服务的架构应该各自独立的管理自己的数据。那么多个微服务访问同一个MySQL,或者其他NoSQL服务,是一种错误的实践吗?原本就有关联的微服务都访问同一个数据库,不是比通过API互相通讯,效率更高吗?
答:我同意这种说法,理想情况下每个微服务后面依赖的基础设施服务都应该是独立的。
但现实情况不可能这么理想,出于成本等各种原因需要共享数据库。共享数据库实例一定程度只影响部署和运维的独立性,这个是可以接受的。但直接共享数据则是绝对『***』的,是要避免的,即便不是微服务,是单体应用,也应该避免模块之间直接共享数据,而是要通过互相的service依赖。
避免这样做的主要原因是数据本身不能独立成服务,而是要通过代码逻辑的『解释』。如果把数据直接共享出去,当需要修改数据的『解释』方式,比如修改表结构,或者需要读取的时候对数据特殊处理一下,或者加一层缓存不立刻刷新到数据库,等等,你都不知道牵扯哪些模块,哪些部门。
所以数据最好是通过API『解释』后输出结果,如果有变更只需要修改一个模块即可。
问:我想再追问一下。多个微服务,访问的MySQL,应该是在database级隔离,还是大家各自自觉?此处的“隔离”指逻辑意义上的隔离。
答:逻辑意义上肯定是需要隔离的。
问:但是这样性能上又差了。
答:微服务本身就不是解决性能问题的,如果要性能,本地的lib依赖调用肯定效率高于远程的rpc。
问:比如:某个表,逻辑上,就是只能由某个服务去读写,其他服务不能(严格禁止)去直接访问这些数据。只能通过API。
答:对,我的回答就是这个意思,服务之间的数据通过库直接共享是要绝对避免的。不然就是一个坑。
问:是啊,这就是困扰的问题。在性能与架构的清晰性上,要有一个折中的点,这个很难把握。
答:其实反过来想一下,如果你的业务需要缓存,本身就要避免数据库层面的共享了。所以这个不仅仅是微服务的要求。一个没有缓存的服务,还考虑什么性能问题。
问:在我们的项目里,我也做过一个类似confd+metad的项目,但是没有推广成功。所以很想问问,实际推行这个方案时,有没有遇到什么阻碍?
答:这个我们也才刚开始推广,内部试验的结果是,刚开始还是有一些学习成本的,但只要有一个经验之后就容易了。
我们这个其实是给基础设施服务的厂商和用户之间搭建了一个桥梁,让基础设施服务的交付更简单,让用户使用也更简单,这两方面的推广我感觉应该阻碍不大。更大的阻碍应该在于让用户将自己的服务进行改造。这一点上我们还有许多需要改进的地方。
问:我解释一下当时的情况,也可以进一步聊聊。我当时其实做得特别简单,基于redis,做了一个items+template的模型,然后写了一个ruby的脚本,可以一键生成各种配置文件。当时只花了2个小时不到的时间,自己觉得很得意。受到的质疑是:为啥自己造轮子?不是有ansible or chef吗?基于成熟工具的配置管理,不是更加可靠吗?
答:我不太清楚你说的阻力来自于哪方面,我们这个对内部人来说降低了PaaS服务的研发成本,肯定是欢迎的。
我觉得只针对这点,你的这个轮子就值了。比如你可以让他们做一下lb后端服务节点扩展后lb配置的自动变更。这点 ansible就做不到。
问:对了,我当时的那个工具,不是一个常驻服务,只是为了docker build的时候,生成配置文件用的。所以,价值低了。
答:哦,如果这样的话,你的这个工具就和ansible差不多了。
问:不过,现在我们会选择k8s的方案,其实反而不必那么麻烦搞配置了。
答:嗯,不过k8s中的服务,有时候也是需要变更配置的,现在也没有比较好的方案。
问:对于中小型企业来说,很可能都还没用上zookeeper、docker这类技术,那么微服务对于这些企业来说意义在哪,或者有必要吗?
答:微服务其实有两种场景。
一种是企业应用私有部署的场景。
这种场景下,拆分微服务,对应用生产商来说,可以加快交付效率,方便形成产品矩阵,通过各种组合的方式交付产品给用户。比如一个任务管理系统,可以将用户系统,任务系统,沟通系统拆开,这样用户系统和沟通系统可以再组合一个采购管理系统,就是一套新的产品了。但这种拆分提高了使用者的安装运维成本,需要等待分布式应用管理系统的普及,比如我们做的这个系统就是一种。
另外一种是互联网或者SaaS服务。
这种场景下,运维者就是生产者自己,拆分的意义在于研发交付效率。如果当前这个的瓶颈不在这里,可以不用着急拆分,但思路可以借鉴,从而降低以后拆分时的成本。
zookeeper、docker这种其实应该属于基础设施服务,不应该是应用开发者本身需要太多关注的,只是当前的微服务体系还不太成熟。等生态再成熟一些,开发者就可以只关心自己的业务逻辑拆分和定义了,其他的都托管到云服务即可。
问:我阅读了全文,最后我都模糊了微服务的概念了,文章中做的这个叫配置下发吧?不是叫微服务吧?能符合自发布、自部署、松耦合吗?如果不是,怎么成为微服务?
答:这篇文章探讨的问题是微服务的场景下,每个微服务后面的基础设施服务,如何自动部署?伸缩,如何和应用本身的微服务互相感知?
你可以说这个不叫微服务,毕竟微服务的概念各人有各人的解释,有认为微服务就是无状态的,所以数据库本身不能算微服务。
但无论如何,即便是认为基础设施服务不算微服务,微服务是肯定是需要基础设施服务的,探讨这个问题的解决方案至少是有意义的。
另外我个人其实不太同意微服务(microservice)这个词的。世上没有微服务(microservice),只有服务(service),但服务这个词被SOA给用了,Martin Flower 可能觉得不好区分,所以加了个『微』(micro)字。
在我的理念里,服务就是一组暴露出远程编程接口的endpoint,接口可以是 Rest,可以是rpc,也可以是自定义协议(比如数据库或者缓存)。
问:正想追问一句,你对Cloud Native这个词,怎么看?
答:Cloud Native 我也算是国内早期推广者之一了。去年那次青云的开发大会上,我讲的就是这个主题。
Cloud Native 我觉得是当前云的一种演进,IaaS的任务是让大家先接受云,所以需要适应传统的应用机制,网络,主机,存储等都是模拟传统的机房的机制。
但到现在之后,大家基本上都接受了 IaaS了,第一步任务算是完成了,现在需要的是应用来适应云的机制,所以叫 Cloud Native 。
下面粘贴我的两页ppt来解答这个问题。
问:那和PaaS又什么区别?
答:传统的PaaS对应用的限制太多了,通用性有问题。但其实本质上用户需要的是一种更通用的 PaaS。
问:我觉得基础设施已经属于IaaS了。
答:其实我的观点是以后 IaaS 会回归到硬件层,上面的都归 PaaS/CaaS 了。
问:青云在比较了业界现有的产品(ansible/puppet/kubernetes/mesos)后,在深知现有产品的缺点后,是如何做出自己的 QingCloud 应用配置中心的?如何克服现有产品的那些缺点?如何做出自己独有的优势,以便推向公共应用市场时能打败其他同类竞争产品?想听更多技术内幕/细节 ;-)
答:这个谈不上打败,各种产品有各种产品的应用场景。各种产品其实都是在现实和理想之间的一种折中,只不过看倾向与哪边了。
比如我们的这个产品,相对kubernetes来说,更偏向于现实,为了适应各种集群系统,做了许多妥协。因为kubernetes可以等待应用去适应它,而不是它来适应应用,我们就不行,我们得交付给用户一个立刻可用的产品,还要能适应当前的多数分布式应用。
另外我们这个产品当前还是依托于我们的IaaS,无法独立使用,所以适用范围上来说,还是不一样的。
问:微服务化,一般都用什么来实现分布式锁来保证数据的最终一致性呢?
答:分布式锁的实现方式很多,比如用zookeeper,etcd,redis。本质上就是依赖一个共享存储来实现,利用共享存储的某个排他性操作,比如创建某个key,而获得一个独占资源的标志。
互联网业务实现最终一致性大多数不依赖于锁,而是通过其他的机制,比如定时的核对数据等方式来实现。
问:请问QingCloud的基础服务的运维和自动化框架的研发,是由运维来负责后期维护么,还是开发来负责维护的?在初创公司,有哪些服务,例如(数据库服务),适合做成微服务,数据库服务切分的原则是什么?
答:我们还是主要靠研发来维护具体的服务。初创公司的无状态业务服务适合做成微服务,其他的有状态服务除非是有云平台提供这种能力,否则不建议自己搞。数据库服务切分的原则这个貌似也想不出一个通用的原则,主要考虑独立性,数据量等元素吧。
问:微服务架构里各个微服务的配置管理有最佳实践么?一个问题是配置很多,一个问题是当需要同步修改多个微服务(不是指一个逻辑服务的多个实例,而是有上下游调用关系的服务们)如何做到优雅的配置更新?
答:依赖服务配置更新的例子我文章中有,思路就是通过服务注册中心来定义依赖关系,服务的变更要通过注册中心通知到其他的依赖方,然后由依赖方自己变更。
PS:附本场Chat过程中作者引用的PPT完整版下载。
(以上内容转自GitChat,版权归GitChat所有,转载请联系GitChat,微信号:GitChat,原文:《王渊命:QingCloud微服务实践全解析》
本文转载自异步社区。
原文链接:https://www.epubit.com/articleDetails?id=NC7E3EF931D2000012A30159169601323
- 点赞
- 收藏
- 关注作者
评论(0)