[补充实习笔记] 项目流程与角色分工

项目角色

PDM Product Manager 产品经理(对商业计划负责)
PM Project Manager 项目经理(对开发负责)
VD Visual Designer 视觉设计
ID Interactive Designer 交互设计
DEV Developer 开发
TEST Test 测试(性能测试、安全测试、功能测试)
DBA Database Administrator 数据库管理员
SCM Software Configuration Management 软件配置管理
PE Production Engineer 应用运维工程师(线上环境)

项目流程

1、MRD  运营

2、用户调研

===========分割线========= 开发介入

3、PRD产品需求文档

4、PRD评审

5、交互

6、视觉

7、技术方案

8、TC评审     TestCase 开发写给测试看的,也是写给开发看的

9、测试用例评审 测试写的

10、开发

11、冒烟测试

12、详细用例测试

13、项目发布计划制定

14、项目效果数据整理

[补充实习笔记] JAVA服务端开发设计的一些指导原则

一,性能相关:
1,避免在循环内部new一个对象。
2,所有与IO相关的操作,都需要考虑性能问题,一般采取的措施是连接池,缓存,减少调用次数,合并请求。
3,每个业务都要分析整个请求链路,找到瓶颈,通过压测的方式确认问题及验证解决方案。
4,根据业务情况,使用异步化和最终一致性。
5,CPU,内存,网络IO,磁盘IO这些瓶颈,需要知道在合适的场景牺牲什么换取什么。通俗的讲是空间换时间,还是时间换空间。
不同业务场景下,要做合理的取舍。例如多线程并发查询后merge。这个就是利用CPU,内存换取速度。
6,善于借助集团内成熟通用的平台来解决性能问题。如TAIR分布式缓存,METAQ,NOTIFY消息队列,HSF,OPENSEARCH等等。
要知道什么场景适合用什么,每个产品的最佳实践是什么要清楚。
7,学会通过业务视角解决技术问题。例如:如果没有分库分表,支付宝的大量交易数据的并发性,可能永远无法解决。
适当的时候,需要根据用户ID去分库分表,分散数据库IO瓶颈。避免只从技术角度考虑问题,陷入死胡同。
8,使用新技术新协议时,一定要分析出最佳使用场景,不能盲目相信。搞懂原理,才能通过最佳实践发挥性能优势。
二,监控相关:
1,监控分为系统监控,应用监控,业务监控。
系统监控一般监控网络IO情况,磁盘IO,空间,CPU,内存等等。
应用监控一般监控JVM的内存,GC情况,日志中的异常情况,SQL,SPRING方法等的耗时情况。
业务监控一般监控一些业务指标,如PV,UV,交易的变化趋势等等具有业务含义的数据。
2,系统监控,应用监控统一接入alimonitor。业务监控暂时接入XFLUSH,这块还在研究。
3,做好容量规划,避免无法支持业务增长。监控好容量。
4,对于调用链路非常深的系统,做好链路监控,及时发现瓶颈。
三,安全相关:
1,不要为了维护方便,在代码里留后门。之前review代码发现有这些问题,上次阿里内外上有一个帖子也反馈了这个问题。
2,涉及到用户密码等,一定要散列哈希算法加密存储。
3,关键用户敏感数据(如:信用卡数据)不能存日志文件中,避免主机漏洞被拖拽。很多互联网公司就发生了这样的事情。
4,要考虑完整业务链路的安全,不仅仅是某一端的安全问题。
5,充分利用集团安全团队的产品及规范,避免产品出现安全漏洞,代码安全这块加强和安全同学一起REVIEW。
6,要注意开发环境和生产环境信息做隔离,避免因在开发环境中泄露导致生产环境安全问题。
7,不在外网分享带有业务规则及需要保密信息的内部文档。
四,规范相关:
1,幂等性:所有对外暴露的接口,需要做到幂等性。
2,隔离性:对同一个数据源的操作,建议由一个服务向外暴露,避免多个不同系统操作同一个数据源,特别是避免修改操作。
3,开源使用:使用第三方开源jar包时,一定要谨慎。搞懂原理,避免不成熟导致缺陷。
对开源的第三方包,一定要有源码。
4,线程安全:要时刻关注线程安全问题。每个业务都要考虑代码是否是线程安全的。
5,关于编程模型,不做强制要求,但是有一个原则就是,这块技术是主流的,外部容易招聘到相关人才,
技术体系是完善的,容易学习和发展定制。
6,关键代码及业务逻辑,一定要有注释。
7,每个系统的设计及需求,接口等,一定要有文档。方便沟通交流以及团队的传承交接。
8,不用存储过程去实现复杂的业务逻辑,原则见第2点。
9,JAVA的日志记录,格式要统一,存储路径和位置,以及磁盘满了之后日志转移的机制要完善。
10,设计REVIEW:系统设计一定要组织REVIEW,避免设计的不合理导致后续扩展性不好。
review的角度,考虑业务的扩展性及发展方向是一个重点。
11,重点业务的单元测试和接口测试用例一定要有且全面。
12,统一使用PE提供的运行环境和容器,特殊定制化容器场景一定要充分测试。
五,异常处理相关:
1,要区分好业务异常还是系统异常。为每种异常定义好处理方式。
2,避免抛出大量异常不处理。
3,异常为了方便系统间传输,一般需要约定errorCode。例如场景:可以根据错误编码,将异常翻译成多国语言。
4,跨进程调用,不要将整个异常堆栈传递过去。
六,设计模式相关:
1,模块之间避免循环依赖。
2,尽量使用接口解耦应用。
3,代码中使用分层设计的思想。
4,高内聚低耦合。

[补充实习笔记] TDDL入门

TDDL(Taobao Distributed Data Layer) 是平台架构&开放平台-分布式产品组提供的一套分布式数据访问引擎。

