前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >王晓波:同程艺龙Serverless沙龙分享

王晓波:同程艺龙Serverless沙龙分享

原创
作者头像
腾讯云开发者社区技术沙龙
修改2018-08-29 18:19:44
1.3K0
修改2018-08-29 18:19:44
举报

王晓波:专注于高并发互联网架构设计、分布式电子商务交易平台设计、大数据分析平台设计、高可用性系统设计。拥有十多年丰富的技术架构、技术咨询经验,深刻理解电商系统对技术选择的重要性。

同程艺龙跟腾讯不太一样,我们是主营机票的一家公司。其实这家公司做的蛮多的,跟大家的生活都相关。

Serverless在同程的应用,其实我们可以看到,刚才腾讯云分享的是在云端的Serverless。我要讲对同程来讲为什么做Serverless这件事?其实是来自于这么一个思考,就是一条SQL到一个服务的距离到底有多远?我们为什么做Serverless?是因为我们抢时间。时间对我们来说才是真正的成本。当年做这件事情的时候,我们每天都能有新发布。但是反过来想,每天发布其实并不重要,或者并不代表你能有什么能力。真正能力是什么呢?产品早上的需求,你晚上能不能上线?这个对电商来说是很重要的。所以我们考虑到做Serverless。

这个事做的比较早,在2016年下半年做,2017年就把大部分迁到Serverless上的都迁上去了。我们为什么这么大胆尝试它?因为2014年末和2015年初的时候,把同程的应用全部容器化。我们在2015年完成微服务切换。这两件事情完成后我们发现还做什么,我们发现这两件事情做完对我们是有提高,但是不是革命性的。我们再回到这个问题,在真正多元的应用场景SQL是很常见的东西,服务也是很常见的东西。从SQL到服务应用输出的话是多远的距离,其实非常非常远。这里的所有问题都会造成编程是不快乐的,比如测试环境在哪里,开发环境在哪里,CASH服务器在哪里,负载均衡在哪里,因为这些对我没有意义,我就想把它变成我的代码。这个事可以想想,能不能让一个SQL到一个服务的距离更加缩短。

我们怎么缩短这件事情?第一个事情,就是开发环境,测试环境,生产环境,灰度环境,各种环境。大家回想一下各种环境,当有故障的时候是如何产生的?当我们做高可用或者做线上检查的时候往往对生产环境把的很严,但是我们认为这个坏掉是对我们的损失,但是开发测试环境关注的多吗?没有,因为自己的挂掉就挂了。其实你需求减少,导致时间变长,随之导致市场竞争力下降。

还有框架,框架层出不穷,同程艺龙三千名开发员可以造出一大堆框架,但是这样的框架往往会出现很多的问题,不统一。再接下来这些环境是不是导致程序员不快乐?但是说作为一个好的程序员不应该懂这些吗?其实也是对的。因为对于一个全栈工程师来说当然懂得这些东西,但是问题是我们做的是工程学,工程应该有它的流水线和分工,所以这个问题就成了流水线上的障碍。

就这些障碍吗?不是。还有部署。看今天的上线从传统的的看,一个应用的发布可能会有半年、一年。曾经我看过一个日本人说他们在做日本保险。说这是大项目,开发半年,上线半年。我说部署呢?说部署很快。还有运维,就是人为把技术人员分成业务开发人员,写代码的,另外一类叫运维工程师。他们两者之间有没有矛盾呢?我们一直说产品同学和开发同学的矛盾最大的。但是反过来想过没有,运维工程师和程序员矛盾才叫大。为什么会这样?当第一个应用上线,我相信是没有运维工程师,因为运维工作一定是工程师自己干完的。但是到今天分工这么大后发现一个问题,鸿沟越来越大,最后就吵架了。我们能不能把运维废了,这个不是说不要他,而是让他躲在后面,让他无形的存在。无服务器这么多,里面一个很大的是无运维化,让运维躲到技术后面去。还有一件事情就是扩容,这件事情也是做了很多,当然也有高大上的,自动扩容,但是永远回避不了当流量冲过来会挂一下,所以如何做扩容?最简单的是埋点服务器上去,我也不跑,今天就一个亿流量过来,我就放两个亿服务器,不就不挂了吗,扩啥容呢?但是这个资源是浪费的,如何利用它。这个看起来是成本效率的相关。

