构建一个稳定,高效,容错,易维护,可监控的服务调用框架,以便推进公司业务系统朝着SOA架构演进,从而使总体业务架构更加清晰,可控和可度量,最终实现业务产品的健康,敏捷发展。java
目前汇付各业务系统各自独立,存在重复业务逻辑,经过数据库共享数据等问题。项目粗放式生长,缺少清晰的脉络和独立的职责。
不少相同数据在不一样的系统中存在冗余,给变动和维护带来很大的难度,也没有系统负责维护这些数据,基本靠人工重复维护的方式。
系统职责的不独立,必然带来人员职责的划分不清,致使生产率的低下和产品演进速度的缓慢。 linux
构建这样一套框架须要从底层通讯,编码/解码,序列化,异步处理,线程池等几个大的方面入手,具体可行性分析以下:
底层通讯:依赖于第三方包netty
编码/解码:自定义二进制编码协议
序列化:依赖于第三方协议,如hessian, protobuf, thrift,以实际状况权衡使用
异步处理:基于Future Pattern实现
线程池:使用JDK concurrent包自带的线程池,如有效率问题,后期再作优化数据库
稳定:不会由于系统请求并发量的陡增而出现性能大幅度降低的状况,而且持续可用
高效:性能及吞吐量应比开源的rpc框架高,如hessian, xfire等
容错:应具有底层网络通讯容错及部分只读业务容错的能力
负载均衡:经过客户端负载均衡的方式,摒弃额外的软/硬负载设备,具有更好的性能和可靠性
简单监控:V1.0.0版本中仅实现简单的监控统计功能(log/jmx/telnet方式)
配置服务提供者:V1.0.0版本中仅支持客户端手工配置服务提供者地址和权重的方式,后续版本改由注册中心提供json
项目编号 | 251 |
---|---|
项目名称 | Pegasus |
项目经理 | 刘健 |
项目简述 | Pegasus为分布式服务框架,推动公司业务架构朝着SOA方向发展 |
名称 | 版本 | 连接 |
---|---|---|
无网络
FP | 624.00 |
---|---|
生产率基线 | 3.01 |
工做量估算 | 207.3089701 |
# | 模块 | 子模块 | 功能 | EI | EO | EQ | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
S | M | C | S | M | C | S | M | C | ||||
1 | 通讯客户端 | service stub | 2 | 2 | ||||||||
2 | invoke filter chain | 5 | 5 | |||||||||
3 | client route | 4 | 4 | |||||||||
4 | client load balance | 4 | 4 | |||||||||
5 | heart beat task | 3 | 3 | |||||||||
6 | reconnect task | 2 | 2 | |||||||||
7 | communicate protocol | 5 | 5 | |||||||||
8 | 通讯服务端 | service registry | 4 | 4 | ||||||||
9 | communicate protocol | 5 | 5 | |||||||||
10 | service processor | 2 | 2 | |||||||||
11 | process filter chain | 4 | 4 | |||||||||
12 | 客户端服务端集成 | 3 | 3 | |||||||||
13 | http通讯支持 | design & coding | 5 | 5 |
影响因子列表 | 级别(0-5) | 缘由 |
---|---|---|
数据通讯 | 5 | |
分布式数据处理 | 5 | |
性能 | 5 | |
大业务量配置 | 5 | |
复杂处理 | 5 | |
可复用性 | 5 | |
支持变动 | 5 | |
级别总数 | 35 |
4.3.1 人力资源session
角色 | 人数 | 姓名 | 备注 |
---|---|---|---|
项目经理 | 1 | 刘健 | |
架构工程师 | 1 | 刘健 | 初期1人,后续加入其余开发工程师 |
开发工程师 | 3 | 刘健,刘成业,待定 | |
测试工程师 | 2 | 待定 | 须要与测试部门协调 |
4.3.2 基础设施架构
硬件环境 | 线下3台虚拟机用于测试 |
---|---|
软件环境 | linux系统(centos), 局域网千兆网络 |
4.3.3 工具和技术并发
用途 | 工具名称 | 版本 | 生产厂商 |
---|---|---|---|
开发 | Eclipse/IDEA | 任意 | / |
测试 | EasyMock | 任意 | / |
设计 | Microsoft Visio | 2007 | Microsoft |
压测 | JMeter | 任意 | Apache |
构建 | Maven | 2 | Apache |
持续集成 | Jenkins | 任意 | / |
4.4.1 项目排期
任务 | 负责人员 | 参与人员 | 开始日期 | 完成日期 | 估算工时 | 实际完成日期 | 备注 |
---|---|---|---|---|---|---|---|
需求分析 | 刘健 | 各业务项目责任人 | 2013-05-22 | 2013-05-28 | 12h | 2013-05-28 | |
FP估算 | 刘健 | 项目开发成员 | 2013-05-30 | 2013-05-30 | 4h | 2013-05-30 | |
概要设计 | 刘健 | 项目开发成员 | 2013-06-03 | 2013-06-03 | 8h | todo | |
源代码编写 | 刘健 | 项目开发成员 | 2013-06-04 | 2013-08-12 | 500h | todo | |
单元测试及报告 | 刘成业 | 项目开发成员 | 2013-06-04 | 2013-08-12 | 100h | todo | |
源代码审核 | 刘健 | 项目开发成员 | 2013-06-04 | 2013-08-12 | 50h | todo | |
开发模拟上线 | 刘健 | 项目开发成员 | 2013-08-15 | 2013-08-16 | 2d | todo | |
质量测试 | QA | QA,项目开发 | 2013-08-14 | 2013-08-19 | 4d | todo | |
性能测试 | QA | QA,项目开发 | 2013-08-20 | 2013-08-21 | 2d | todo | |
QA模拟上线 | QA | QA,项目开发 | 2013-08-22 | 2013-08-27 | 4d | todo | |
生产上线(含准备) | 刘健 | 小白鼠项目人员,项目开发,QA | 2013-08-22 | 2013-08-29 | 6d | todo | |
生产测试 | 刘健 | 小白鼠项目人员,项目开发,QA | 2013-08-29 | 2013-08-30 | 2d | todo |
4.4.2 项目文档
4.4.3 上线计划
培训需求 | 参加人员 | 培训师 | 计划日期 |
---|---|---|---|
项目目标及整体概要设计 | 开发人员,QA | 刘健 | 2013.06.05 ~ 06.07中一天 |
How to test pegasus | 开发人员,QA | 待定 | 待定 |
# | 会议名称 | 频率/日期 | 参与人员 |
---|---|---|---|
1 | 项目每日例会 | daily | 项目成员,QA |
2 | 项目周会 | weekly | 项目成员,上级管理,QA |
3 |
风险类型 | 风险描述 | 风险规避措施 | 负责人 |
---|---|---|---|
项目管理 | 规避项目进度,人力方面的风险 | 每日例会上跟进 | 刘健 |
开发 | 模块设计,实现,接口契约方面的风险 | 每日实时跟进 | 刘成业 |
测试 | 测试进度,问题反馈,及时跟进修复等风险 | 每日例会跟进 | 待定 |
其余 | 线下测试环境可靠性及持续集成等支撑平台状态跟进 | 每日实时跟进 | 刘成业 |
名称 | 版本 | 连接 |
---|---|---|
Netty Doc | 3.2.1-Final | http://netty.io/3.6/guide |
Hessian Doc | 3.1.5 | http://hessian.caucho.com/doc/ |
RPC | Remote Procedure Call |
---|---|
Sync | 同步调用,客户端调用远程服务接口时,业务线程Block,直到服务返回结果 |
Callback | 回调调用,客户端调用远程服务接口时,业务线程不Block,而且无结果返回,结果会在后续返回,并触发注册的Callback接口执行 |
Future | 异步调用,客户端调用远程服务接口时,业务线程不Block,无结果返回,但能够获取到此次调用的句柄Future实例,后续能够经过 |
Oneway | 单向调用,客户端调用远程服务接口时,业务线程不Block,无结果返回,而且服务端无响应消息写回,客户端不关心服务端是否正 |
注:简要绘制,实际编码时进行丰富和调整
序列化 | 优势 | 缺点 |
---|---|---|
XML | 描述能力强,跨语言 | 占用空间大,marshall/unmarshall效率极低 |
JSON | 描述能力强,跨语言,比XML节省空间 | 占用空间较大,jackson引擎尚不熟悉 |
Java | 对Java的各种对象支持完善,使用方便 | 速度慢,占空间 |
Hessian | 字节码方式,跨语言,性能较快,空间较小 | 各种语言的实现支持不够 |
Protobuf | 跨语言,占用空间极小,性能极快 | 须要编写中间代码并生成最终代码,每次更新代码很是麻烦 |
Thrift | 性能,空间俱佳,功能较protobuf完善 | 须要中间代码生成最终代码,跟新代码很是麻烦 |
综合以上各种序列化方式的优缺点,从性能和使用性方便综合权衡,选择较中庸的Hessian序列化方式做为Pegasus的默认序列化方式。后续考虑将其余方式做为可选的实现,使用者自由进行选择。
跨语言方面经过提供http + json的方式实现。
暂不考虑,做为v2版本实现,由于目前不须要考虑注册/订阅和监控模块。
目前包含两类实现:随机路由(random),依据服务提供者负载进行均衡路由(load-autoaware)
Random:
Load Autoaware:
将异常与正常返回区别对待,正常返回使用object::response.return,异常使用throwable::response.error返回,以便服务端异常序列化后传递到客户端,客户端没有该异常的完整结构信息时,可以反序列化为throwable对象,而非没法反序列化或反序列化为map。
序列化或反序列化过程当中出现异常,须要模拟为error response返回给调用端,以便调用端知晓具体的异常信息。
业务异常须要enrich上相关的远程调用信息,如请求派发的地址,请求类型,请求sequence,请求超时时间等,以便快速定位异常。
+----------------+----------------------+-------------------+----------------------+------------------------+----------------------+------------------+ | magic (2 bytes)| serialize (1 byte) | sequence(8 bytes) | message type(1 byte) | expand region(8 bytes) | body length(4 bytes) | message body | +----------------+----------------------+-------------------+----------------------+------------------------+----------------------+------------------+
magic: magic number
serialize: 标记使用的是什么序列化协议(目前支持hessian, java)
sequence: 该次请求的序列号
message type: 消息类型(业务调用/心跳/业务异常/框架异常)
expand region: 预留扩展区
body length: body区的长度
message body: 消息body区
使用统一的threadfactory和threadpool,以便对线程规范命名,统一监控定位,以及后续的统一优化。
须要区分为session context与transient context,区别以下:
session context:在每次rpc调用时,从client端一直传递到server端,并从server端返回到client端。
transient context: 仅在client端或server端传递,如client端的invoke chain,server端的process chain上传递,不会传递到相对的另外一端。
使用tracker context(session context)进行分布式调用的调用信息跟踪。
因为对目前公司各业务项目的性能控制状况不了解,而且支付交易系统对数据完整性有极高的要求,因此谨慎起见,将框架的默认RPC超时时间设置为15s,若超过15s仍不返回,则视做超时,且现阶段不对超时作传递计算的优化处理。
开发排期较紧,开发完毕后,再一次性补充设计文档内容!!!
1. 同步应答接口功能,http协议,测试该接口的各类调用方法以及成功率
2. 异步应答接口功能,binary协议,4个接口为:sync,oneway,future,callback
3. 注册中心控台功能测试,包含:权重配比功能,动态增减server服务,配置生效的实时性以及心跳带来的容错处理机制
4. 性能测试,主要包含稳定性测试和容量测试的评估,模拟异常状况下系统运行状况以及容错效率的提高
测试任务 | 人员 | 方法或工具 |
---|---|---|
测试计划以及测试策略 | 张林 | 文档描述 |
功能测试 | 张林、龚建林 | 调用接口,工具ecplise junit |
性能测试 | 张林、马莉莉 | 执行工具jmeter或loadrunner |
其余任务 |
|
里程碑任务 | 工做量 | 计划开始日期 | 计划结束日期 | 人员安排 |
---|---|---|---|---|
制订测试计划 | 1d | 2013-7-29 | 2013-7-29 | 张林 |
设计测试用例 | 3d | 2013-7-30 | 2013-8-1 | 张林、龚建林 |
执行功能测试 | 3d | 2013-8-2 | 2013-8-6 | 张林、马莉莉、龚建林 |
执行性能测试 | 3d | 2013-8-7 | 2013-8-9 | 张林、马莉莉 |
实际应用测试 | 3d | 2013-8-12 | 2013-8-14 | 功能测试组(钱管家) |
功能:
注册中心控台功能测试,该功能有2个
性能:
这次性能测试,主要测试该系统在正常运行时,其稳定性和容错性,在正常运行状况下,该系统的内存消耗以及对于服务器的cpu消耗状况,在发生错误或者异常的状况下,该系统是否可以无错误的继续运行,从而构建一个稳定,高效,容错,易维护,可监控的服务调用框架。
接口:
本次测试的接口有5个,分别以下:
测试方法:
本次测试,将通讯中间件基础服务提供的jar包,以应用的形式,部署在本地,提供接口供客户端访问及调用。
1. 根据不一样的接口,采起不一样的调用方式,模拟各类类型如String,int,long等的调用,检验接口返回是否正确。
2. 根据不一样的接口,模拟报异常的状况传送给客户端及服务端,检验服务端或者客户端对于异常处理的状况是否知足需求。
注册中心权重配比功能测试:
Case 1
测试目标 |
检验server权重分为0表示服务中止工做 |
测试方法 |
将2台机器的权重配比更改,如:server1权重改成0,server2改成1 |
完成标准 |
当server1改成0,server2改成1以后,server1中止工做,检查系统运行状态或者观察日志去判断 |
Case 2
测试目标 |
权重分配后,其是否实时生效 |
测试方法 |
将server服务权重同时设置为0或者同时设置为1-10不等,检验系统是否可以实时暂停服务或者运行服务 |
完成标准 |
同时设置为0时,系统暂停工做,客户端响应报错 同时开启权重1-10不等,检验系统是否可以当即工做 |
Case 3
测试目标 |
检测权重分配比例是否生效 |
测试方法 |
初始状态:server权重都为5 将server的权重配置,一个改成1,另一个改成9,检验其发送的请求是否按照1比9的比例,流向server服务 |
完成标准 |
经过观察cpu的消耗来模糊的观察压力分布,经过日志的计数,来观察精细的压力分布 |
Case 4
测试目标 |
心跳异常测试 |
测试方法 |
大量的发送请求至server端,忽然将某台server权重设置为0 |
完成标准 |
|
Case 5
测试目标 |
找不一样配置的机器做为server端,检验配比效果是否与预期一致 |
测试方法 |
找配置比例差距较大的server服务(2C和4C和32C) |
完成标准 |
完成各类配比检测(在机器不出现任何异常的状况下),按照实际配比进行请求流向分配,经过日志能够查询 |
注册中心增减server功能测试
Case 1
测试目标 |
增长一台server服务后,该服务可以正常接受请求 |
测试方法 |
手动配置一台新的server服务,查看后台日志是否接收到请求 |
完成标准 |
添加完server服务,该应用可以正常运行起到分流减压做用 |
Case 2
测试目标 |
减小一台server服务,系统不受影响,可以正常运行 |
测试方法 |
将权重设置为0再删除该应用 |
完成标准 |
可以成功删除该server并经过日志查看该应用再也不接受到请求 |
Case 3
测试目标 |
增长或删除server服务过程当中,不对其余server形成任何功能上的影响 |
测试方法 |
增长或者server服务 |
完成标准 |
在增长或减小过程当中,其余server正常运行,无任何异常状况出现 |
性能测试:
测试目标 |
检验系统的所能承受的最大请求数(TPS) |
测试方法 |
模拟用户发送请求,观察测试指标 |
完成标准 |
容量测试,主要测出最大值,结果待定(需评审) |