为什么需要TDDL?

 
核心的目标是为了解决以下三个问题:
一、数据访问路由
    将针对数据的读写请求发送到最合适的地方。
二、数据的多向非对称复制
    一次写入,多点读取
三、数据存储的自由扩展
    不再受限制于单台机器的容量瓶颈与速度瓶颈,平滑迁移。

TDDL流程图

d1031a5d-c5d7-47a1-9189-bbe631f54984
所有蓝色的部分(TDDL三层架构),都是实现了jdbc接口的具体实现,因此可以按照需要随意选用。之所以为此,原因很简单,因为每层都有损耗,不管是易用性还是性能,都会有,所以要看用户的选择,需要用什么就上什么,我们不干涉。具体的三层架构见下:

TDDL整体三层架构

28e919fd-871c-4c09-b307-76f1d8c580f3
TDDL主要部署在ibatis或者其他ORM框架之下,JDBC Driver之上,三层数据源每层都按JDBC规范实现, 所以可以将其当作与普通数据源实例化并且注入到各种ORM框架中使用。
TDDL架构分为了3层,最上层的TDataSource负责分库分表路由结果合并,持有多个GroupDS实例中间层TGroupDataSource 负责主备切换读写分离,即根据读写特性与权重,选择一个具体的DB Server进行操作,持有多个AtomDB实例;最下层AtomDataSource持有原子的数据源(剥离的JBOSS数据源)并且可以动态改IP ,连接信息等,能够动态响应数据源创建与销毁。包括IP、用户名、密码、最大最小连接池、连接参数,从Diamond上拉取并交给JBOSS DB。JBOSS DB完成数据库连接管理与池化操作。3层数据源都可以单独使用,应对不同的应用场景。
先来看一条SQL的具体执行流程。而后分别分析三层。

TDDL执行SQL过程

 62aa2073-84d0-415d-8b6d-e90a95806bc8
其中sql解析/ 规则计算/表名替换/选择GroupDs执行sql/合并处理多个结果集 5个步骤在Matrix层执行, 根据权重选AtomDs/具有重试策略地在AtomDs上执行SQL 2个步骤在Group层执行, 读写数控制、线程并发数控制/执行sql返回结果集 2个步骤在Atom层执行。
        为何要做SQL解析?
 
        在这一步,TDDL将SQL中分库分表的条件进行解析提取,包括order by, group by, limit m,n, join等信息、sum, max, min等聚合函数信息、distinct信息。(此外,TDDL行复制需要重新拼写SQL,带上sync_version字段。次要理由。)

TDDL初始化

913f828a-a1c9-4dc7-bb36-05dbafd67907
TDDL初始化主要包括规则信息的初始化和各层数据源拓扑结构的初始化,其中前者包括 规则中的分库分表字段、规则字符串的处理和库表对应关系初始化,后者包括Matrix层 的dsMap初始化,Group层每个GroupDs实例中多个(或单个)AtomDs的可用不用,权重关系 等初始化,Atom层根据本地配置或者持久配置中心的数据源信息初始化剥离的JBOSS数据源, 并且将自身实例和这些数据源一一对应映射起来。这一初始化的过程是从上到下的,也就是 说只有Matrix层配置的GroupDs才会初始化,只有这类GroupDs中配置的AtomDs才会初始化。

TDDL Matrix Data Source

Matrix DS 用于管理数据片sharding,核心功能是根据给定的参数从规则引擎中计算出目标库的路由信息,然后进行路由。
基本功能:
1) 数据的水平切分
 数据库的水平切分,从本质来说就是根据关键的key,将数据切分为多个小片。主要的切片方法是取模和按日期,还有些会将这两种方式综合起来使用。而TDDL的目标也就在于对这些情况进行更好的支持。因为mysql的表有数据量的限制,因此在切库的基础上,还要进行适度的切表,以保证数据库的硬盘的使用率。
2) 事务管理
 TDDL提供了最基本的事务管理功能,首要的目标是让业务现有的事务模型更加简化。
3) 数据库选择
 与事务管理结合,允许业务指定查询的具体目标,用于彻底的替换dbRoute.提供更简单的配置方式和配置模型。与事务管理结合后,可以提供更为清晰的事务判断和事务管理。
4) 规则的集中管理
 规则的集中管理有利于进行数据库的平滑扩展时的状态切换和统一管控。在进行平滑扩展时,分库分表信息必须持有两套不同的规则,在准备完成的时候一并进行切换。
5) 不同数据散列结构读写分离
主要针对以下场景的支持,假设有一张表,是auction_auctions ,在主库内是分布在两个oracle中的, 丛库则分布在16个mysql中,每个mysql有4个表。
那么在这种情况下的读写分离就是不同数据散列结构的读写分离了。TDDL对这种场景也可以予以支持。
TDDL Group Data Source
Group datasource 是构建于atom datasource之上的数据源,他的目标是管理多组数据完全相同的数据库。比如通过mysql或通过oracle进行数据复制后的主备数据库。目标是在rjdbc的基础上,对主备,备库可读的场景进行更好的支持。
基本功能:
1) 主备数据库动态相互容灾切换
支持进行主备的对调切换,状态对调后备库变为主库,主库变为备库,类似rjdbc的作用。
2) 相同数据片内读写分离
针对mysql replication机制进行的数据主备复制,可以直接使用group datasource来支持读写分离。读写分离支持权重设置,允许对不同库使用不同的权重。
3) 读重试
一台数据库挂掉后,如果是个fatal exception ,那么会进入读重试,以确保尽可能多的数据访问可以在正常数据库中访问。
4) 数据库挂掉后的线程保护,不会因为一个数据库挂掉导致所有线程卡死。
使用try – lock机制来进行线程保护,在第一次捕捉到fatal exception以后,只允许一个线程进入数据库进行数据访问,直到数据库可以正常的工作为止。
5) 流量控制,数据库保护