这些东西加起来,是不是我们要去做Serverless的一个动力呢?其实还不是。还有一块,对于我们的服务行为,比如我们的调试,可以想象一下,我们在2015年的时候把所有的应用全部微服务化之后,带来了一个苦难。其实今天坦白说我们用微服务做很好。我为什么今天说微服务困难?可能当我们服务数很少的时候,比如我跟奈飞的同学交流他说他们有很多服务器。在同程艺龙有多少呢?光一个机票运作平台有接近一千个应用。这还是应用,应用是什么概念呢?是N个服务的拼装。我们有上千个。上千个微服务带来多少的可以独立部署的微服务呢?非常吓人。而且它的微服务还在不停的迭代。带来的调试基本抓瞎,提供了一大堆工具为他支撑,这个是非常痛苦的。还有性能,每个程序员都在关注性能,但是性能是不是每个程序员都应该关注的?如果从纯技术角度每个人都应该关注。但是关注不等于能解决。因为不是每个程序员都能把性能解决好。那是不是有一个很好的方式解决?像高并发这个性能好一些,这个高并发到哪儿就关掉,让它熔断。这样的话可以让程序员解放出来,来设计业务模型。

还有安全,这些安全并不是无缝的到每个程序员,如何通过一个平台把这些能力赋给程序员,让程序员不需要干其他技术的事。这些东西加起来,就是我们要去做Serverless的原因。从我们一开始设计,到我们开发上线,真的很远。这个很远的一个原因是没有办法安安心心写代码,因为这里的核心是应用这条线。而应用的核心是业务的模型,就是业务线。业务线上的老虎太多了,我们要打掉,所以就做Serverless。我们在2015年末做这个平台,做完后把同程可以进入它的应用进行应用。我为什么说可以进入呢?因为我们也是从底层,到隔离等等完全是私有化,我们做的时候认为很大程度下我们是在改正现在微服务带来的麻烦,所以我们很多框架的调度是在对微服务框架的封装和更新,后面会讲到为什么是这样的。

让程序员码代码快乐一点。十年前这个架构在同程会使用,说输出一个应用,再输出一个服务,我们调度一下,跑一下,感觉很唯美。为什么?两个程序员看看,什么都不需要。因为这样在有的垂直领域很常见的。当然这样的问题在成长的时候就会发现有问题。

传统框架模式下,它会造成应用的爆炸式增长,都不知道哪个是对的。十年,你想这样的都不敢下线,因为有的是依赖的。流量的瓶颈也出来。总说性能不好,因为你的调用量太长了,而且你自己也不敢动,所以性能不好。所以同程进行了改造,在2015年全部做了微服务化。

当然微服务化我们也是做了,像传统服务器快速转入,把一些非微服务的东西做出来。什么样的服务称之为微服务?我觉得一直是没有一个很好的标准。以至于说微服务还在长大。为什么这样说呢?我一个现实例子,我们开始做第一款微服务改造的时候比较激进,所以选择的交易类的平台。当然做的很成功上线了,但是问题发生在什么时候呢?发生在三个月之后。在我们下单服务里出现了一个新的下单服务。然后按照传统程序员的命名方式的话,它被称之为“新下单服务”。又过一个月出一个新下单服务,它称之为“新新下单服务”?于是架构师找他们,说为什么出这样的名字,为什么不能合并?因为明天就要上线,我不想污染老的。半年会出现新新新下单服务,还有的在后面加一个括号,勿用,已放弃。这样的服务出现后我们发现微服务不断长大,它的问题爆发出来了,就是大量的微服务在出现,它的运维不会改。原来的运维方式很简单,是对它的判断依据比较大,当微服务之后出现了大量的微服务,它的部署和运维非常乱。

