本文作者系逸创云客服产品CTO — 刘铭
随着互联网飞速发展,软件市场需求日益增长,用户对软件核心价值观转变,必然扩大软件服务化趋势,从而催生SaaS商业模式,也就是Software as a Service。在过去的一些年里,SaaS的优势也越来越突显,服务开通即用,零维护,按需付费,随时随地,安全等,顺应企业市场发展需求。虽然国内saas服务也在不断发展,国内各类SaaS企业服务应用也取得了很大成就,其中很典型的就是CRM和项目管理系统。有了成功先例,继而就有了的后继创业者,因此竞争日趋激烈,市场也逐渐细化。国外SaaS客服市场早已风生水起,而在SaaS客服领域的国内开拓者却凤毛麟角。面对着国内巨大的客服市场的需求缺口,为了顺应更多企业在互联网+时代在客户支持服务的连续需求,逸创云客服(KF5.com)很早就开始布局此块业务和服务。
作为SaaS客服在国内的实践者和领跑者,逸创云客服能将来自各个渠道的用户反馈,转化成一个个工单,让企业能够统一管理、跟踪和响应,用户也能随时通过各种渠道得知处理进度。这些渠道包括邮件、电话语音、即时IM、移动SDK、网页表单、反馈咨询、微信、微博等等,用户与企业的客服人员之间能够很方便的进行沟通。
逸创云客服从2012年最初上线到现在,历经近三年风雨。其中有很多令人振奋的创新,也有很多令人沮丧的困难。在解决困难的过程中,很多时候也获益于互联网开放的知识共享与开源工具。下面我将分享一下逸创云客服的发展历程所遇到的砍和解决方式。
技术选型
在2011年9月真正开始做逸创云客服这个产品时只有两位工程师,我是其中一位。架构采用的是典型的LAMP(Linux+Apache+PHP+MySQL),所有资源都在一台物理服务器上。团队采用PHP作为开发语言,因为PHP简单强大,适合做动态网站,能快速上手,而且社区活跃。开发框架在选型后也采用了基于MVC模式的Yii框架,面向对象思想,开发效率高,代码结构清晰,非常符合创业公司快速敏捷的风格。而且其强大的组件,丰富的类库,优秀的扩展性,也在之后的开发进程中得到了很好的体现。
锁定需求
技术选型确定下来后,接着就是锁定需求了。最初的挑战是对业务逻辑和工单流程的设计,针对这个问题,团队借鉴国外一些具有类似功能的产品,基于自身对产品的思考,对公共业务逻辑进行总结抽象,构建出了一个基本的工单系统模型。之后在此基础上,开发与工单相关具有复杂逻辑的商业规则。从产品创建之初,就奠定了逸创云客服团队之后的开发风格:基于需求,快速搭建出一个具备核心且扩展性良好的功能原型,随即对其进行快速迭代。在确定了初版原型和核心功能后,逸创云客服的初版就在2012年上线了,同时也获得了小众市场客户的青睐。
贴近市场
在产品的推广中,我们发现市场用户对于云客服的理解还停留在在线交谈形式,为了更好的迎合市场需求,并结合云客服自身的工单特性,团队用了近一个月时间开发出了基于工单的在线交谈,交谈记录保存成工单或者是工单回复,便于追踪和跟进。采用的核心技术是openfire、xmpp、strophe.js。
在产品体验上,最初的产品形式是动态的PHP网页,客服人员和普通用户的视图是同一个界面层,只是根据权限不同,渲染不同的导航与内容。这也为客服人员带来了一些疑惑,感觉操作起来不够清晰,于是团队又快速的将用户端和客服端分离,普通用户看到的页面称为用户端,客服人员管理工单和用户的页面称为客服端。解决了这个问题,也为我们带来了很大的好处,因为企业开通后,一看到这两种页面就能很容易理解其操作方式,不会有什么迷惑,这也省去了我们不少的时间和精力。
产品体验上的里程碑
接下来,我们迎来了产品体验层次上的一次质的飞跃。传统的网页在每次表单提交,或者是重要交互后,都要对页面进行刷新,从服务器重新获取资源。每次刷新时的等待都是在挑战使用者的耐性,过多的请求又会增大服务的压力。客服端作为核心处理端,需要加载的内容是很多的,而一次次的刷新等待也是在浪费客服人员们的宝贵青春。秉着客户体验至上的原则,我们开始了Web App的研发。最初的难题是选择一个适合的前端MVC框架,在对Angular.js和Ember.js进行对比后,我们选择了Ember.js,因为它无需编写大量的样板代码,会自动推导出许多配置,比如在定义一个路由资源的时候,可以自动判定路由的名称和控制器。甚至会在你没定义控制器的时候,自动为你的资源生成一个。同时它包含了一个优秀的路由和一个可选的数据层。和其他框架不同,它们的数据层非常小ember 有一个拿来即用的非常成熟的数据模块,只需要简单的配置,就可以和后台的PHP很好的集成。团队在考虑开发简约性的同时也考虑到了应用性能,而性能是 Ember.js 设计的主要目标。诸如 The Run Loop 这个概念,可以确保数据的变化只导致单个 DOM 更新,即使同一块数据进行了多次更新也是一样,还有计算属性的缓存, 还有可以在编译时或在服务端对 HandleBars 模板进行预编译的能力,都可以帮助你保证应用的负载,保证它跑得足够快。在基于以上优点的考虑,在开发中和后面应用上线后并实现了非常棒的效果。虽然当时教程和示例都很少,团队通过看英文文档和源码,很快把这个框架用出飞一样的感觉来了。经历了一个半月的研发,在2013年8月新版的PC客服端上线,提升80%-120%的操作速度,客服操作起来高效便捷,再也不用担心页面重新加载了。
在邮件和工单间搭一座桥
前端的架构改进暂告一段落,团队的重心放在了邮件渠道上。在此之前的邮件只是负责提醒,并不是真正的把邮件和工单结合起来。而我们这次要实现的是,可以把企业的客户发送指定逸创云客服邮箱的邮件自动转换为工单,并且可以将邮件回复转换为工单回复,让企业的客服人员在云客服内处理客户发送的邮件支持请求,同时,客服也可以通过邮件来回复客户,在工单里都会有记录保存。我们基于postfix搭建了邮件收发系统,通过对接收的邮件进行解析,转化成相应的工单,并且触发相应的邮件提醒给用户和客服人员。最开始采用了最原始的轮询方式,以pop3协议对邮件队列进行读取,这种方式的即时性很差,而且当有多个读取进程时,会存在明显卡顿等问题。于是我们将其优化,一接收到邮件,就将其转到服务器脚本进行处理,从系统收到邮件到转化为工单,时间间隔不会超过3秒。企业也可以使用自己的邮箱作为支持服务邮件地址,只需要配置好企业邮箱转发后,即可开始使用。之后又对国内和国外各种类型的邮件服务进行格式兼容,保证邮件内容和附件读取的准确性和高成功率,并且不断针对其服务进行完善优化。
以市场需求为方向
继邮件之后,我们又完善了APP应用,移动端web页面,微信渠道,微博渠道,每一个客户支持渠道都是为了满足企业在客户支持服务上的需求。
纵观众多优秀的web产品,都具备很好的实时性。实时性就是指跟浏览器端保持一个长连接,便于实时推送Feed和通知。逸创云客服产品对于实时性的要求还是比较高的。一个客服需要看到其他客服人员正在查看的工单,避免发生冲突。当多个客服进入同一个工单处理页面时,需要工单处理冲突提醒。当客服在处理工单时,工单有了变化,比如被普通用户回复了,需要告知此客服。我们也将通知功能与触发器结合起来,企业可以实现自定义场景的提醒规则。为了实现此功能,团队采用了异步特性的node.js、能建立稳定长连接的socket.io、拥有发布者和订阅者机制的redis、支持复杂sql查询的MySQL。这个推送服务我们为其命名为Pusher,Pusher占用资源较少,响应速度快,推送准确,也为电话语音和后面IM服务重构和重设计奠定了实践基础。
第三方集成
随着越来越多的企业把现有系统与云客服平台进行深度结合,除了在原型上线版本时提供的SSO单点登录方案后,提供一套机制完善的web API也是众望所归。为此逸创云客服团队基于产品本身和用户需求深入整理了RESTful API的规范与内涵,最终开发出了一套简单易用,可读性高的API服务,一切设计细节在接口调用里都有体现。
物理架构变迁史
从最初到现在,逸创云客服的架构经历了三次演变。
第一阶段(2012.6~2013.5):
采用一台高配置的物理机,最初是托管在成都电信机房,后来为了让网通用户也能快速访问,转到了上海双线机房。
第二阶段(2013.5~2014.9):
采用了云端IaaS服务,包括静态文件服务器,功能应用服务器,MySQL服务器,Email/Pusher服务器和IM服务器。
第三阶段(2014.9至今):
随着服务的访问量越来越大以及企业对服务稳定性服务连续性的苛刻要求,为了服务稳定性,我们对其进行负载均衡。首先是用两台Nginx服务器进行调度,采用Nginx+keepalived的方案,让keepalived来监控Nginx的状态,当一台Nginx停止服务的时候能够自动切换至另一台。随后又用两台Memcache服务器,分别把Session和文件缓存给独立出来,这样无论Nginx采用何种调度规则,都不会影响的后端的Web服务。接着把用户上传的文件,分离多台文件存储服务器,最后又对MySQL进行了主从和读写分离。这样再加上三台功能应用服务器,不计各种渠道的服务,总共15+台服务器。此外,团队还在对产品的安全方面,监控方面进行完善,希望以后可以给大家更多的分享。
结束语
这个世界唯一不变的就是变化。逸创云客服始终坚持以客户为中心,以市场为导向,追求极致,拥抱挑战,提供最优质的客户支持服务。 逸创云客服团队对于技术的态度始终如一,兼容并包,与时俱进,开拓创新。