由于时间比较仓促,写的有些凌乱,有兴趣的同学可以更多的线下沟通。
回顾
淘宝的开放算上 2010 年已经走了快三个年头了,从服务提供者的角色转变为开放平台的角色,从 30 多个服务到 300 多个服务,从 2000w 的日调用量到 8 亿的日调用量,在技术和产品上都在经历着不断地蜕变。
开放平台产品的几个关键词:快,稳,安全,易用,透明。这些关键词构成了开放平台第一阶段的产品需求。
快:速度是服务调用的第一感知。在一次服务调用过程中,最多拆分的步骤:DNS 解析,TCP 连接的建立,数据传输(包括上下行),数据解析,平台安全校验,后台业务处理。因此如何优化这些步骤就成为提速的关键,优化有几种思路:
- 直接优化处理过程,减少时间消耗。
- 间接优化处理过程,提高处理过程中资源利用率,增加并发处理效率。
- 合并处理过程,减少重复处理。
- 处理逻辑外移,合理利用外部计算能力。
这里分别举几个例子来说明一下上述的概念:
- 在年初时一直采用 apache+jboss 的结构,但是发现在数据解析部分用容器处理会比较慢,其实是因为外部 http 请求数据传输质量有好有坏,当大数据量请求服务到来时,容器需要多次 IO 很多小数据包后才能够继续后面的业务处理,本身过多的 IO 处理直接增加了数据解析阶段的时间,也增加了整体业务处理时间。通过采用 nginx+jetty NIO 的模式,利用 nginx 的数据堆积转发可以大大降低后端容器在数据解析上的消耗时间(nginx 消耗也不大),另一方面 Jetty 的 NIO 通过修改仿 BIO 的模式也能够提高数据处理性能。
- 对于开放平台来说,由于存在大量的上行大数据量服务的存在,因此上行带宽其实也是比较宝贵的资源,同时也是整体业务处理快慢的一种约束,如何提高带宽的利用率,通过 Lazy 的方式解析请求字节流,按需读取数据,遇到业务判断不满足立刻结束请求返回错误,可以大大的降低对无用的大数据量请求的解析成本,从而提高整体的带宽利用率,提高整体的请求处理能力。
- 批量服务处理模式及 QL 的实现能够极大地提高多次无关性请求或者串联请求的处理效率,其实在 Facebook,twitter 都有现成的样板,但到了淘宝这种电子商务复杂度高,安全性高的体系中,有很多细节需要去关注。
- 平台各种访问控制策略计算都外移到外部分析集群中,虽然牺牲了部分的即时性,但是减少了平台计算成本(特别是全局性的计算需要依赖外部 kv 系统来统一控制),同时策略可灵活运行期配置,业务相关多变的内容被移出,防止经常发布导致的不稳定性。另外对于后端服务结果的统一格式化操作也交由各个业务提供者自己处理(以类库方式依赖平台提供的格式化工具包,但计算却分散在各个应用提供者集群而不是开放平台集群)。
稳:稳定是服务最基本的需求。如何做到稳定主要从几个不稳定的角度去看:外部应用的不稳定,平台依赖的不稳定,后端服务提供者的不稳定。外部应用常常会由于自己的异常发布或者爬虫等其他原因突然大量的调用平台,此时将会给平台和后端服务造成很大的威胁。因此需要对应用有访问频率控制,访问频率控制粒度最小到服务级别,控制目标可以是应用级别,用户 & 应用级别,应用 &IP 级别,甚至是应用 &Agent 级别。对于平台依赖的不稳定,当前通过平台整体的管道化作降级实现,整体流程被拆分成很多管道,多个管道之间业务关联不强,当其中一个管道依赖资源出现问题时,可以在主流程中“卸载”该管道,同时告警,当异常处理完毕后,可以再将管道人为增加上去。(当然如果这个管道是关键不可缺的情况,就无法简单降级处理)。后端服务提供者的能力及稳定性都参差不齐,但是由于同样接入在开放平台上,加之传统容器阻塞模式的处理业务请求,使得后端某一个服务处理能力出现问题时,将会消耗大量的开放平台前端容器线程,最终影响其他后端正常的请求无法进入被处理。因此,采用 Jetty 的类似于 Servlet3 的异步化请求处理方式,能够将容器线程池与业务线程池分离,同时业务线程池可以根据业务规则和后端服务处理能力来选择是否处理请求,还是排队等候处理或者直接丢弃请求,最终实现服务隔离和服务的差异化处理。
安全:是开放双刃剑最危险的一面。安全主要有三方面的考虑:用户信息安全,淘宝数据安全,ISV 身份安全。用户信息安全在很多开放平台上都采用 OAuth 的方式,而淘宝开放平台则简化了 OAuth 的模式,便于开发者简单开发。但还是有些问题需要进一步去优化和解决,例如手机端和桌面端的授权无法走 OAuth 的回调返回结果的模式,因此现在采用应用轮询的方式和手工拷贝授权码的解决方案,这需要有更好的优化措施(OAuth2 的解决方案中有些可以尝试)。另一方面,淘宝电子商务体系的差异性,使得授权可能涉及到两方甚至多方(例如交易服务,团购服务),因此用户授权策略也不能简单的使用 OAuth 的方式来解决。淘宝数据安全性主要体现在对于服务调用的监控,通过服务调用分析来判断服务调用的合法性(应用授权情况及服务调用情况比对等),同时通过不同的 ISV 体系来限制服务的访问范围和访问频率,间接地控制数据非法获取的问题。ISV 身份安全主要是考虑高级别的 ISV 的访问权限很高,APPKey 和 Secretcode 被盗用的风险很大,因此通过 IP 控制和动态密钥的方式来保证高级别应用的身份安全性。
易用:与人方便自己方便。在开放平台团队中易用也是大家最关注的一个产品特性。如何降低服务升级对于外部开发者的影响,如何降低后端服务发布的接入成本,成为开放平台工具化的最初需求驱动。开放平台升级一次服务,影响之广,周期之长是有目共睹的(twitter 的 auth 升级,foursquare 服务升级),降低服务升级影响最有效的方式就是提供被广泛使用的各个语言版本的 SDK,同时数据类服务的 SDK 是最细粒度的 SDK,后续的流程化组合化的 SDK 将会根据领域的不同而不同,更加便于开发者开发,一方面简化了开发者的开发成本,另一方面升级过程往往可以在发布新的 SDK 中顺利得到过度。(顺带对于应用端到服务端真实的业务请求处理时间和成功率统计也依赖于 SDK)。另一方面,从开放平台初期的手把手接入开放平台,手工编写服务定义和返回结果格式文件,手动编写 SDK 和发布 wiki 文档,到现在填写表单,自动创建定义文件和结果格式文件,自动生成多版本 SDK 和上线 wiki 文档,都为服务提供者减轻了发布服务的负担,同时也减少由于人为失误导致的问题。其实回过头来看,不管改善了那一方的体验,最终节省了开放平台的支持资源,也提高了服务质量。而 SDK 的垂直化封装,改善用户体验将会是明年的一个重点,因为淘宝的服务和普通的 SNS 及地理等服务不同,有很强的业务性和规则性,因此单独的数据类服务对于开发者来说门槛太高,需要根据不同领域的应用有不同封装和指导。(商城,大卖家,买家营销,江湖,淘客,行业分析等等)
透明:就像一切归于尘土一样,上述一切归于系统透明。不论是开放平台还是其他什么系统,最终要的是系统数据透明化。快的优化基于优化前对于系统瓶颈的查找和优化后系统处理能力的对比,这些需要数据来说明。稳定的基础需要海量的数据加上业务规则做决策,在问题出现前防范于未然,在问题出现后最小代价快速解决问题。安全的深度挖掘需要对数据作关联分析,最终找到不合理性的服务调用。易用也需要根据数据作指导,确定易用不是平台设计人员的易用,而是开发者在乎的易用。
在开放平台体系中,针对数据量在 T 级以下,分析业务规则复杂多变,即时性要求高的前提下,采用松散的分布式处理协作结构,抽象统计分析模型作为分析引擎,满足上述的业务需求,具体的结构如下:
具体的文档还在编写中,一些集成测试还需要做的更好一些,后续考虑开放出来更多人可以参与贡献(有太多可以优化的地方),代码可以直接在 google code( http://code.google.com/p/cheep-worker/ )上 check out 下来:
http://cheep-worker.googlecode.com/svn/trunk/ cheep-worker-read-only
技术展望
外部通知服务(类似于 twitter 的 streaming 服务)的推广,推送数据变更通知到应用,将采用 comet streaming 模式来即时推送,节省短链接带来的性能损耗(网络连接消耗和对方服务能力不确定性,改主动多次连接为被动长连接),同时简化消息推送到达率策略。
今年更多的网站开始开放服务,因此会考虑在平台间为了合作而作部分的兼容,例如在授权模式上除了使用简化的 OAuth 以外,也兼容 OAuth1 和 OAuth2(这部分将可能成为数据类服务的标准,也就是安全级别较高的服务将会迁移到这种模式下)。
QL 和 Batch api 的模式将会考虑从内部走向外部,QL 和 Batch api 的在内部垂直化开发过程中得到业务的反馈不断完善后,考虑将这部分机制堆外,提高开发者开发效率,同时也为将来可能的外部服务简单的 Mashup 提供技术上的可行。
Hosting 服务的提供及应用行为监控。应用的用户增长不确定性需要有弹性的后端提供服务能力扩展支持,因此 Hosting 将会成为应用发展的很重要一环,同时在 hosting 上增加应用发布控制和应用数据访问控制,可以更好的保证数据安全性和应用稳定性的监控。
如何将业务开放不再独立于后台系统,实现开放更为直接,将成为很多从已有系统开放的网站较大的挑战,前期出于快速响应的需求,采用独立开放部门去封装开放服务的方式,而到了初中期由于业务变更的复杂性,更希望能够由服务提供者直接开放服务,内部服务调用体系和外部服务调用体系统一(facebook 这样的网站内部服务体系和外部保持一致化,极大降低了服务内外两套系统的磨合成本)。
在海量请求和大数据量上下行请求的场景下(特别是在网络数据传输不好的情况下或者在手机终端的应用),如何保持快速,稳定将会成为底层系统的最大挑战,一则优化现有 Web 容器(Jetty NIO 和事件驱动模型),二则重新采用新的实现方式简化 Web 容器实现(API 请求对于 Http 协议中的很多规范实现要求不是很高)。
关于作者
岑文初(花名:放翁),2006 年加入阿里巴巴,2007 年初开始负责阿里软件平台架构设计,2007 年底开始进入开放平台领域,2009 年 8 月加入淘宝开放平台,现在是淘宝开放平台主架构师. 个人没有什么特别擅长的,只是能够在学习情况下较快进入角色。
感谢张龙对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。
评论