这个时候我们反复说的一件事情是什么呢?就是重构。为什么程序员这么喜欢重构?为什么呢?因为写代码的时候总会被打断,总会有人让你提前上线。这个我们称之为程序员自己挖了一个坑。自己留着的时候说没关系,我三个月有空档期我重构一下。但是反过来看,这些真的被重构了吗?我在想我们为什么不能放弃掉这个代码,重新做一个,老的不要了。但是这是一个不现实的问题,因为工程太大了。以至于说重构代价是非常非常大。每次重构,当然老板最不喜欢听的就是,怎么又要重构,不是上个月才重构过吗?我的需求放这儿还没有做,怎么又要重构呢?所以有一段时间我们说禁止再提重构的项目。大家换个名字,叫优化。

其实我们发现制度永远解决不了问题,所以一定要用技术解决。怎么解决呢?其实反想回去说,我们为什么做Serverless,其实一个出发点很简单,我们去看我们的运维同学,运维同学也喜欢多的工具,典型的工具是什么,一个脚本。运维会写很多脚本,你见过运维脚本,运维同学说你稍等,这个脚本我重构一下。运维同学会说算了,我重写一下吧。脚本的Bug很少,为什么呢?进行脚本的单位非常明确。一个文件名字就决定了它到底做什么。这个服务总是会爆,研发没有找到为什么?所以运维同学写了一个脚本,说12点重启。所以这个脚本名字叫重启一下。简单吧,它不需要重构了。

为什么我们的业务逻辑不能这样去做呢?一个代码脚本能不能就是一个微服务?到今天经常会说Serverless,我们叫函数即服务。但是我叫做脚本即服务,为什么呢?当我们只有一个函数了,可想而知这两个都解决了。干脆叫脚本更通俗易懂。脚本用完就走,下次再写一个也行。当然这里会存在一个问题,说什么样的东西能放进去?今天是Serverless在国内用的还没有那么普遍的一个问题,就是微服务器也是这样的,什么样的服务是微服务?如果把整个都堆在上面,估计是不行的。因为你整个系统的架构或者交易类的,你这样下去会发现整个系统架构是一块一块的,一点一点的,互相之间找一个东西串起来非常贵。所以其实不是所有的东西都适合放。什么东西适合放?就是即走即用的适合放进去。这样的应用到底有多少呢?其实互联网里大量这样的应用,为什么,它本身是一个适应的发散性的,高并发的行业。当然对于像交易类的,比如像供应链型的,它是非常非常稳定的,重业务型的,切到Serverless不合适。

我的一个问题,是程序员做一个新的升级的时候,一定给自己填个坑。所以我们在Serverless填了微服务的坑

说了这么多总结下来,就是业务发展太快了,我们要更快速的代码变现速度提升性能。还有快速之中,环境问题,部署问题,应用弹性设计问题太困扰程序员,所以我们要抽象出来,不要让他们再有耦合的情况出现。于是我们把它设置成这样,对于同程来说我们比较好的是把应用做容器化,同时又做了中间件,这些中间件如何被使用?当然对中间件的使用其实也是我们在Serverless的一个重点改革的点,为什么?在我们三千多程序员开发的时候出现一个问题,因为有些中间件是我们做的,每天有多少程序员不会用,这样的问题会问到中间件开发者。往往中间件是五六个人做的,面对三千个程序员,这个用起来好像有一个BUG。所以我们当时还成立了一个客服团队。这个团队做了一个月也疯了,因为每天问的问题都是同一个问题,一天要说两百遍。

我们说把一个容器做我们的实例部署,当我们需要弹性的时候拉起不就行了吗?但是这样的开销太大。你部署只用一点点东西,还拉起容器,你不可能跟上。所以我们开始去做。当然做的时候我们对容器改造,一开始我们选择Node Js和LUA。还有一个好处是它们是动态的,我们对它们的改造是容易的,我们做了隔离,然后再到容器里跑。刚才说的微服务变成脚本化后不是更多吗?为了这个事情我们做了一个编排的事情,这个比微服务编排复杂的多,这个时候编排是非常非常重要的。但是这时候又说,折算好几个脚本串在一起,有什么问题吗?其实中间调用一定是网络的IP方式,各种方式都会有,这种方式调的时候一定会对性能降低的。所以在做函数的时候,我们选择的是比较轻的应用做,重的话性能会降低很多。

