洪泽国,2007 年硕士毕业于中科大,先后在 Oracle、腾讯等公司就职,主要关注在线服务的高可用、高性能和易扩展。
大家好,我来自滴滴出行,今天其他老师分享的内容覆盖内容比较大,我分享的话题相对小一些,讲一个具体的应用。我们在 passport 设计时候踩过很多坑,后来在可用性方面做了很多优化实践,今天给大家分享其中的 7 个小优化。
我的题目就指出了 Passport 设计的一切都是为了高可用。Passport 主要有两个功能,第一登录;第二,授权或者鉴权,每一个请求过来,我这边都会做一个校验,校验量是比较大的。再考虑到滴滴的场景,我们在座的大家可能是乘客端,但是我们还有司机端、代驾端等,司机端每一秒都会发请求过来,请求方就会到 Passport 请求一下,所以是一个典型的高并发高可用场景。
业务场景
先简单介绍一下业务场景,我来自滴滴平台部门,平台是一个业务支撑部门,支付、账号、消息等功能都会在我们平台里。今天主要给大家介绍账号子系统,我们设计 Passport,有很多优化的规则,比如大系统做小,做服务拆分,力度拆得非常小,目的是为了高可用。
Passport 的应用场景,工作之一就是登录。登录成功之后返回 ticket,之后每一个业务请求都会把 ticket 传过来,如果合法,则返回给调用方用户真实的信息。
Passport 简单理解,它是三元组。登录的凭证是手机号码、密码、UID,可以简单理解为 Passport 只维护了三元组。
在我们开始设计一个账户,用户其他资料一开始揉在一起设计,后来我们发现这个问题非常麻烦,可用性会存在一些瓶颈,因此把大系统做小,把 Passport 单独拆出来,只包括这三元组。
一切为了高可用
我的第二个分享内容是一切为了高可用,我们做了什么?我们会从编程语言上,最早用 PHP 写的现在用 golang。最小闭环,柔性降级,异地多活,访问控制,接口拆分等。
1. 选用什么编程语言
我们编程语言是 PHP,现在账号系统用 golang,提升非常明显。有一个例子,一个乘客的用户服务,在线上布了 45 个实例,司机端或者乘客端都有心跳,每一个端有点像 ddos 攻击一样,不停的轮询,司机要不停上报他的状态或者坐标等等信息,访问量非常大。一开始用 45 台 PHP,后面用 golang 重写了一下,只用 6 台机解决了这个问题。
2. 最小闭环(大系统小做)
刚才也说到用户的资料包括 count、UID、密码、名字等信息,我们把它做了一个拆分。拆分有什么作用?和我之前在腾讯的经历有关系。之前在腾讯的时候,老大一直说 QQ 永远不能存在不登录情况下,即时登录进去都是空白都能接受。这个的确有很大的差异,当用户不能登录,他以为他的账户被盗了,这会形成很大的惶恐,但登录之后什么都没有,他知道肯定是系统挂了,不会有恐慌的心理。因此对于帐号系统来说,需要永远要保证它是能登录的。
最小闭环刚才说了,passport 只包括三个最主要的属性。我们乘客端刚刚上了密码登录,司机端都是用密码登录。在 QQ 时登录量是非常大的,校验量非常大需要做很多细致的工作。腾讯包括微信的架构都有一条经典的经验,大系统小做,当你把系统做小之后,高可用性最容易做,每一个功能比如用户存储的信息越多,这个事情就越难一些。
(小编注:在上一篇大促系统全流量压测及稳定性保证——京东交易架构分享文章中,京东商城的杨超将这种设计方法叫异构)
3. 柔性及可降级之 Ticket 设计
很多公司都需要降级,在柔性降级里面举几个例子跟大家分享。
在移动客户端应用,登录时间通常是很长的。比如大家用微信,不需要经常登录,但是服务端需要有踢出用户的能力。踢出是什么概念?登录后,可以用另外一个手机登录就把前一个踢出,这样应用就会更安全。就因为可踢出,实现就会稍微复杂一点。
我加入滴滴之前已经存在一个 Passport,最早是 PHP 语言写的。在滴滴合并快的,我也了解快的那边的情况,大家在设计 ticket 时比较简单和类似,一登录,生成一个 ticket,业务来请求提供认证,认证服务和 ticket 进行对比,对的就通过,不对就让用户踢出。
我相信很多帐号系统都是这样实现,但这里面隐藏比较严重的问题。ticket 是无语义的,里面没有任何信息。其次如果 ticket 服务不稳定校验就会不通过,所有的业务请求第一步就是来校验,它对系统的要求,第一是低延时,你得足够稳定足够快。第二,不能有故障,一旦你个服务失败,用户端就会请求失败,就叫不到车。
在滴滴,不管基础组件比如 MySQL 都需要考虑失败的情况,和滴滴快速成长有一定的关系,所有业务系统,在实现时就需要充分考虑系统的不可靠性。
于是我们对 ticket 重新进行设计,下图是目前的设计。第一我们 ticket 增加了语义,里面是有内容进行了加密。这里面提一点,加解密尽量不要用 RSA 非对称算法,那会是一个灾难。ticket 里面包含一些信息,包括手机号、UID、密码。