TDDL Atom Data Source

Atom Datasource 如其名,就是一个原子的datasource。从本质来说,就是一个对jboss的浅包装。允许业务通过非jndi的方式获取jboss的数据源,同时也可以协助dba进行统一的数据库管理。依托于diamond server进行数据配置的统一管理。从而实现一个数据库,唯一的对应一套ip+port+username+password+schema的目的。减少配置中的环节。让数据库使用更简便。
基本功能:
1) Dba管控
2) 定期密码变更
3) Jboss数据源管理的相关功能
功能介绍:
a) 线程数统计
线程统计的作用是,在线程进入数据库访问的getConnection()阶段,线程数自增1,在退出数据库访问的close()阶段,线程数自减1。使用这种方式统计真正与数据库交互的线程数。
这样如果数据库挂掉,那么会有更多线程等待已经挂掉数据库的连接,如果到达伐值(可在app规则中设置,默认关闭),那么会拒绝超出伐值后的线程访问数据库的请求。
b) Try-lock机制
如果数据库发生了fatal exception(也就是断连接,数据库硬盘满)等异常的时候,TDDL会抓取到这种异常。一旦发现这种异常,立刻对数据库访问进行保护,只允许单个线程访问数据库,其他线程访问则全部抛出错误。
使用这种方式可以比较有效的保护业务机器的处理能力。
c) 状态切换
DBA发现问题时,可以迅速反应,将数据库状态置为NA,那么所有访问都会直接抛出异常,从而保护业务服务器。
d) 执行次数统计
允许通过设置指定单位时间片内执行的修改类型的sql和查询类型的sql的个数。
Atom使用的参数全部在Diamond上,包括三部分:
1、global:数据库ip, port, dbname信息
2、app:appName和数据源连接池、连接参数、用户的映射
3、passwd:数据库用户名和密码的映射
(2、3可以有多个)

Diamond取数据过程

以IC最新的Mysql动态数据源为例:
因为做了分库分表,所以最上层是Matrix数据源(TDataSource),appName是IC_MYSQL
那么拼成Matrix的dataId:com.taobao.tddl.v1_IC_MYSQL_dbgroups
组名是DEFAULT_GROUP(后续所有dataId的组名都是DEFAULT_GROUP)
以dataId和组名通过http GET访问diamond:(以日常10.232.10.23为例)
http://10.232.10.23:8080/diamond-server/config.co?group=DEFAULT_GROUP&dataId=com.taobao.tddl.v1_IC_MYSQL_dbgroups
得到:
MYSQL_ICDB_00,MYSQL_ICDB_01,MYSQL_ICDB_02,MYSQL_ICDB_03,MYSQL_ICDB_04,MYSQL_ICDB_05,MYSQL_ICDB_06,MYSQL_ICDB_07,MYSQL_ICDB_08,MYSQL_ICDB_09,MYSQL_ICDB_10,MYSQL_ICDB_11,MYSQL_ICDB_12,MYSQL_ICDB_13,MYSQL_ICDB_14,MYSQL_ICDB_15
这个内容是appName为IC_MYSQL的Matrix的group列表(对应TGroupDataSource)
对group列表中的每个group,例如MYSQL_ICDB_00
拼成Group的dataId:com.taobao.tddl.jdbc.group_V2.4.1_MYSQL_ICDB_00 这个dataId 用来获取一个group内部的主备结构,读写权重配置
组名是DEFAULT_GROUP
以dataId和组名通过http GET访问diamond:(以日常10.232.10.23为例)
http://10.232.10.23:8080/diamond-server/config.co?group=DEFAULT_GROUP&dataId=com.taobao.tddl.jdbc.group_V2.4.1_MYSQL_ICDB_00
得到
MYSQL_67_ICDB0:r10w10p0,MYSQL_69_ICDB0:r0w0p0
这个内容是MYSQL_ICDB_00的具体主备结构配置;逗号分隔开每个库;每个库的冒号前面是Atom数据源(对应TAtomDataSource))的key,冒号后面是这个库对应的读写权重。
对每个Atom数据源的key,例如MYSQL_67_ICDB0
拼成Atom相关的2个dataId:
com.taobao.tddl.atom.global.MYSQL_67_ICDB0 这个用来获取数据库本身的信息
com.taobao.tddl.atom.app.IC_MYSQL.MYSQL_67_ICDB0 这个用来获取appName对物理库如何使用的信息(其中IC_MYSQL就是最开始Matrix数据源的appName)
http://10.232.10.23:8080/diamond-server/config.co?group=DEFAULT_GROUP&dataId=com.taobao.tddl.atom.global.MYSQL_67_ICDB0
得到:ip=10.232.31.67 port=3306 dbName=icdb0 dbType=mysql dbStatus=RW
http://10.232.10.23:8080/diamond-server/config.co?group=DEFAULT_GROUP&dataId=com.taobao.tddl.atom.app.IC_MYSQL.MYSQL_67_ICDB0
得到:userName=ic minPoolSize=10 maxPoolSize=20 idleTimeout=60 blockingTimeout=500 connectionProperties=connectTimeout=1000;characterEncoding=gbk;socketTimeout=1000
根据上面两个结果中的dbName和userName拼成数据库密码的dataId:
com.taobao.tddl.atom.passwd.icdb0.mysql.ic
http://10.232.10.23:8080/diamond-server/config.co?group=DEFAULT_GROUP&dataId=com.taobao.tddl.atom.passwd.icdb0.mysql.ic
encPasswd=6eaf1b*********a8
这个是加密后的密码
至此,数据库所有的配置信息获取完毕。
在异常流程下,目前主要通过两种方式来保证业务可以正常启动
1. 如果这个机器曾经启动过,那么如果diamond死掉,他会使用本地cache启动机器
2. 如果这个机器从来没有启动过,diamond死掉,那么可以让sa scp数据文件到本地机器中,启动服务

