基基 spring 基基基 基基基基基基基统 基基基 基基 :
基于 spring 构建的淘宝虚拟业务系统
淘宝网:虚明
自我介绍花名:虚明 姓名:周剑2007-2009 雅虎 平台技术 C/C++/PHP
2009-2012 淘宝 新业务 JAVA
高性能并发业务系统设计与开发
• 淘宝虚拟业务及架构介绍• 基于 spring 构建业务层
– 应用– 数据库– 中间件
• 自定义 spring 特性• 问题
主要内容
3
淘宝网虚拟业务线
4
• 交易量大,日订单数千万级• 无实体商品,较少依赖库存• 业务逻辑复杂,大量事务操作• 对第三方接口依赖严重• 基于淘宝统一技术架构• 异步操作,特殊的支付方式
虚拟业务特点
5
虚拟交易基本架构
6
应用配置管理
7
• Property 文件 + 集中式管理 (scm.taobao.net)• 静态配置:
– Maven + antx.properties– <context:property-placeholder/>
• 动态配置: ConfigServer/Diamond
IoC
8
• @Autowired• @Repository• @Component• @Service• <context:annotation-config/>• <context:component-scan
base-package="com.taobao.lottery.persistence"/>
AOP
9
• Monitor : annotation + aop– 调用第三方接口监控– 定时程序运行监控– 性能优化
• 异步化 / 并发控制 / 缓存– @Aysnc
– @Once
• Tprofiler– Instrument
– 字节码注入
MVC
10
• 淘宝 WebX– SpringExt :基于 Spring ,提供扩展组件的能力,是整个框架的基础,基于 spring schema-based
extensions 。– Webx Framework :基于 Servlet API ,提供基础的服务。– Webx Turbine :基于 Webx Framework ,实现具体的网页功能,例如: Action 处理、表单处理、
模板渲染等。
• Webx Framework – RequestContext
– 对 request/response 的处理– Session/Lazy-commit/Rewrite– Basic/buffered/set-locale
– Pipeline– 串联管道,不改变 request/response– 独立– 流程定制化
http://openwebx.org
MVC
11
• WebX Turbine Style– 基于 pipeline– 页面驱动– 约定胜于配置
• Screen :页面主体• Layout :页面布局• Control :嵌入的页面片段• Action : Java 代码
Database
12
• TDDL(Tabao Distributed Data Layer)– 容灾切换– 负载均衡– 自动扩容– 数据复制
– 行复制: WAL, 跨库– DbSync :异步复制
– 精卫:数据分发– 愚公:数据迁移和扩容
TDDL example
13
TDDL example
14
TDDL example
15
<bean id="commissionTableRule" init-method="init“ class="com.taobao.tddl.common.config.beans.TableRule"> <property name="dbIndexes" value="lottery_dpc,lottery_ssq,lottery_gpc"/> <property name="dbRuleArray" > <list> <value>
def type_id = #lottery_type_id#;if(type_id == 1) return 1else if(type_id == 25) return 2 else return 0
</value> </list> </property>
<property name="tbRuleArray"> <list>
<value> def type_id = #lottery_type_id#; if(type_id == 1) return #lottery_type_id# *100 + #issue_id# %1000 %64 else if(type_id == 25) return #lottery_type_id# *100 + #issue_id# %1000 %32 else return #lottery_type_id# *100 + #issue_id# %1000 %1</value>
</list></property><property name="tbSuffix" value="resetForEachDB:[_0000-_2600]" />
</bean>
事务
16
• 常规的 spring 声明式 + 编程式事务• TDDL 不支持事务• 通过消息中间件达到最终一致
– Notify
– Metamorphosis
Timetask
17
• @Cron(“*/1 * * * * ?”)
• Spring Quartz Scheduler– 管理界面– 集群切换– 单实例– 监控
• 案例:– TTM– AtEye– TTControl
Cache
18
• Ibatis CacheModel
• @Cacheable/@CacheEvict– 不适用的场景举例
• 缓存敏感场景• 强一致性场景下缓存异常• 对既有代码修改程度
• Tair :强依赖• 优化:
– 远程 Tair + 本地 Cacheable – 异步化
RPC
19
• HSF– TCP/IP | WebService– 同步、异步、 OneWay 、 Callback 、可靠异步– 序列化: JAVA/Hessian/ProtocolBuffers– OSGi– ConfigServer
• Spring JMX– 系统状态监控– 开关控制– 配置修改
Dynamic Language
20
• <lang:groovy />• Groovy Shell
– 运行时状态检查– 提高开发效率– 部分实验性 web 开发– 特殊情况下的数据处理
• 危险
第三方通信
21
• 通信方式: HTTP/SOAP• 昂贵的调用:异步• Spring TaskExecutor
– 共享线程池 vs 隔离线程池• Callback
– 加密、校验– 专线
• 监控– 系统– 业务
LazyBatis
22
public interface DummyDAO { @Select List<DummyDO> selectLimit20(); }
<?xml version="1.0" encoding="GBK"?> <sqlMap namespace="dummyDAO"> <select id="selectLimit20" resultClass="com.taobao.geek.test.lazybatis.DummyDO" > <![CDATA[ SELECT id,a_b_c,ab,test_money,status FROM lazybatis LIMIT 20 ]]> </select> <sqlMap>
<bean id="sqlMapClient" class="com.taobao.geek.lazybatis.LazybatisSqlMapClientFactoryBean"> <property name="dataSource" ref="testDataSource" /> <property name="mappingLocations" value="classpath:com/taobao/geek/test/lazybatis/sqlmap/*-sqlmap.xml" /> </bean> <bean id="dummyDAO" class="com.taobao.geek.lazybatis.LazyDAOFactoryBean" > <property name="className" value="com.taobao.geek.test.lazybatis.DummyDAO" /> </bean>
LazyBatis
23
Reflection + ASM bytecode inject
@Select@Insert@Update@Delete@PropNameList<xxxDO> getOrderList(@PropName(“user_id”)String id, PropName(“type”)int type)
Map<String,Object> m = new HashMap<String,Object> (); m.put(“user_id”, id); m.put(“type”, type);sqlMapClient.executeQuery(“namespace.getOrderList”, m);
@DAO(BeanDefinitionScanner)<yacs:scan scanner="com.taobao.geek.lazybatis.LazyDAOScannerConfigurer"> <key="base-package" value="com.taobao.geek.test.lazybatis" /> </yacs:scan>
LazyBatis
24
Reflection + ASM bytecode inject
@Select@Insert@Update@Delete@PropNameList<xxxDO> getOrderList(@PropName(“user_id”)String id, PropName(“type”)int type)
Map<String,Object> m = new HashMap<String,Object> (); m.put(“user_id”, id); m.put(“type”, type);sqlMapClient.executeQuery(“namespace.getOrderList”, m);
@DAO(BeanDefinitionScanner)<yacs:scan scanner="com.taobao.geek.lazybatis.LazyDAOScannerConfigurer"> <key="base-package" value="com.taobao.geek.test.lazybatis" /> </yacs:scan>
• 基于 TaobaoDiamond
– 降级开关– 灰度发布开关– 在线配置更新
@Switchable
25
Thank You!Q & A
诚聘英才