这个是我们当时开始时候做的情况,做完后上线第一版我们做了一个测试,我们用最小单元部署4台物理服务器,最多可支持1万个应用。当然这也是我们的一个原型,我们跑原型的时候,红色的是比较重了实例或者到了临界值需要扩容的。绿色是准备扩容的,白色的正常的。当然我们现在所有应用都会有这样的监控。

刚才说,怎么去使用中间件,这个也是Serverless要解决的一个问题,于是我们做了一个SDK,来统一的用。为什么这样做呢?刚才说了问问题的太多了,以至于你无法服务过来,或者是使用标准也不统一。这个也不是最重要的,刚才我们说了我们想做微服务。无服务器的时候,举个例子来讲,我需要从滴滴捞出一批数据的时候怎么做?首先说滴滴服务器在哪儿?这个东西本身不够服务器,你还是在服务器编程,所以程序员不想知道滴滴在哪儿,也不知道知道它是多少个主,多少个从,我就想知道它的实例名叫什么。这样做有什么好处呢,真正开发的时候很多同学不再需要考虑布在哪里。同时Cash会这样做,Q也会这样做。这样就是不停的在脚本里说需要什么东西,而这个东西永远是一个对象。

做这件事情还有扩容的问题,这个也非常麻烦,所以我们把整个的负载层全部重新做一个动态的扩容。为什么?让它进行不降低性能的情况下让它快速拉起。同时我们也担心这个上线后挂掉,防止挂就要有一个好的容灾。

我们也是对后面,刚才说的每种东西都做了SDK。我们更方便的是什么,其实有的事会做调试。调试时会发现日志没法输出,在平台上一样,任何一个情况的日志都可以进行输出,调用的时候是从Cash到IDE。其实有可能一个脚本还调真正的微服务,很正常,刚才的一个情况,Serverless服务的名字就能找到了。而控制中心,负载均衡这些都不需要了。

当时做这套系统给到我们开发人员的时候第一眼是很开心,说可以写代码了。第二个是根本没有人用。我说都说这么多,它的开发,它的使用,打破了我原来编程的方式。原来编程是从本地调试,我还用这套东西的时候变成零散的东西,很难用。于是我们做了一套统一IDE的WEB。这个是在任何情况下都是在微服务器上,任何产品都可以写,在家可以写,只要有点时间都可以写这个代码。它的好处是什么呢?原来配置的环境灭掉,真的没有环境了。在这里写的不需要考虑环境在哪里,我只需要知道我的代码。像这个脚本上线,有一个访问环境,是地区可见,还是什么。这样的好处在开发过程中就没有环境的限制。而且根据上线的可用范围,就是调后面的数据源,环境,自动的给他做了一个选择。

当然这套东西,Serverless调试,我们也给它做了一个简单的Debug。其实说的这么好,程序员也很反感,说你把我废了,我离开你这里我不会写代码了。但是确实碰到这样的问题,因为程序员只能用你的。所以我们做了一个本地的环境,定制做了一些事情。但是使用下来,真正最好用的,到现在用的也是比较多的,因为程序员除了自己技术爱好外,还有变现压力。因为这个东西做完真的下午就可以上线了。

这个还是蛮丰富的,我们做了代码版本冲突,代码上线。为了说能够让所有程序员把这个脚本,自己有什么脚本发布出去,我们做了一个脚本商店,在每个部门,每个流程,已经有这些可以直接调。