[补充实习笔记] HSF入门

HSF全称为High-Speed Service Framework,旨在为淘宝的应用提供一个分布式的服务框架,HSF从分布式应用层面以及统一的发布/调用方式层面为大家提供支持,从而可以很容易的开发分布式的应用以及提供或使用公用功能模块,而不用考虑分布式领域中的各种细节技术,例如远程通讯、性能损耗、调用的透明化、同步/异步调用方式的实现等等问题。

适用场景:
  • 将集中部署的应用转换为分布式应用
对于这种需求场景,HSF将提供帮助,基于HSF可以非常容易的将集中部署的应用转换为分布式应用,而不用去过多的考虑分布式应用需要掌握的技术,也不需要对现有应用进行过多的改动,这一切HSF都会提供支持。
  •  以统一的方式对外提供或使用外部的公用功能模块
对于这种需求场景,HSF将提供帮助,基于HSF所有分布式部署的功能模块都可以以一种简单而标准的方式进行通讯,而无需关注所使用的公用功能模块部署在什么地方以及怎么远程调用它等问题,可做到的效果就像是本地调用library的API一样。
  • 开发分布式应用
对于这种需求场景,HSF提供了分布式领域问题解决的支持,HSF屏蔽了分布式应用带来的一些问题,例如:如何与远程的功能通讯、异步/同步调用等问题,使用HSF,只需要简单配置就可以做到就像本地调用一样的效果。
总结来说就是,只要应用涉及到分布式,那么HSF就可以提供支持和帮助。
为何使用HSF?

07年时,淘宝是一个单一的应用Denali。随着业务的发展,暴露了两个问题:

1、业务功能累积,单一应用不堪重负
2、牵一发而动全身,代码难以维护
因此在07年下半年,将Denali进行了拆分。面临问题:拆分后系统跑在不同的虚拟机中,如何互相调用?因此开发了HSF。

HSF远程调用流程

bd9b2f21-4f27-439c-9cc8-1ae5a2b63343
基本调用流程:
1、连接服务器
2、把接口名,方法名,参数传给服务器
3、等待服务器返回结果即可

HSF框架结构

22ee41db-90ac-4304-8956-9f69319a5594

应用层:HSFSpringProviderBean/ HSFSpringConsumerBean
协议层:RPC协议(TCP/IP协议,Webservice协议,Google protocol buffers协议)/序列化协议(java,Hessian)
核心服务层:RPC服务/路由规则服务/地址服务/配置服务/notify消息服务/OSGI容器及jar依赖管理。
QOS(Quality of Service,服务质量):监控 日志(哈勃,logstat)
容器接入层:Tomcat,Jboss
b087af20-8f20-4dd3-99f7-536e40bb1042

[7.22实习笔记] 校招实习生百阿百技培训笔记

前几天报名了今天的校招实习生百阿百技培训。今早9点半在1号楼的白马山庄准时开始。主持人先闲扯了下,介绍一天的计划,上午是华黎带来的关于阿里技术发展历程以及个人经验的分享,下午还有两场讲座但与技术关联不大。由于师兄还给我布置了任务,我就参与了上午的讲座就回来了。在这里整理一下上午听到的笔记,可能比较零散,凑合着看。

从集中式应用到分布式应用

淘宝07年的负载是每天100万笔订单,当时采用的还是集中式的系统。集中式系统并不落后,不要陷入唯分布式至上的误区。

08年时,淘宝的数据库力量非常强悍,Oracle认证有60%在淘宝。当时的策略是,性能瓶颈了都从数据库角度入手,优化SQL、建索引等……虽然数据库技术力量非常强,撑起了淘宝的高访问量,但这种做法始终是有瓶颈的,一旦负载超过了天花板,会没有补救的办法(没法加机器水平扩展)。当年JD的618大促挂了,刘强东说要加三倍的机器,但这不能解决问题。集中式应用不可扩展,所以淘宝决定升级架构。

但需要明确,集中式应用的开发和维护代价都比较小。

分布式应用需要解决的核心问题:如何利用多个节点解决计算和存储;应用解耦和异步化;

传统关系型数据库的集群方案不靠谱。淘宝面对非常多类型的存储。

淘宝2.0~3.0的转变。HSF,Notify和数据访问层 三个中间件让集中式走向分布式应用。

※做好接口!你的产品可以有问题,但你应该是第一个发现的,不能让别人跑来告诉你你的产品有问题。(程序员的尊严)

分布式调试非常困难(解耦后找不到消息去向)

如何做线上容量规划和评估(线上真实引流压测)

水平扩展和垂直扩展:工程师不要因为分布式能够水平扩展而过度依赖水平扩展;目前过度依赖加机器,而没有充分发挥单机性能。

同城多机房;异地多机房。

趋势

算法的价值:先发优势

云计算时代:开发让应用做到可伸缩

无线(天猫的无线优先)

DT:数据≠算法。能不能让存数据的成本低,能不能让数据计算快。业务工程师应该有数据的sense:业务如何为公司产生数据;如何在业务中利用数据;如何利用数据产生价值。

建议

站在风口。

选择对职业发展有帮助的公司和职位。机会和空间很重要。看书和学知识只是基础,实战很重要。

找个感兴趣的方向,很辛苦但不会很痛苦。

目标:定短期目标。随着年龄的增大时间会越来越碎,如果愿意在事业上有发展,刚毕业对自己狠一点。

危机感。推荐书籍《浪潮之巅》。

[7.21实习笔记] Notify入门

待更新……

0

1

2

Notify Metamorphosis
模型 Push Pull
服务端 消息存储

处理请求

保存推送轨迹

保存订阅关系

消费者负载均衡

