SOA,面向服务架构,是构建中大型项目的必备架构,以下分析SOA的主要构成要素,并对比腾讯内部使用的SOA框架和阿里巴巴内部使用的SOA框架的优劣。
1. 协议
协议的序列化性能要好,这个是肯定的,一般用google的protobuf之类的协议,有一个java protobuf协议和google的完全兼容同时不需要预先处理。
协议非常重要,它负载着接口传递的信息,从扩展性和兼容性考虑都非常重要。
最重要的则是协议的版本控制:
1)协议有版本字段version,可以是自增也可以是时间戳,协议的每个字段会注解(或注释)是哪个版本起加入的。如果协议里面有List等更深层嵌套,如果嵌套结构不被复用,那么就可以用个自增版本控制;如果嵌入的结构是复用的,那就推荐使用时间戳作为版本。
2)对于低版本客户端请求高版本服务器,高版本服务器应该兼容低版本协议,根据协议版本由服务器端来决定怎样处理业务逻辑。对于返回数据,到底是高服务器端适配低版本返回数据,还是低版本客户端忽略高版本数据字段,这个都可以考虑。对于Java自带的序列化,它对上对下都是兼容的,但没有手工指定版本那样好依靠版本做不同的业务逻辑处理。
3)对于高版本客户端请求低版本服务器,低版本服务器会忽略高版本协议中新的数据,并处理业务逻辑返回低版本的数据,高版本客户端应该有能力处理低版本的返回数据。
腾讯的AppServer/AppPlatform是由协议的版本来服务版本的,服务器本身没有版本号控制。服务器都是同一批升级的,没有办法控制调用某个服务时,只请求指定版本的机器。如果要实现这样的效果,就修改下服务名称,例如叫XXXv2。
阿里的HSF,协议是依靠Java(Hessian)做到上下都兼容,但是没有版本区分,只能看某个字段能不能拿到值来判断,比较弱。但是服务器机器是有版本和分组的,调用方需要指定服务器版本和分组。但在实际开发过程中,线上一直是1.0.0和HSF分组,依靠版本/分组做升级的情况就没有使用过,aone2的发布也不支持部分机器1.0.0部分机器2.0.0这样的情况,所以HSF的协议版本控制是不太完善的,没有办法监控客户端和服务端的协议版本统计。当然好处就是灵活,直接Java的序列化类,不需要维护一个单独的版本。
从协议版本的设计上,腾讯胜。但从实战的角度上,打平。
2. 注册中心与环境: 本地、开发、测试、预发、线上等
在实际项目开发过程中,需要搭建各种环境,至少线下线上是免不了的,测试和预发一般也是要的。SOA也需要提供这样的环境隔离。目前知道的腾讯和阿里的两种做法:
1)腾讯是靠服务器上的agent来控制环境。例如有一个SOA服务,名称叫queryService,这个名称是全局唯一的,在开发环境,它对应的服务器是A:3888端口,在测试环境,它对应的服务器是B:3999端口,线上对应的是C:3888和D:3888两台机器。这些信息,可以在配置中心网页配置,配置中心以环境为单位分开配置。配置完之后,配置中心会推送给每台机器的agent程序。而对于每台机器上的应用,假如它要调SOA服务queryService,应用会拿本机的agent数据,知道要调用的SOA服务的机器端口,然后直接访问。对于本地开发,可以直接指定机器的ip端口直接调用。
所以,agent维护了整个系统的环境,这个事情由运维负责。相同的代码和配置,放到A机器上它就访问了开发的服务,放到B机器上它就访问了测试的服务。这个减少了很多服务的配置项。不足是目前环境的ip需要手工配置到配置中心,实际上可以搞成自动注册的,本地环境的自动注册功能则可以关掉。
2)阿里的HSF也有各种环境,但是环境里面还是需要指定HSF服务的版本号和分组(一般配置在Spring bean,这也使得每次用hsf服务都要配置,比较麻烦)。例如开发和测试环境在HSF是同一个大环境,所以应用如果依赖N个应用的服务,就需要为服务各配置N项开发和N项测试的版本。预发、线上等同理。服务提供者本身也要配置HSF版本和分组,但是会自动注册到配置中心。例如SOA服务com.xx.IQueryService,服务提供者开发环境和测试环境各部署一台服务器,开发服务器配置版本是1.0.0.daily,测试服务器配置版本是1.0.0.test,这两台服务器起来之后,会把自己的ip地址和端口自动发送给配置中心。而服务使用者的应用,如果是开发环境,那需要配置1.0.0.daily,如果是测试环境,则配置1.0.0.test,需要手工配置。
这个自动注册的功能的便捷性,实际上已经被各种配置破坏完了。还好阿里是以应用为单位的,应用包含web和SOA服务层,应用上所有的服务一般都一个版本,所以像一达通后台BOSS这种规模的应用,一般十几个版本号就可以维护。
其实更好的做法是一个环境自己用一个注册中心,这样就免去每个环境要用不同的版本的问题。
总结一下注册中心和环境应该具备的特性:
1)区分环境并感知环境的能力 2)自动负载均衡,自动下线失效机器,自动恢复上线机器 3)服务自动注册、手动注册
从设计上看,腾讯的agent是非常规整的模型。
- agent应该有能力识别当前的环境,例如dev/test/pre/idc
- agent可以扩展为拿配置项(阿里Diamond)、mysql地址密码(保护线上mysql密码)等
- agent的维护有自己的门户和权限控制。如果是大公司使用时,agent可以增加命名空间来隔离不同部门。
- agent支持windows、linux各种操作系统。
从注册中心设计和环境使用方面,腾讯胜。
3. 监控、治理
SOA框架会采集所有调用的耗时,调用量(分每台机器和总体),这些数据就可以做实时监控也可以做历史趋势比较。
监控是简单的特性,而SOA治理才是大头。SOA应该有能力检测到从页面或定时任务开始的一个SOA调用,它后续一路下去的所有SOA调用(包括调用的服务名次、次数和时间)。通过这些数据,就可以分析调用量有没有出现循环、会不会太长、有没有良好的层次关系。这些指标可以作为系统复杂度的指导。
阿里的EagleEye设计,就是通过调用链来采集数据。从页面或定时任务开始(实际上只要没有traceId,就创建一个)就创建一个随机的128位字母的traceId,此后的SOA调用或notify消息传递,都会带上这个信息。根据这个traceId,就可以找到一条调用的全过程。比扁平化的SOA监控更强大的是,这个可以对一个功能的全链路进行统计。例如用户点击提交订单的按钮后,后台会调用一系列SOA、请求一系列SQL、发送一系列信息等,哪个比较慢,一目了然。
实际上,页面框架Webx、SOA框架HSF、消息notify、数据库TDDL这4个点都有EagleEye的采集,所以系统的全链路基本清晰了。
强弱依赖统计、瓶颈分析:
调用来源分析:
还有个RpcId记录了调用的顺序,因为时间每台机器不一样,是不准的。
Google有这类产品的设计:http://research.google.com/pubs/pub36356.html twitter的:http://engineering.twitter.com/2012/06/distributed-systems-tracing-with-zipkin.html
在SOA治理方面,阿里胜。
4. 管理调用方、自我保护
服务提供应该有能力保护自己。SOA的服务提供方,应该可以提供密钥和调用者标识符给调用者,并设置该调用者的调用频率,如果超过调用频率,就禁止为其提供服务并报警。
另外一个是来自Google的理念,对于导致多次服务超时的异常参数,应该有屏蔽的能力。也称熔断。
在这方面,目前阿里的HSF好像没有涉及,连安全性都没有。这方面,腾讯胜。