另外一个很重要的事情,真正做到说让我们脚本具有高并发我们怎么办,去配置它,我们会有一个属性界面。像很多网页需要反扒,还有需要高并发,都可以根据需要使用。甚至我们还做了一个秒杀,我们做的一个简易秒杀,就是排队系统。这个时候可以想像这样的事情的话,其实如果一个秒杀需求的话,如果真的给一个程序员去做的话,他可能需要一周考虑并发的问题,但是他真需要把这个写完,可能一个下午就写完,写完后就可以用了。这个秒杀不是大的,像昨天晚上七八点钟没有房间了,来个秒杀,这都是一瞬间的。昨天写的还有用吗?其实已经没有用了,就下线,不要了,以后再说吧。所以通过这套系统可以快速灵活的上线。

每个人进去后还有自己的目录,包括请求日志。基本上每个程序员从入口进去看到的日志和自己的服务。

做下来之后我们自己总结下来我们省了什么东西?我们省了项目初始化的成本。我们在一个项目的时候,从申请各种东西,模块,框架选择,这些东西全部被省略掉了。接下来的是数据源,我要找日志,要去选择数据源等等,这些东西大概降低了80%。还有开发,因为其实在开发过程中,调试和找内部依赖是很麻烦的事情,这个事情在这当中解决掉了。当然代码还是要写的,所以它并没有说80%,我们算下来是40%提高效率。当然对于运维部署来说,从程序员角度来讲,运维参与度非常低;但是从运维角度来讲参与度非常高的,因为后台全部依赖于他们的能力,所以从运维角度来说是90%的提升,但是对运维同学来讲从运维状态变成维护状态。

我们看一下两年来我们把什么样的东西放到我们这个平台上去跑的呢?第一个,我们所有的网页,活动推广,部分变化量大的后台,实时变化的都放进去了。为什么说第一个选择的网页呢?特别是一些活动推广页变化非常快的。为什么呢?因为对市场把握度不是很大,所以也需要实验,这个实验就需要快速的变现能力,这个就可以通过Serverless实现。你的部署,你的脚本废弃或者重写这个代码成本是非常低的,有这两个前提下你变现速度会快很多。

Serverless在同程的情况:轻型服务。一些逻辑简单的业务服务,一些逻辑变化快的业务服务,大量的临时的小服务。

再下来是价格实时的计算。为什么说这个东西也是我们的主要场景呢?其实OTA,我们做票务,酒店这类的,OTA价格的计算跟普通传统电商价格计算不一样的。大家说这个有什么不一样呢?一张机票一千块钱就是一千块钱。其实并不是这样。当我们在XX电商平台上买一个帽子的时候,上午是20,我相信下午还是20。但是如果购买一张机票或者酒店,每次查询,价格一定不同。为什么不同?因为全地球在共享一个酒店的房间,或者同一架飞机同一个座位,它随时会被别的平台售出去,因为资源就这么多。而且这时候价格也是随着一定的人数,或者乘坐的时间不同而发生变化。什么意思呢?像昨天上订北京的酒店,这一定是涨价的,因为量大。这个不是OTA在涨价,而是酒店自己在涨价。这个时候OTA保证你订到房间,所以它要做实时价格计算。这里有大量的价格逻辑。机票也一样,像国际机票,这个问题像北京飞到巴黎飞机到底多少价?有多种中转。各种中转就带来价格不一样。这样做静态或者做Cash定价一定不准。保证准就是实时预测。实时预测带来的问题就是有大量的价格脚本去跑。这套就是放在我们系统做,这个跟我们扩充有关,因为这个做完就可以废弃掉。还有像扩容,每天有一百亿访问量和一亿访问量完全不一样,而且这个弹性空间会非常大。

当然我们也还在做,像我们最近刚加入更多的语言,WEB化IDE能力提升,更多的技能被配置化,将自动测试系统并入。我今天的分享就到这里,谢谢大家。

Q&A

Q:我想知道咱们的数据是同程上的,还是同程上的服务器?

A:同程因为应用比较多,量比较大,同程是混合云的状态。同程有自由的机房,比较大。在腾讯云上也有大量的虚拟机。它的用处不同。比如很多情况下流量扩容依赖于腾讯云扩容,很多供应链系统,或者计算有自有的机房,基本是混合云的状态。

Q:不希望敏感信息能在外面访问到,您觉得放到云存储上还是自己的存储器上?