集中式

消息存储

处理请求

分布式

客户端 处理响应和请求 处理响应和请求

保存pull状态,如拉取位置的偏移量offset

异常情况下的消息暂存和recover

实时性 较好,收到数据后可立即发送给客户端 取决于pull的间隔时间
消费者故障 消费者故障情况下,服务端堆积消息,重复推送耗费资源。

保存推送轨迹压力很大。

消费者故障,对服务端无影响
其他 对消息推送有更多控制,能实现多样化的推送机制。

当消费者数量增多的时候,推送压力大,性能天花板。

消费者处理能力差异,导致堆消息

需要在客户端实现消息过滤,浪费资源。

需要在不同客户端之间协调,做负载均衡。

推荐资料

Notify 淘宝百科:http://baike.corp.taobao.com/index.php/Notify

(【对比】Metamorphosis淘宝百科:http://baike.corp.taobao.com/index.php/Metamorphosis-User-Guide

Notify Wiki:http://gitlab.alibaba-inc.com/notify/notify1/wikis/user-manual

(【对比】Metamorphosis Wiki:http://gitlab.alibaba-inc.com/middleware//metaq3/wikis/metanotes

Notify 学习视频:http://xue.alibaba-inc.com/trs/mediaDetail.htm?mediaUid=1ac893ae-01e1-4f64-a863-5f5a5f575b34

《Taobao Notify Overview》:http://baike.corp.taobao.com/images/e/eb/Taobao_Notify_Overview.pptx

《Notify Principle》:http://baike.corp.taobao.com/images/2/24/Principle.pptx

[7.14实习笔记] Maven入门

今天主要学习了Maven。整理记录一下。

Maven 是 Java 项目的一个构建工具,阿里内部使用Maven 2.2.1作为项目构建工具。

【Tips】关于Maven和后面WebX的学习,建议参照WebX提供的样例petstore进行对照理解。petstore的Github仓库地址为:https://github.com/webx/citrus-sample/tree/master/petstore

安装配置

安装

安装过程在上一篇博客中已经写过了:

[7.11实习笔记] 环境搭建 JDK+IDEA+MAVEN+JBOSS+HSF+SVN

配置

首先,我们要介绍一下仓库的概念。

在不用Maven的时候,比如说以前我们用Ant构建项目,在项目目录下,往往会看到一个名为/lib的子目录,那里存放着各类第三方依赖jar文件,如log4j.jar,junit.jar等等。每建立一个项目,你都需要建立这样的一个/lib目录,然后复制一对jar文件,这是很明显的重复。重复永远是噩梦的起点,多个项目不共用相同的jar文件,不仅会造成磁盘资源的浪费,也使得版本的一致性管理变得困难。此外,如果你使用版本管理工具,如SVN,你需要将大量的jar文件提交到代码库里,可是版本管理工具在处理二进制文件方面并不出色。

Maven仓库就是放置所有JAR文件(WAR,ZIP,POM等等)的地方,所有Maven项目可以从同一个Maven仓库中获取自己所需要的依赖JAR,这节省了磁盘资源。此外,由于Maven仓库中所有的JAR都有其自己的坐标(坐标的概念将在下面提到),该坐标告诉Maven它的组ID,构件ID,版本,打包方式等等,因此Maven项目可以方便的进行依赖版本管理。你也不再需要提交JAR文件到SCM仓库中,你可以建立一个组织层次的Maven仓库,供所有成员使用。

简言之,Maven仓库能帮助我们管理构件(主要是JAR)。

Maven的仓库分为本地仓库远程仓库。运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。

关于仓库的 详细介绍,可参见:http://juvenshun.iteye.com/blog/359256

为什么要谈到这个概念呢?因为它是Maven的配置文件settings.xml的很重要的一部分。这个配置文件一般存在在两个地方,分别是用户目录下的.m2目录里,以及maven安装目录的conf目录中。

打开这个配置文件,我们主要关注下面几项内容:

<localrepository>:这一项指定了本地仓库的存储目录。

<mirrors>:这一项指定了远程仓库的镜像地址。如果你的地理位置附近有一个速度更快的central镜像,或者你想覆盖central仓库配置,或者你想为所有POM使用唯一的一个远程仓库(这个远程仓库代理的所有必要的其它仓库),你可以使用这项配置。

<profiles>:profile可以让我们定义一系列的配置信息,然后指定其激活条件。这样我们就可以定义多个profile,然后每个profile对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。比如说,我们可以通过profile定义在jdk1.5以上使用一套配置信息,在jdk1.5以下使用另外一套配置信息;或者有时候我们可以通过操作系统的不同来使用不同的配置信息,比如windows下是一套信息,linux下又是另外一套信息,等等。关于profile的具体使用可参见:http://haohaoxuexi.iteye.com/blog/1900568

IntelliJ IDEA中配置Maven

在IntelliJ IDEA中使用Maven,可以在File→Settings→Project Settings→Maven中进行设置。

其中可以在Runner项下设置vm options: -Xmx512m -XX:MaxPermSize=1024m

项目结构

Maven的项目使用一个统一的约定的标准目录结构(Standard Directory Layout)。如下所示:

my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

这是一个典型的项目目录结构。

目录结构最顶层,是一个POM文件pom.xml(关于POM会在下面详细讲)。另外也可以有README.txt,LICENSE.txt等说明性文本。

子目录只有两种,src和target。其中target主要是存储build出来的东西的,src是存储所有的源代码的。它可以有这几种子目录:main(存放主要的构建代码);test(存放单元测试代码和资源),site,等。

在存储源代码的目录下(main,test等),有java(存放java代码),webapp(存放网络应用程序代码)和resource(存放资源)等目录。

src/main/java 应用程序/库的源代码
src/main/resources 应用程序/库的资源
src/main/filters 资源过滤文件
src/main/config 配置文件
src/main/scripts 应用程序/库的脚本
src/main/webapp 网络应用程序源代码
src/test/java 测试源代码
src/test/resources 测试资源
src/test/filters 测试资源过滤文件
src/it 集成测试(主要用于插件)
src/assembly 装配说明
src/site 站点
LICENSE.txt 项目许可协议
NOTICE.txt 项目所依赖的库所要求的说明和权限
README.txt 项目自述文件

POM

现在进入了Maven很重要的一个概念:POM(Project Object Model)。POM是Maven的核心,它以XML格式描述了所有与项目有关的信息。

首先介绍一个概念:坐标

坐标是指项目的唯一标识,以 GAV(groupId,artifactId 和 version)区分,这里我们可以将 groupId 理解为某某公司的 xxx 组或者产品线,开发了某一个项目,对应的版本为 XXX。这里 groupId 包含公司和内部组(或产品线)的信息,如 org.apache.commons,表示 Apache
软件组织下的 Java Commponents 产品线;ArtifactId 则表示项目的名称,如 commons-io,表示项目名称,Version 则表示某一 Artifact 的版本,如 1.3.2,1.3.3-SNAPSHOT 等。

当我们打开一个POM文件,首先看到的是一段描述我们正在建立的artifact信息:

[xml]
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
[/xml]

这是强制性的开端部分。接下来是一组坐标。描述了当前项目的groupId, artifactId, version和name。

下面是<properties>。我们可以把properties理解为一组自定义的变量。我们可以在下面定义的依赖中使用这些变量,这样未来在我们需要升级包版本等场景时,可以通过修改变量的值来方便的实现。大家可以参照petstore的pom.xml文件来理解。

而后是依赖管理的部分。

[xml]
<dependencies>
<dependency>
<groupId>jdbm</groupId>
<artifactId>jdbm</artifactId>
<version>1.0</version>
</dependency>
[/xml]

这是一个获取jdbm的简单依赖。默认情况下,Maven通过访问http://www.ibibio.ort/maven2/来获得依赖,如果你查看jdbm/jdbm/1.0/目录,就会发现jdbm-1.0.jar文件,Maven将恢复它;以及一个简短的jdbm pom.xml文件,它列举artifact本身拥有的任何依赖。你可以手动浏览ibibio贮藏库或使用MVN Registry这样的网站来搜索贮藏库。

下一个要讨论的依赖是dwr,但你在ibibio贮藏库中找不到它。你必须将它安装到我们自己的本地贮藏库中。

[xml]
<dependency>
<groupId>dwr</groupId>
<artifactId>dwr</artifactId>
<version>2.0M3</version>
</dependency>
[/xml]

下一个依赖为Java Servlet API。在ibibio库中可以找到它,但我们只有在建立项目的时候才需要它;因为当我们配置一台网络服务器时,servlet API已经存在。

[xml]
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4-20040521</version>
<scope>provided</scope>
</dependency>
[/xml]

scope说明何时需要这个artifact,因此“provided”说明artifact由运行时间环境提供。另一个scope类型为“test”,它说明只有在测试时需要artifact。例如,我们这样包括Junit:

[xml]
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
[/xml]

那么,我们如果想引入一个依赖,应该怎么写这个dependency呢?其实我们可以通过远程仓库来搜索每个构建对应的XML描述。

常用的搜索页面有:maven.oschina.net,以及search.maven.org。我们在其中搜索一个构建,便可以得到它对应的XML描述。

现在,POM还剩最后一块内容:插件。

[xml]
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
[/xml]

Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven-compiler-plugin完成的。进一步说,每个任务对应了一个插件目标(goal),每个插件会有一个或者多个目标,例如maven-compiler-plugin的compile目标用来编译位于src/main/java/目录下的主源码,testCompile目标用来编译位于src/test/java/目录下的测试源码。

生命周期

Maven强大的一个重要的原因是它有一个十分完善的生命周期模型(lifecycle),这个生命周期可以从两方面来理解,第一,顾名思义,运行Maven的每个步骤都由它来定义的,这种预定义的默认行为使得我们使用Maven变得简单,相比而言,Ant的每个步骤都要你手工去定义。第二,这个模型是一种标准,在不同的项目中,使用Maven的接口是一样的,这样就不用去仔细理解每个项目的构建了,一般情况下,mvn clean install 这样的命令是通用的。

Maven有三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,初学者容易将Maven的生命周期看成一个整体,其实不然。这三套生命周期分别是:

  • Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
  • Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
  • Site Lifecycle 生成项目报告,站点,发布站点。

我再次强调一下它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期。

知道了每套生命周期的大概用途和相互关系以后,来逐个详细看一下每套生命周期,Clean和Site相对比较简单,先解释一下。

每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean ,这个的clean是Clean生命周期的一个阶段。有点绕?要知道有Clean生命周期,也有clean阶段。Clean生命周期一共包含了三个阶段:

  • pre-clean  执行一些需要在clean之前完成的工作
  • clean  移除所有上一次构建生成的文件
  • post-clean  执行一些需要在clean之后立刻完成的工作

mvn clean 中的clean就是上面的clean,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,mvn clean 等同于 mvn pre-clean clean ,如果我们运行 mvn post-clean ,那么 pre-clean,clean 都会被运行。这是Maven很重要的一个规则,可以大大简化命令行的输入。

下面看一下Site生命周期的各个阶段:

  • pre-site     执行一些需要在生成站点文档之前完成的工作
  • site    生成项目的站点文档
  • post-site     执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
  • site-deploy     将生成的站点文档部署到特定的服务器上

这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。

最后,来看一下Maven的最重要的Default生命周期,绝大部分工作都发生在这个生命周期中,这里只解释一些比较重要和常用的阶段:

  • validate
  • generate-sources
  • process-sources
  • generate-resources
  • process-resources     复制并处理资源文件,至目标目录,准备打包。
  • compile     编译项目的源代码。
  • process-classes
  • generate-test-sources 
  • process-test-sources 
  • generate-test-resources
  • process-test-resources     复制并处理资源文件,至目标测试目录。
  • test-compile     编译测试源代码。
  • process-test-classes
  • test     使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
  • prepare-package
  • package     接受编译好的代码,打包成可发布的格式,如 JAR 。
  • pre-integration-test
  • integration-test
  • post-integration-test
  • verify
  • install     将包安装至本地仓库,以让其它项目依赖。
  • deploy     将最终的包复制到远程的仓库,以让其它开发人员与项目共享。

基本上,根据名称我们就能猜出每个阶段的用途,关于其它阶段的解释,请参考 http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

记住,运行任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么我们运行mvn install 的时候,代码会被编译,测试,打包。

骨架

Maven约定的项目目录结构,如果手动创建,每个工程的重复工作非常多。为此,Maven提供了Archetype以帮助我们快速勾勒出项目骨架。

在IntelliJ IDEA中,使用Maven的骨架创建项目非常简单。我们只需选择File→New Project→Maven,勾选Create from archetype,然后在下方选择所需要使用的骨架(例如maven-archetype-webapp),点击Next按照向导提示操作即可。在选择骨架时,也可以直接输入关键词查找相应的骨架。

资料推荐

一些maven书籍介绍和一些maven视频介绍:
http://pan.baidu.com/s/1hq00qLA

国外非常不错的学习材料网站,集成了介绍、快速引导,书籍推荐等:
http://www.tutorialspoint.com/maven/index.htm

maven官网:
http://maven.apache.org/

官网介绍什么是maven:
http://maven.apache.org/what-is-maven.html

maven2和maven3的区别(目前主流是maven3):
http://tech.it168.com/a2010/1108/1123/000001123274_all.shtml
http://www.infoq.com/cn/news/2011/07/xxb-maven-10-time-to-update

maven下载:
http://maven.apache.org/download.cgi
windows需要下载的文件:apache-maven-版本号-bin.zip

maven官网5分钟速成:
http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

maven官网入门指南:
http://maven.apache.org/guides/getting-started/index.html

FAQ英文官网:
http://maven.apache.org/general.html

FAQ英文非官网:
http://docs.codehaus.org/display/MAVENUSER/FAQs-1

maven一些插件列表:
http://maven.apache.org/plugins

Maven 的41种骨架功能介绍:
http://www.cnblogs.com/iusmile/archive/2012/11/14/2770118.html
http://docs.codehaus.org/display/MAVENUSER/Archetypes+List

[7.11实习笔记] 环境搭建 JDK+IDEA+MAVEN+JBOSS+HSF+SVN

7月11日流水

今天上午领了工牌和PC。排了一个多小时的队。本来8点半到想着能早点领,没想到排PC的队排了半天突然工作人员一句“实习入职跟我来”,队伍全乱了……好不容易领了机子到IT临时服务点配置了一下,出来都快11点了。无力吐槽。

webwxgetmsgimg (3)

回到工位就把工牌和支付宝绑定了。这样在园区各个地方都不用带钱包,食堂超市直接刷工牌。还是比较方便的。

webwxgetmsgimg (4)

下午就是根据师姐给的内部百科链接(叫翔哥的师兄写的文档),以及一个Taobao_Developer_Cookbook的文档开始搭建工作环境。具体的笔记在下面会写。第一次搭这些环境还是比较蛋疼的。记录下来也好以后备查。

7月11日笔记

首先,明确需要搭建的环境:

  1. JDK 1.6.0_43
  2. IntelliJ IDEA 13.1.3(社区版)
  3. Maven 2.2.1
  4. JBoss 4.2.2.GA
  5. HSF 2.1.0.6
  6. TortoiseSVN 1.8

其次,阿里统一将这些环境安装在D:java_tools目录下。

为何要规划安装目录? 

开发人员之间经常会进行一些交流或者协助排查问题,最常见的几句话?“你的 Java 安装在哪里?”;“JBoss 安装在哪个目录下?我要改一下设置!”。“Eclipse 安装在哪个目录下,打开一下!”。如果不想让你的同事费心做这些事情,那最好将这些开发用的软件安装在指定的目录下,这样大家的环境都一样,排查问题就方便很多。还有 Java 软件最忌安装在有空格或者中文的目录下,这个一定需要注意一下。

为何要使用旧版的环境? 

版本还是挺重要的,有些高版本会导致一些莫名其妙的错误。师兄曾遇到过Maven版本的问题,总提示日志系统不存在。

接下来就可以依次搭建这些环境啦~

JDK 1.6.0_43

软件环境:Windows版,64位

下载地址:http://dl1.cr173.com//soft1/jdk-6.zip

安装配置:

  1. 下载并解压ZIP包。执行其中的jdk-6u43-windows-x64.exe,根据提示完成安装
  2. 配置环境变量:计算机→属性→高级系统设置→高级→环境变量
  3. 系统变量→新建JAVA_HOME变量。值为JDK安装目录。
  4. 系统变量→寻找PATH变量→编辑。在值的末尾加上JDK安装路径下bin目录,以及jre的bin目录(目录间以;分隔)
  5. 系统变量→新建CLASSPATH变量,值为 .; 以及JDK目录下lib目录,以及这个lib目录下的tools.jar
  6. 测试是否安装成功:启动cmd,输入java –version。如果显示版本号则安装成功。

IntelliJ IDEA 13.1.3(社区版)

软件环境:Windows 社区版(这是商业软件,是付费的。但社区版是免费的。)

下载地址:http://download-cf.jetbrains.com/idea/ideaIC-13.1.3.exe

安装配置:

  1. 下载并执行安装程序,根据提示完成安装
  2. 修改IDE外观与字体:File→Settings→IDE Settings→Appearance 在这里选择喜欢的Theme,以及Override default fonts by的字体和字号;
  3. 修改代码字体:File→Settings→IDE Settings→Editor→Colors & Fonts→Font 先在Scheme name处点Save As,输入自己的配置的名字;然后设置自己喜欢的字体字号和间距。个人比较喜欢Source Code Pro,看着很舒服。
  4. 解决中文乱码:在上一步把Show only monospaced fonts的勾去掉,Primary font选自己喜欢的英文字体,勾选Secondary font并选择一个中文字体。我选的是微软雅黑(Microsoft YaHei UI)。
  5. 显示行号:File→Settings→IDE Settings→Editor→Appearance,勾选Show line numbers以显示行号。

更多技巧:http://www.cnblogs.com/sky100/archive/2009/01/22/1379949.html

插件使用:

  1. 插件安装的方法:
    1. File→SettingsIDE Settings→Plugins 点击Browse repositories按钮。
    2. 在搜索框直接搜索想要的插件
    3. 点击右边的install plugin按钮就可以了。
  2. 常用插件:
    1. Identifier Highlighter 高亮显示选中变量插件
    2. Key Promoter 快捷键提示插件
    3. Jrebel 热部署插件(需破解。破解方法:http://my.oschina.net/lujianing/blog/178578#OSC_h2_3
    4. FindBugs for IntelliJ IDEA
    5. TabSwitch 通过ctrl+tab在文件、各个面板间切换。
    6. Mybatis
    7. EncodingPlugin 可按项目指定其默认编码,非常有用

(更多插件请参阅http://blog.csdn.net/sunny243788557/article/details/26556967

Maven 2.2.1

下载地址:http://dxdown1.onlinedown.net/down/apache-maven-2.2.1-bin.tar.zip

安装配置:

  1. 下载并解压ZIP包。将其解压到安装路径。
  2. 下载 http://baike.corp.taobao.com/images/9/96/Maven_Settings.xml 这个配置文件,并覆盖到mavenconf目录中。
  3. 设置系统环境变量(同上文JDK的方法),将安装目录下bin目录添加到PATH环境变量值中。
  4. 新建系统环境变量M2_HOME,设置值为maven安装目录。
  5. 测试是否安装成功:启动cmd,输入mvn –version。如果显示版本号则安装成功。
  6. 执行mvn help:system进行mvn的初始化工作,主要是检查artifact是否能正确下载,初始化Maven本地仓库等。

JBoss 4.2.2.GA

软件环境:我们这里要使用的是阿里修改过的JBoss线上通用版本,和官方版本不一样,修改了classloader双亲委派。

下载地址:http://hsf.taobao.net/software/jboss-4.2.2.GA.zip

安装配置:

  1. 下载并解压ZIP包。将其解压到安装路径。
  2. 新建系统环境变量JBOSS_HOME,设置值为JBoss安装路径。
  3. 测试是否安装成功:运行Jboss安装目录下bin目录中的run.bat,若窗口中没有出现异常,且出现10:16:19,765 INFO [Server] JBoss (MX MicroKernel) [4.2.1.GA (build: SVNTag=JBoss_4_2_1_GA date=200707131605)] Started in 30s:828ms字样,则表示安装成功。
  4. 我们可以通过访问 http://localhost进入JBoss的欢迎界面

HSF 2.1.0.6

下载地址:http://hsf.taobao.net/hsfversion/hsf2.1.0.6/taobao-hsf.tgz

安装配置:

  1. 下载tgz包。
  2. 将其解压到JBoss目录下的serverdefaultdeploy目录下即可。

TortoiseSVN 1.8

软件环境:Windows 64位版

下载地址:http://cqindex.newhua.com/down/TortoiseSVN-1.8.7.25475-x64-svn-1.8.9.zip

安装配置:

  1. 下载并解压ZIP包,执行其中的安装程序。
  2. 根据提示进行安装。在组件选择的一步,记得勾选command line client tools(默认是不安装这个部分的)。没装的话,IDEA可能会报错,提示执行svn命令出错。

至此,基本的开发环境搭建就完成了。后面就要开始学习啦~

[7.10实习笔记] 入职手续与培训

决定在博客里记录下每天的实习生活。可能是日常流水,也会有学习笔记。

7月10日流水

7月10日上午起早转公交到海创园。早早来到二层大厅等待领自己的材料。大概9点多领到了一个文件夹和一个文具袋。文件夹里是一大叠卖身契,文具袋里是工牌套、各种笔和本子。然后就进会场坐着等待开始了。

webwxgetmsgimg (1)

一上午的主要任务就是讲解一堆卖身契的签法,以及上交了一张一寸照用于办理工牌。(坑爹的是,按照后来发下来的工牌情况看,乖乖交照片的都是扫描制作的,照片普遍都偏色严重;而因为没带照片交电子版的反而幸免于难…- -#)

中午在海创园挤到爆的食堂吃了饭。只有1小时用餐时间,很赶。

下午是行政,财务,IT,薪酬福利培训。比较冗长。就不多说了。主要槽点在于男性25岁以上就算晚婚了可以享受15天带薪婚假哦~ 唉,首先,我得在25岁前找到妹纸……

结束培训突降暴雨。我们在海创园等到暴雨过去后,终于来到园区了。园区倒是非常漂亮的~ 天猫事业部在4号楼。终于见到了亲爱的师兄师姐们。

webwxgetmsgimg

惊喜的发现隔壁工位刚入职的师姐,也是福建人~口音太亲切了哈哈。因为工牌还没发下来,所以蹭了师姐一顿晚饭。感觉团队还是很融洽的~

对即将开始的实习生活充满了期待啊。

webwxgetmsgimg (2)