A:个比较有挑战性,我觉得放在哪儿并不是最重要的问题。就好比把钱放银行更安全,还是放自己家更安全。不同的人给你不同的答案。比如你加是大庄园,保安上千个,我估计放家里更安全。如果你家只有你一个人,而且是租的房子,可能放银行更安全。当然银行也有不安全的情况,因为银行是最大的打劫目标。回到你刚才的问题,与其考虑数据放哪里安全,不如说做好整体应用的安全性。刚才说到安全的问题,其实今天的安全问题,我们搜索一下,到底有多少安全问题是因为底层引起的,其实不多,更多的是应用的漏洞和应用的不注意,导致的应用接口的漏洞比较多,产生了数据不安全。与其去选择底层,不如把上层真正的应用安全做好;同时我们有一个安全的团队会去最外层到最里层做应用的安全,主机的安全,漏洞的检测和搜集都有安全团队做。这样的情况,就是安全由安全来做。

Q:我们曾经碰到这样的问题,如果我们用云存储我们信息的话,对保险行业来说,他们每个月都会有保监会的人核对这些信息,需要把这个信息跟他们核对。但是每次核对的时候会出现一些数据有问题,数据有问题我们希望直接核对数据库,然后直接进行修改。如果放在云上的话,可能我们没法儿直接访问他的数据库,出了问题的话没法儿修改。如果用腾讯修改的话这个更麻烦了。

A:你想做数据安全,数据一定不能随意修改。其实也是在同程内部,我们私有云下,应用的程序员也没有办法接触到数据库。其实这个做我们有很多优化去做的,其实有大量修正的系统做。系统的好处就是保证数据的安全。因为其实确实对每个工程师去直接操作数据库会有很多问题发生。

Q:我们现在在做很多传统的项目开发,但是会遇到关系型数据库。像随着相互的扩展,相互的模型之间会越来越多关联性,无服务化这块怎么样去把传统的项目,把里面的复杂的逻辑进行简单的拆分,并且使每个运算之间,每个服务之间,使它们的状态彻底的没有关联,无状态化。我觉得从传统项目开发,到无服务中间肯定有一个很长的鸿沟,就像刚才您提到的,SQL语句到我们的服务距离有多远。所以我觉得中间这个过程是我们最欠缺的。所以不知道这个过程该怎么解决?

A:一个传统的应用,特别是老的应用,就是一个大数据库对一个应用的情况如何把它变成Serverless的情况,其实这有两条路走:第一,跟Serverless完全没有关系,需要在应用解耦。这是另外一个话题,可能跟微服务相关,就是如何把老的应用解耦服务化。如果直接对着这个拆,因为你刚才说到Serverless对微服务来说并不是一个有一没有二的情况,它俩应该是并行的状态,应用于不同场景的状态。这个对老的场景来说是把数据解耦。这个事情做完后,里面挑拨以后出适合Serverless的,比如变化比较大的,应用比较轻的东西,这样把Serverless转掉,这对以后的压力是非常非常低的。所以先把业务模型的解耦和应用的服务化的解耦。不可能今天是一个传统型的架构模式,第二天就拆,这个肯定是不现实的,因为不可能停下来做这件事情。我们原来拆分过程一定是挑出我们比较麻烦的部分,和比较好改的部分来去把它选准,做版本迭代,比如一个月后会怎么样,三个月后会怎么样,把它一部分迁移掉,保证业务还在并发的状态下走。

Q:最终能不能达到一种理想的状态,就是把整个项目后台全部无服务化掉?

A:这件事情,其实我们现在做了两年也没有做到,为什么呢?因为我刚才在PPT里讲的,我认为目前的无服务化并不是能够完全的把所有的系统都设到这里。因为它毕竟还是在做一个特定场景下的事情。所以还是有大量的微服务存在的,去完成它的业务逻辑。为什么呢?刚才整个PPT通篇讲下来,就是讲并发快的,轻的可以往这里迁。但是重的,不稳定性的用微服务器可能是合适的。

本文PPT附件如下。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档