paulwong

#

我们应当怎样做需求调研:迭代

前面我一直在反复强调这样一个观点,需求分析不是一蹴而就的,是一个反复迭代的过程。它将从第一次需求分析开始,一直持续到整个项目生命周期。为什么这样说呢?让我们一起来分析分析。

在第一次的需求分析阶段,我们在一段时期内需要与客户进行反复地讨论,这个过程往往是这样一个反复循环的过程:需求捕获->需求整理->需求验证->再需求捕获••••••

需求捕获,就是我们与客户在一起开研讨会,讨论需求的活动。客户可能会描述他们的业务流程,这时我们在纸上绘制简单的流程草图,及时地记录下来;客户在描述业务的同时,可能会反复提到一些业务名词,详细询问这些名词的含义,以及它们与其它名词的关系,用类图或者对象图绘制简单的草图;客户在描述业务的同时,还会提出今后的软件希望实现的功能,如能够展示某个报表、能够导出文件,以需求列表的形式记录下来。一个功能,在需求列表中会有多个需求,而每个需求应当能够用1、2句话,在20个字以内就可以描述清楚。需求列表是客户提出的最最原始的需求,他不掺杂任何分析设计,是我们的每项功能必须实现的内容。需求列表是需求验证以及日后的用户验收测试的依据,不论我们今后如何分析和设计这些功能,都要能如实地实现这个列表中提出的需求。(需求列表应当如何编写,将在后面的章节详细描述。)

需求整理,就是在需求研讨会后,需求分析人员对研讨内容的分析和整理的过程。首先,需求分析人员应当通过用例模型,划分整个系统的功能模块,以及各个模块的业务流程。用例模型分析是一个由粗到细的过程,这样一个过程也是符合人类认识世界的思维习惯的一个过程。最先,我们应当对整个系统绘制用例图,设计用例场景,并依次对这些用例进行用例描述、流程分析、角色分析等分析过程。当然,在整体用例分析的同时,我们还应当进行一个整体的角色分析,绘制一个角色分析图,进行一个流程分析,绘制一个流程分析图(可以是传统的流程图、UML中的行动图,甚至一个简单的示意图,等等)。

然后,我们再在整体用例图的基础上,依次对每个用例绘制用例图。每个用例图中,会更细致地划分出多个用例,并依次进行用例描述、流程分析、角色分析等分析工作。如此这般地不断细化,直到我们认为需求已经描述清楚为止。

在一个系统中,用例需要细化几次,是由这个用例的业务复杂程度决定的。对于一个简单的用例,只需要细化一次就够了;而对于比较复杂的用例,则需要细化2~3次,甚至更多。

用例分析的过程,之所以称之为分析,它掺入了很多需求分析人员对业务的理解与设计:模块如何划分、流程如何设计、业务如何转换,等等。用例分析,还需要让需求分析员与架构师、设计师等技术人员共同协作来完成,因为用例分析还包含对业务需求的技术可行性分析。只有一份可行的需求分析,才能为后续的设计开发扫清障碍,有效降低项目风险。最后,需求分析员应当将需求列表中的内容,逐一地与用例进行核对,以避免分析人员忽略用户的某项业务需求。(后面将详细描述用例模型的搭建过程。)

在用例分析的同时,需求分析人员还需要对业务中的相关事物,制作领域模型。领域模型,是对用户业务领域中相关事物、相互关系、相互行为操作的描述,它是以对象图和类图的形式表达的。需求人员对领域模型的分析,对业务理解的深度,对日后软件的设计,以及软件的功能扩展、升级演化,都起到了至关重要的作用。(后面将更加详细地讲述领域模型。)

最后,当我们完成了一系列的分析整理并形成文档以后,应当对及时地与客户进行反馈,确认我们的理解是否正确,也就是需求验证工作。需求验证工作应当贯穿整个研发周期,并且在不同时期表现出不同的形式。首先,在需求分析阶段,需求验证工作表现为对需求理解是否正确的信息反馈。需求分析人员与客户再次坐在一起,一项一项描述我们对需求的整理和理解,客户则时不时地对一些问题进行纠正,或者更加深入地加以描述。我们则认真地记录,回来整理,并等待下一次的验证。在需求分析后期,我们还可以制作一些简单的原型,更加形象地描述我们对需求的理解,会使我们与客户的沟通更加顺畅。随后的设计开发阶段,我们则应当以迭代开发的形式进行。每开发完一个迭代周期,将开发的成果与客户反馈。这样做的结果是,客户可以及时地提出我们对需求理解的偏差,或者及时提出对我们设计不满意的地方,使我们存在的问题得到及时地发现与解决。问题及时的解决,使我们修复问题的代价得以降至最小。之后,当开发进入到验收测试阶段,我们则是与客户一道,一项一项地验证我们的软件是否满足需求列表中要求的业务需求。最后,当软件迎来下一次升级开发时,我们将开启另一次轮回。

因此,需求分析就是按照这样的过程,每次多理解一些,再多理解一些,更多理解一些,逐渐深入的过程。每深入一步,我们的软件就更接近客户的满意。

我们应当怎样做需求分析
我们应当怎样做需求调研:初识
我们应当怎样做需求调研:拜访
我们应当怎样做需求调研:研讨会
我们应当怎样做需求调研:需求研讨
我们应当怎样做需求调研:迭代
(续)

posted @ 2012-02-14 01:12 paulwong 阅读(540) | 评论 (0)编辑 收藏

Hadoop集群环境搭建

通常,集群里的一台机器被指定为 NameNode,另一台不同的机器被指定为JobTracker。这些机器是 masters。余下的机器即作为DataNode 也作为TaskTracker。这些机器是 slaves\ 官方地址:(http://hadoop.apache.org/common/docs/r0.19.2/cn/cluster_setup.html)
1 先决条件确保在你集群中的每个节点上都安装了所有必需软件:sun-JDK ,ssh,Hadoop
JavaTM1.5.x,必须安装,建议选择Sun公司发行的Java版本。
ssh 必须安装并且保证 sshd一直运行,以便用Hadoop 脚本管理远端Hadoop守护进程。
2 实验环境搭建2.1 准备工作操作系统:Ubuntu
部署:Vmvare
在vmvare安装好一台Ubuntu虚拟机后,可以导出或者克隆出另外两台虚拟机。
说明:
保证虚拟机的ip和主机的ip在同一个ip段,这样几个虚拟机和主机之间可以相互通信。
为了保证虚拟机的ip和主机的ip在同一个ip段,虚拟机连接设置为桥连。

准备机器:一台master,若干台slave,配置每台机器的/etc/hosts保证各台机器之间通过机器名可以互访,例如:
10.64.56.76 node1(master)
10.64.56.77 node2 (slave1)
10.64.56.78 node3 (slave2)
主机信息:

机器名IP地址作用
Node110.64.56.76NameNode、JobTracker
Node210.64.56.77DataNode、TaskTracker
Node310.64.56.78DataNode、TaskTracker
为保证环境一致先安装好JDK和ssh:
2.2 安装JDK
#安装JDK
$ sudo apt-get install sun-java6-jdk1.2.3
这个安装,java执行文件自动添加到/usr/bin/目录。
验证 shell命令 :java -version 看是否与你的版本号一致。
2.3下载、创建用户$ useradd hadoop
$ cd /home/hadoop
在所有的机器上都建立相同的目录,也可以就建立相同的用户,最好是以该用户的home路径来做hadoop的安装路径。
例如在所有的机器上的安装路径都是:/home/hadoop/hadoop-0.20.203,这个不需要mkdir,在/home/hadoop/下解压hadoop包的时候,会自动生成)
(当然可以安装/usr/local/目录下,例如/usr/local/hadoop-0.20.203/
chown -R hadoop /usr/local/hadoop-0.20.203/
chgrp -R hadoop /usr/local/hadoop-0.20.203/

(最好不要使用root安装,因为不推荐各个机器之间使用root访问 )

2.4 安装ssh和配置1) 安装:sudo apt-get install ssh


这个安装完后,可以直接使用ssh命令 了。
执行$ netstat -nat 查看22端口是否开启了。
测试:ssh localhost。
输入当前用户的密码,回车就ok了。说明安装成功,同时ssh登录需要密码。
(这种默认安装方式完后,默认配置文件是在/etc/ssh/目录下。sshd配置文件是:/etc/ssh/sshd_config):

注意:在所有机子都需要安装ssh。

2) 配置:
在Hadoop启动以后,Namenode是通过SSH(Secure Shell)来启动和停止各个datanode上的各种守护进程的,这就须要在节点之间执行指令的时候是不须要输入密码的形式,故我们须要配置SSH运用无密码公钥认证的形式。
以本文中的三台机器为例,现在node1是主节点,他须要连接node2和node3。须要确定每台机器上都安装了ssh,并且datanode机器上sshd服务已经启动。
( 说明:hadoop@hadoop~]$ssh-keygen -t rsa
这个命令将为hadoop上的用户hadoop生成其密钥对,询问其保存路径时直接回车采用默认路径,当提示要为生成的密钥输入passphrase的时候,直接回车,也就是将其设定为空密码。生成的密钥对id_rsa,id_rsa.pub,默认存储在/home/hadoop/.ssh目录下然后将id_rsa.pub的内容复制到每个机器(也包括本机)的/home/dbrg/.ssh/authorized_keys文件中,如果机器上已经有authorized_keys这个文件了,就在文件末尾加上id_rsa.pub中的内容,如果没有authorized_keys这个文件,直接复制过去就行.)
3) 首先设置namenode的ssh为无需密码的、自动登录。
切换到hadoop用户( 保证用户hadoop可以无需密码登录,因为我们后面安装的hadoop属主是hadoop用户。)
$ su hadoop
cd /home/hadoop
$ ssh-keygen -t rsa


然后一直按回车
完成后,在home跟目录下会产生隐藏文件夹.ssh
$ cd .ssh
之后ls 查看文件
cp id_rsa.pub authorized_keys
测试:
$ssh localhost
或者:
$ ssh node1

第一次ssh会有提示信息:
The authenticity of host ‘node1 (10.64.56.76)’ can’t be established.
RSA key fingerprint is 03:e0:30:cb:6e:13:a8:70:c9:7e:cf:ff:33:2a:67:30.
Are you sure you want to continue connecting (yes/no)?
输入 yes 来继续。这会把该服务器添加到你的已知主机的列表中
发现链接成功,并且无需密码。


4 ) 复制authorized_keys到node2 和node3 上
为了保证node1可以无需密码自动登录到node2和node3,先在node2和node3上执行

$ su hadoop
cd /home/hadoop
$ ssh-keygen -t rsa
一路按回车.
然后回到node1,复制authorized_keys到node2 和node3
[hadoop@hadoop .ssh]$ scp authorized_keys node2:/home/hadoop/.ssh/
[hadoop@hadoop .ssh]$ scp authorized_keys node3:/home/hadoop/.ssh/

这里会提示输入密码,输入hadoop账号密码就可以了。
改动你的 authorized_keys 文件的许可权限 [hadoop@hadoop .ssh]$chmod 644 authorized_keys

测试:ssh node2或者ssh node3(第一次需要输入yes)。
如果不须要输入密码则配置成功,如果还须要请检查上面的配置能不能正确。
2.5 安装Hadoop#切换为hadoop用户
su hadoop
wgethttp://apache.mirrors.tds.net//hadoop/common/hadoop-0.20.203.0/hadoop-0.20.203.0rc1.tar.gz
下载安装包后,直接解压安装即可:
$ tar -zxvfhadoop-0.20.203.0rc1.tar.gz


1 ) 安装Hadoop集群通常要将安装软件解压到集群内的所有机器上。并且安装路径要一致,如果我们用HADOOP_HOME指代安装的根路径,通常,集群里的所有机器的
HADOOP_HOME路径相同。
2 ) 如果集群内机器的环境完全一样,可以在一台机器上配置好,然后把配置好的软件即hadoop-0.20.203整个文件夹拷贝到其他机器的相同位置即可。
3 ) 可以将Master上的Hadoop通过scp拷贝到每一个Slave相同的目录下,同时根据每一个Slave的Java_HOME 的不同修改其hadoop-env.sh 。
4) 为了方便,使用hadoop命令或者start-all.sh等命令,修改Master上/etc/profile 新增以下内容:
export HADOOP_HOME=/home/hadoop/hadoop-0.20.203
exportPATH=$PATH:$HADOOP_HOME/bin
修改完毕后,执行source /etc/profile 来使其生效。

6)配置conf/hadoop-env.sh文件

配置conf/hadoop-env.sh文件
#添加 export JAVA_HOME=/usr/lib/jvm/java-6-sun/
这里修改为你的jdk的安装位置。
测试hadoop安装:
Bin/hadoop jar hadoop-0.20.2-examples.jarwordcount conf/ /tmp/out
3. 集群配置(所有节点相同)3.1配置文件:conf/core-site.xml




fs.default.name
hdfs://node1:49000


hadoop.tmp.dir
/home/hadoop/hadoop_home/var



1)fs.default.name是NameNode的URI。hdfs://主机名:端口/
2)hadoop.tmp.dir :Hadoop的默认临时路径,这个最好配置,如果在新增节点或者其他情况下莫名其妙的DataNode启动不了,就删除此文件中的tmp目录即可。不过如果删除了NameNode机器的此目录,那么就需要重新执行NameNode格式化的命令。
3.2配置文件:conf/mapred-site.xml




mapred.job.tracker
node1:49001


mapred.local.dir
/home/hadoop/hadoop_home/var


1)mapred.job.tracker是JobTracker的主机(或者IP)和端口。主机:端口。
3.3配置文件:conf/hdfs-site.xml




dfs.name.dir
/home/hadoop/name1, /home/hadoop/name2 #hadoop的name目录路径



dfs.data.dir
/home/hadoop/data1, /home/hadoop/data2



dfs.replication

2



1) dfs.name.dir是NameNode持久存储名字空间及事务日志的本地文件系统路径。 当这个值是一个逗号分割的目录列表时,nametable数据将会被复制到所有目录中做冗余备份。
2) dfs.data.dir是DataNode存放块数据的本地文件系统路径,逗号分割的列表。 当这个值是逗号分割的目录列表时,数据将被存储在所有目录下,通常分布在不同设备上。
3)dfs.replication是数据需要备份的数量,默认是3,如果此数大于集群的机器数会出错。
注意:此处的name1、name2、data1、data2目录不能预先创建,hadoop格式化时会自动创建,如果预先创建反而会有问题。
3.4配置masters和slaves主从结点配置conf/masters和conf/slaves来设置主从结点,注意最好使用主机名,并且保证机器之间通过主机名可以互相访问,每个主机名一行。
vi masters:
输入:
node1
vi slaves:
输入:
node2
node3
配置结束,把配置好的hadoop文件夹拷贝到其他集群的机器中,并且保证上面的配置对于其他机器而言正确,例如:如果其他机器的Java安装路径不一样,要修改conf/hadoop-env.sh
$ scp -r /home/hadoop/hadoop-0.20.203 root@node2: /home/hadoop/

4 hadoop启动4.1 格式化一个新的分布式文件系统先格式化一个新的分布式文件系统
$ cd hadoop-0.20.203
$ bin/hadoop namenode -format
成功情况下系统输出:

12/02/06 00:46:50 INFO namenode.NameNode:STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG: host = ubuntu/127.0.1.1
STARTUP_MSG: args = [-format]
STARTUP_MSG: version = 0.20.203.0
STARTUP_MSG: build =http://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.20-security-203-r 1099333; compiled by 'oom' on Wed May 4 07:57:50 PDT 2011
************************************************************/

12/02/0600:46:50 INFO namenode.FSNamesystem: fsOwner=root,root
12/02/06 00:46:50 INFO namenode.FSNamesystem:supergroup=supergroup
12/02/06 00:46:50 INFO namenode.FSNamesystem:isPermissionEnabled=true
12/02/06 00:46:50 INFO common.Storage: Imagefile of size 94 saved in 0 seconds.
12/02/06 00:46:50 INFO common.Storage: Storagedirectory /opt/hadoop/hadoopfs/name1 has been successfully formatted.
12/02/06 00:46:50 INFO common.Storage: Imagefile of size 94 saved in 0 seconds.
12/02/06 00:46:50 INFO common.Storage: Storagedirectory /opt/hadoop/hadoopfs/name2 has been successfully formatted.
12/02/06 00:46:50 INFO namenode.NameNode:SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode atv-jiwan-ubuntu-0/127.0.0.1
************************************************************/


查看输出保证分布式文件系统格式化成功
执行完后可以到master机器上看到/home/hadoop//name1和/home/hadoop//name2两个目录。在主节点master上面启动hadoop,主节点会启动所有从节点的hadoop。
4.2 启动所有节点启动方式1:
$ bin/start-all.sh (同时启动HDFS和Map/Reduce)
系统输出:

starting namenode, logging to /usr/local/hadoop/logs/hadoop-hadoop-namenode-ubuntu.out
node2: starting datanode, loggingto /usr/local/hadoop/logs/hadoop-hadoop-datanode-ubuntu.out
node3: starting datanode, loggingto /usr/local/hadoop/logs/hadoop-hadoop-datanode-ubuntu.out
node1: starting secondarynamenode,logging to /usr/local/hadoop/logs/hadoop-hadoop-secondarynamenode-ubuntu.out
starting jobtracker, logging to/usr/local/hadoop/logs/hadoop-hadoop-jobtracker-ubuntu.out
node2: starting tasktracker,logging to /usr/local/hadoop/logs/hadoop-hadoop-tasktracker-ubuntu.out
node3: starting tasktracker,logging to /usr/local/hadoop/logs/hadoop-hadoop-tasktracker-ubuntu.out
As you can see in slave's output above, it will automatically format it's storage directory(specified by dfs.data.dir) if it is not formattedalready. It will also create the directory if it does not exist yet.
执行完后可以到master(node1)和slave(node1,node2)机器上看到/home/hadoop/hadoopfs/data1和/home/hadoop/data2两个目录。
启动方式2:
启动Hadoop集群需要启动HDFS集群和Map/Reduce集群。
在分配的NameNode上,运行下面的命令启动HDFS:
$ bin/start-dfs.sh(单独启动HDFS集群)
bin/start-dfs.sh脚本会参照NameNode上${HADOOP_CONF_DIR}/slaves文件的内容,在所有列出的slave上启动DataNode守护进程。
在分配的JobTracker上,运行下面的命令启动Map/Reduce:
$bin/start-mapred.sh (单独启动Map/Reduce)
bin/start-mapred.sh脚本会参照JobTracker上${HADOOP_CONF_DIR}/slaves文件的内容,在所有列出的slave上启动TaskTracker守护进程。

4.3 关闭所有节点从主节点master关闭hadoop,主节点会关闭所有从节点的hadoop。
$ bin/stop-all.sh
Hadoop守护进程的日志写入到 ${HADOOP_LOG_DIR} 目录 (默认是 ${HADOOP_HOME}/logs).
${HADOOP_HOME}就是安装路径.
5 .测试1)浏览NameNode和JobTracker的网络接口,它们的地址默认为:
NameNode - http://node1:50070/
JobTracker - http://node2:50030/
3) 使用netstat –nat查看端口49000和49001是否正在使用。
4) 使用jps查看进程
要想检查守护进程是否正在运行,可以使用 jps 命令(这是用于 JVM 进程的ps 实用程序)。这个命令列出 5 个守护进程及其进程标识符。
5)将输入文件拷贝到分布式文件系统:
$ bin/hadoop fs -mkdir input
$ bin/hadoop fs -put conf/core-site.xml input
运行发行版提供的示例程序:
$ bin/hadoop jar hadoop-0.20.2-examples.jar grep input output 'dfs[a-z.]+'
6.补充
Q: bin/hadoop jar hadoop-0.20.2-examples.jar grep input output 'dfs[a-z.]+' 什么意思啊?
A: bin/hadoop jar(使用hadoop运行jar包) hadoop-0.20.2_examples.jar(jar包的名字) grep (要使用的类,后边的是参数)input output 'dfs[a-z.]+'
整个就是运行hadoop示例程序中的grep,对应的hdfs上的输入目录为input、输出目录为output。
Q: 什么是grep?
A: A map/reduce program that counts the matches of a regex in the input.
查看输出文件:
将输出文件从分布式文件系统拷贝到本地文件系统查看:
$ bin/hadoop fs -get output output
$ cat output/*
或者
在分布式文件系统上查看输出文件:
$ bin/hadoop fs -cat output/*
统计结果:
root@v-jiwan-ubuntu-0:~/hadoop/hadoop-0.20.2-bak/hadoop-0.20.2#bin/hadoop fs -cat output/part-00000
3 dfs.class
2 dfs.period
1 dfs.file
1 dfs.replication
1 dfs.servers
1 dfsadmin
7. HDFS常用操作
hadoopdfs -ls 列出HDFS下的文件
hadoop dfs -ls in 列出HDFS下某个文档中的文件
hadoop dfs -put test1.txt test 上传文件到指定目录并且重新命名,只有所有的DataNode都接收完数据才算成功
hadoop dfs -get in getin 从HDFS获取文件并且重新命名为getin,同put一样可操作文件也可操作目录
hadoop dfs -rmr out 删除指定文件从HDFS上
hadoop dfs -cat in/* 查看HDFS上in目录的内容
hadoop dfsadmin -report 查看HDFS的基本统计信息,结果如下
hadoop dfsadmin -safemode leave 退出安全模式
hadoop dfsadmin -safemode enter 进入安全模式
8.添加节点可扩展性是HDFS的一个重要特性,首先在新加的节点上安装hadoop,然后修改$HADOOP_HOME/conf/master文件,加入 NameNode主机名,然后在NameNode节点上修改$HADOOP_HOME/conf/slaves文件,加入新加节点主机名,再建立到新加节点无密码的SSH连接
运行启动命令:
start-all.sh
然后可以通过http://(Masternode的主机名):50070查看新添加的DataNode
9负载均衡start-balancer.sh,可以使DataNode节点上选择策略重新平衡DataNode上的数据块的分布


结束语:遇到问题时,先查看logs,很有帮助。

posted @ 2012-02-13 23:19 paulwong 阅读(5543) | 评论 (0)编辑 收藏

工作心得之二 业务

说到业务是个让人又爱又恨的东西,客户、领导把它看的很重,不少“技术控”却瞧不起它,认为它是“低智商”的代名词。当然了,这些看法都很偏激。技术仅仅是一个工具,因“业务”的需求而诞生至使用,小说里常常写到,当一个人学会了屠龙之术,却发现天地之间没有龙给他“屠”,这个是最悲惨的事情了,这里的“龙”就是业务,“屠龙之术”就是技术,离开了业务的技术是没有意义的。
业务本身是个抽象的集合,真正把它搞懂了其实也能锻炼人的抽象能力。
说来说去“业务”是个什么东西,似乎没有明确的定义,我觉得“业务”就是个“标准”,程序员完成的系统必须满足这个“标准”,不同行业,不同硬件环境都会有自己的合适的标准,某项技术都有其对应的“标准”。
比如一直讨论很久的问题,C++和Java到底谁快,为此也有衍生出了很多讨论,技术控也是乐此不疲,但是或多或少都脱离具体环境。
计算机语言发展了这么多年,都会相互学习优点,不过总有些本质的区别,比如C++的优势是和硬件结合紧密,Java的优势是屏蔽了硬件限制,两者在诞生的时候发展的方向就有不同,比如通信系统的交换机等各类硬件的程序非C/C++莫属,Java在这里难有使用的地方,但是在异构硬件集群中,现在很火的“云”系统,Java的优势就很明显,现在常用的服务器系统大多都是Java。当然也有人说Java免费,所以比C++更容易推广,的确没错,但是这也属于“业务”的范畴。
说完了业务的大范围,下面说说具体行业的业务。我最熟悉的是电信的业务。相比金融、电商系统,从网上的信息来看似乎电信的系统是最没技术含量的,其实电信的数据量远大于金融、电商,只是大量的数据是后台处理,可以异步展现,所以给的要求并不高,总体来说电信系统是入门的技术低,做好了很不容易。

我和不少电信的程序员人聊过,他们纷纷吐槽是,工作就是配置各种业务参数,体力活。但是说到具体的业务模型时,却说不清楚。

我总结的电信系统分2两大部分,业务模型(CRM)和工作流(IOM)。CRM和IOM是比较老的名词了,新的我也不太清楚。
模型如下:

主产品+子产品+产品规则+动作

解释如下:
主产品,和硬件挂钩。现在的电信产品有手机(移动,联通,电信分属不同网段)、固话、ADSL、光纤、2B+D、30B+D等。
子产品,依赖于主产品。比如移动电话的各种优惠包,宽带的互联星空等。
产品规则,这里是最让人抓狂的。产品规则分3类、
1、主产品规则,主产品之间是没有任何关系的,比如一家人可以装两条宽带,用多个手机。
2、子产品规则,基于不同主产品的子产品之间没有任何关系,基于同一主产品的子产品之间有各种规则,比如手机的资费包开通了一个就不能开通另一个,这类为互斥。不同的优惠可以共同作用,这类为叠加。由于各种子产品的数量繁多,所以这些规则的校验和实现是个很庞大的数字。
3、运营商制定的规则,比如,从硬件角度来说,装宽带、装电话、开通手机是互不相干的,但是运营商制定了各种套餐,“强迫”统一办理。这个无论是对程序员还是消费者都是是很讨厌的……
动作,装、拆,(改=装+拆)

分析完了以后可以发现真正麻烦的地方是业务规则这块,一个电信客户系统的质量高低很大程度上就由这个“业务规则引擎”决定,如果只是闷头往这个引擎里加参数的确无聊,但是这正了解这个引擎的工作步骤还是很有趣的,个人认为理解一个系统的运行是很容易提高能力的。

下面说说“工作流”,消费者的任何一个请求在电信系统中都会转变一个流程,某些特殊的业务流程会很长,比如装高清宽带,需要人上门施工,并测试宽带质量等,这些都成功了才会触发其它的步骤。消费者的业务请求在后端实现往往是“事务”型的,比如原来是套餐A,改成套餐B的会有3个步骤,不熟悉电信业务的人可以想下“神州行”改“全球通”。当步骤1和2施工成功后,步骤3发现现有条件不满足时(这里的判断不在当前系统中,或者说当前系统无法判断,必须将数据发送到另一个平台之后由那个平台来判断,这种情况在电信系统里很常见,比如当前系统没有客户资料,所以无法判断),也就意味着不能办理套餐B,这样得回复成套餐A,这样需要对步骤1和2得进行反向施工,也就是“事务回滚”。先后这就是“工作流”的任务。
工作流在电信系统中是很重要的角色,相比于是电商和金融系统,电信系统的工作流最强大。
简单解释下工作流,工作流有两个最基本单元(节点),逻辑节点和工作节点(不同的系统中叫法也不同,但是作用都一样)。
逻辑节点,就是if判断。
工作节点,就是一个具体的施工环节,一般关联一个平台。
一般工作流的具体配置都由这两种节点组成。

工作流定义的关系有,串行和并行(电信里的叫法是同进同退,一般直接定义成事务)。
于一个系统来说,业务层的调优效果优于代码层的调优效果(代码错误引起的宕机问题不属于调优范围)。比如,一个业务的判断规则精简了,比你优化几个计算语句强的多。比如之前说的例子,在步骤1、2、3中,因为3出了问题,导致1、2得反向施工,所以实际有5步操作,1、2、3、2反向、1反向。所以如果3最容易出问题,那么应该调整顺序应该是3、1、2,把最容易出问题的放在最开始,这样可以避免不必要的步骤。其实在系统上线后运行一段时间,就可以统计出那些平台的出错率高,调整顺序几乎是0修改,但是带来的效率提升是明显的,但是没有几个地方有这么做的。

说了这么多,我觉得把整个系统的框架搞明白还是很能提高个人能力,抽象逻辑对于程序员来说必不可少。所以现在每次抱怨工作无聊时,我都会想想,真的就不能挖出点东西么?

posted @ 2012-02-13 23:15 paulwong 阅读(234) | 评论 (0)编辑 收藏

工作心得之一 团队

转眼又是一年,也是我工作的第五个年头。一直想抽时间写点这几年的工作心得,但一直没时间,今天难得空闲,可以写点。这几年下来,我担任过很过角色,码农,组长,设计/架构等都有涉及,所以总结也分3部分:团队、业务、技术。今天先说说团队,估计有很多人也有想法,欢迎大家讨论。

俗话说,双全难敌四手,一个人再牛也比不了一个团队。

我在3家公司呆过,有国企也有外企,也和很多朋友聊天谈到不同的企业团队,发现不同企业的团队质量上的差距是很明显的。首先声明,这里仅仅是我对我所知的环境做个比较,并不针对哪些公司,更没有贬低谁的意思。

对于一个人来说,有一个好的团队就好象在社会里有个“家”,如果是一个坏的团队,那么就是一个“坑”。
为了提高开发效率,现在有越来越多的开发模式被提出来了,但是经常有人抱怨说采用敏捷开发模式,效率没一点上升,反而因为制定各种规则导致效率下降很多,提出这种模式的人只会扯淡。我想有这种抱怨的“管理者”应该很多吧,当然更多人都知道开发模式其实是很有效的手段,只是不知道怎么或者什么时候用它。其实老外在这方面觉得挺好,他们的工作流程是这样的,接到某个任务后,会分配到若干人员头上,那么这些人员就成了一个“临时”的团队,如果在大型公司里,这样是很常见的,网上有个词叫“内部外包”制,他们按照“敏捷”的模型/步骤完成任务。这样的团队有个特点是,团队中的人相互不熟悉,但是齐心,采用某些开发模式或者流程可以弥补因为陌生带来的问题,合理的安排每个人都任务,所以起到很好的效果。说到这里我觉得就够了,抱怨“开发模式”无用的团队的特点是,成员之间很熟悉,但是心不齐,这种情况什么模式都没用。不知道多少人有同感。
但是团队怎样才能真正的团结是个问题。这里就把一个团队可以分成底层的员工和上层的领导。
员工是每个人都起点,所以先从员工说起(当然有名爹的除外)。
作为员工,需要什么?
员工所需要的很简单,待遇 、发展平台 和 环境。前两者很好理解。
待遇,很多人明确就是有钱就干,没钱就滚蛋,的确钱很重要,但这个真不是全部,后面细说。
平台,关系到市场等等因素,比较明显,也没什么好说的。
至于环境这个就很抽象了,环境这里也分很多因素,最关键的一个是来自于领导,举个例子来说明,某个项目出了个问题,客户大发雷霆,公司领导屁颠屁颠跑来赔罪,然后很潇洒的在大酒店请客户吃了顿,摆平客户后回头很潇洒的把当事人骂一顿,当事人第二天潇洒的离职,然后就能看见很多人骂街……,估计很多人都有过这样或者看见过这样的场景。这是我觉得中国很多团队的最大问题,领导眼里一切都是“客户”至上,或许有些道理,但是如果把员工放轻了就很是问题。如果把客户看成“金矿”,那么员工就是“矿工”,诚然,客户是给钱的,但是这个过程得通过员工来完成,客户和员工对于“领导”来说应该是同等重要的,公司给客户的形象完全来自员工,绝不是领导请的那几顿饭。再说明白点,就是领导要给予员工起码的尊重,而不是使唤完了就结束,这样才能换来员工的忠诚。

下面说说“钱”的问题,我想说的是,钱不代表一切,钱只能解决一时的问题,但不可能长久,光是提高待遇的结果就是,员工越来越“贪”。
还是举个例子,美国做过实验,让一个人在独立的房间里,和外界无法联系,实验者在里面每呆一天就能获得很多报酬,我想这个实验大家都知道,结果是,没人撑得了1星期。把这个实验抽象一下,把你放在一个团队里,团队里的每个人都看不起你,鄙视你,无论给你多少钱,你也呆不久,当然毅力惊人的财迷除外……
对于一个团队来说,需要给员工一种感觉,“归属感”。说起来很抽象,那么还是举例子,想下我们大学毕业吃散伙饭那会,多少人哭的昏天黑地?那种感觉算是归属感。一起翘课,一起挂科,一起出丑等等等等,才让我们有了归属感。那么回到社会里来,怎么让一个团队有个归属感呢?这里得看“公司”和“领导”的本事了。

先从公司说起吧,这里得说个看似不相干的事。
中国古代有很多团队,比如戏班子,建筑队等,新加入的菜鸟都会有个专门的“师傅”带,这时,师傅不仅仅是传授技艺,还会在思想和情感上教育徒弟,所以古时有“一日为师,终身为父”的说法,这不仅仅是出于师长的尊重,很多时候“师傅”完全承担了“父亲”的角色。现在时代不同了,职场中很难找到推心置腹的人,逐渐演变成了干一份活拿一份钱。没错,看起来很公平,也是从资本主义那里学来的(但是只学了皮毛而已),造成结果就是让员工觉得自己仅仅是个机器,需要的时候租一下,不需要的时候随时给T掉。
其实在任何大企业里,员工在入职时都有员工培训,定期举行teambuilding,workshop,outing(我只在外企里享受过这些活动,具体解释也说不大清楚,简单来说就是游玩组织活动之类的)等,不少企业为了省钱,都免了,其实这些真的很重要。先说说国外的吧(是国外,不是外企在中国的分公司),最常见的方式有, 老板和大家一起喝啤酒,打桌球/高尔夫等。这样就可以创造一个员工相互交流的平台和时间,老板有更多时间来和员工交流,
现在在回想下我们的团队,一年都见不着老板几次面,也没几次聚会,动不动还扣点钱,这样的公司下面肯定是没好团队的,人员流动肯定大。部分大企业有各种活动,但是有的做的不好,比如年会就是包个大场地,大饭店,来几个表演,抽奖,大多数都是这样了吧,我也和同事聊过,感觉就是领导来自娱自乐一把,完全没员工的事,吃饱走人就行(抽奖?恩抽到最好,我是比较背的那种)。有多少领导真的是放下身价真的和员工进行互动?
估计“员工仅仅是个工具,和服务器这类机械没本质区别。”是那些老板的真实想法。

如果公司在大环境下创造不好,下面的团队很难发展好。

说完公司大环境就说说关系到自己的的团队。
任何一个团队都有个“老大”,我是一直这么称呼的,有点黑社会的味道,为什么呢?因为要做好一个领导,还真得和“古惑仔”电影中的“老大”学习。
1、尊重下属。真正的“尊重”才能换来他们的忠诚,当然他们会有不同理由离开团队,但是离开后还能是好朋友(有多少离职后是老死不通音信的?)。在中国(国外不清楚),大多数人(不是全部)都有“土皇帝”的情节,总觉得下属就是自己的“奴隶”,做什么都是应该的。到最后肯定是光杆司令。当然,员工之间也应该相互尊重,但员工间的矛盾对于团队来说是小问题。

2、公平。对于员工来说,公平分两层,一个是在员工之间,有些人和领导熟,承担的任务轻,反之则重,这个就不多说了,都清楚。另一层的公平是在员工和客户之间,有的时候明显是客户的错误,但是为了“效益”硬说成是员工的,或许这样的行为可以换来一时的利益,但是换个位置想想,一个人在你面前只会谄媚,脏水都往自己身上泼,你会瞧的起他么?时间长了客户不把你当人,员工也不把你当人,不知道你自己把自己当什么……

3、合理地护短,直接说清楚比较难,还得举个例子。当客户无论提出什么要求,如果领导都一字不落的转发,对于员工来说,有没有这个领导是没区别的,自然不理你。换个角度,当客户的任务过重时,如果领导能和客户交涉,为员工争取些权益,员工就会有一种“保护伞”的感觉,自然也就会依靠你。当然凡事得适当。

到这里是不是很像黑社会的老大?以上三点对于任何行业的团队都适用。

4、合理的薪资,这个又是焦点话题,老外定义的合理的薪资是基本工资够员工在当前城市生活,但是一定要有合理的奖励体系,有出色表现的时候要按时奖励,这个薪资体系是和销售的薪资构成很像(但细节和落实程度就有很大差别)。奖励体系是国外工资里很重要的一部分,国内虽然有各种绩效考核,结果到头来总是有什么预算不够,人员太多等等废话成了一纸空文。甚至演变成“拼爹”,反正在垄断行业里,出来问题,就T来T去,没爹的孩子就成了临时工。

在老外眼里奖励措施是很重要的,比惩罚措施更重要(中国做法只有责任落实到个人,出了问题一定得找个零时工出来……),为什么说奖励措施很重要呢?再举例子,在众多抱怨中,最多的是“我干了XXX事,他们不管,一时犯困就被罚”或者类似的。不可否认有对丑事选择性遗忘的的因素,但是领导对下属出色表现视而不见,但对错误严厉惩罚的做法是团队最大的“伤害”,这样给员工的感觉就是“干得好和干得一般”没区别,但是“犯错了就肯定会追究”,这样是最消磨员工的积极性和创造性的,所以很多人是做一天和尚撞一天钟。我和两个老外聊过,他们那里如果这个月干得好了,最高奖金是工资的4倍(最高,不是平均,他们所在的公司也是很不错的公司,那里也不是所有企业有这么好的奖励),所以人人会主动找事干,每周一次的聚会都会找老板展露自己的“成果”。国内企业也有奖励制度,但首先那种奖励程度实在不值一提,其次,员工有方便的通道来告诉领导么,领导知道了会重视么?

提高产品的效率、质量必须从团队开始。我见过的最好团队,6个人合作了4年,5个员工+1老大。每次任务下来后,“老大”不需要多废话话,每个人就知道自己负责哪块,老大只需要和客户扯皮,也基本不需要担心哪个人跳槽,员工郁闷了就喊老大去喝啤酒。这个团队也没什么开发模式,更没什么规章制度。

最后,希望大家在新年里都能找到自己的团队。

posted @ 2012-02-13 23:08 paulwong 阅读(240) | 评论 (0)编辑 收藏

管理随笔

项目管理说到底就是人的管理,这是我在项目管理中意识到的几个关注点。

1. 规则制定。 没有规矩,不成方圆,军队没有纪律就是一盘散沙,做项目亦如此。各个公司甚至项目都有自己不同的规则,规则的存在是为了约束成员的行为,鼓励对团队发展有利的行为,减少对团队发展有害的行为。同时规则的制定需要人性化。这里举个例子,我公司并不要求员工按时上班,也无上班打卡。于是项目经理在上班时间在办公室看不到几个人,有些事情想当面跟某成员说都要先跟成员预约时间。项目进度不紧,任务也不重,做的按部就班,并无大的出错。因为很多人不来,经常来的几个人也开始来的少了,这样的规则有无问题?

这样的规则就造成了一个现象:办公室里一个人都没了。同时由于沟通的时间越来越少,项目本来可以做得更好的但是现在只是没有出大的差错而已。懒人更懒,积极上进的人积极性也大受打击,热情降低。本来可以集中办公的,现在变成虚拟团队了。

规则的制定既需要限制成员的自由,又要给成员最大的自由,所有的规则制定的出发点只有一个:团队发展。第一条,对团队发展有坏的影响的规则都不是好规则。然后才是第二条,规则需要人性化。第三,规则的合理有效性。

上面的例子,如果改为: 上班不打卡,但是员工需要每天到公司上班,如果某天因为有事来不了在不影响项目的前提下需要提前一天通知项目经理,一个月不来的次数不能超过5次。早上上班时间可以定为10:00,10点还迟到的次数一个月不能超过10次。不过这需要增加有一个人来记录。



2. 赏罚分明。不论是好规则还是坏规则,有规则就要执行,就会有人经常违反,有人经常遵守,就会有赏有罚。赏罚分明的好处,就是要让大家知道,干得好和干得坏的待遇不一样。比如上面的新的上班规则,如果有人违反了,怎么办?如果是你的得力下属违反了,怎么办?甚至于如果是你自己违反了,怎么办?如果因为你跟某个成员私交很好,就酌情处理,那你的后门以后会被踏平,大家都会来努力跟你搞好关系,项目没人做了。如果拉不下面子,不妨自己故意违反一次,然后按规定处罚自己。

当然,罚只能是一种手段,罚不能常用,应该常用的是赏。项目经理一定要有能力拿到经费,哪怕很少。赏不能自己掏腰包对吧? 总之,做好做坏一定要不一样,而且最好马上就能不一样,而不是体现到年终的绩效考核上,那太远了。


那上面的规则就可以进一步变成: 一个月迟到10次口头警告,团队里面通报。天天天迟到(20次)则通告上级经理,扣季度奖金xxx。一个月不来次数超过5次,口头警告,团队里面通报。一个月不来次数超过10次,则通告上级经理,劝退xxx。一个月无迟到,无缺勤则拿全勤奖,xxxx。

如果有人下午四点钟来,五点钟走,怎么办?呵呵,这样的人很少吧?有也是奇葩,那你就再修订规则吧。

3. 沟通和社交风格,迎合能力。
沟通是个大话题,项目中项目经理75%以上的时间用于沟通。。。

posted @ 2012-02-13 22:25 paulwong 阅读(232) | 评论 (0)编辑 收藏

JBOSS集群安装

软件及环境:
jboss-5.1.0.GA
nginx-0.8.15
centos5.5
nginx:192.168.1.251
tomat1:192.168.1.251
tomat2:192.168.1.252
jboss安装目录为:/usr/local/jboss
nginx安装目录为:/usr/local/nginx

JDK、JBOSS、nginx安装略过!

Jboss1配置:

/opt/jboss4.3/jboss-as/server/node2/deploy/jboss-web.deployer/server.xml

<!--由于在LINUX环境下,会有多个IP,address不能改成${0.0.0.0},这样会对127.0.0.1也会进行监听,导致启动出错-->
<Connector protocol="HTTP/1.1" port="8080" address="${ jboss.bind.address}">

<!--将<Engine name="jboss.web" defaultHost="localhost">修改为-->
<Engine name="jboss.web" defaultHost="localhost" jvmRoute="jboss1">

/opt/jboss4.3/jboss-as/server/node2/deploy/jboss-messaging.sar/messaging-service.xml
<!--将20行的<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:0}</attribute>修改-->
<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:1}</attribute>

Jboss2配置:

/opt/jboss4.3/jboss-as/server/node2/deploy/jboss-web.deployer/server.xml

<!--由于在LINUX环境下,会有多个IP,address不能改成${0.0.0.0},这样会对127.0.0.1也会进行监听,导致启动出错-->
<Connector protocol="HTTP/1.1" port="8080" address="${ jboss.bind.address}">

<!--将<Engine name="jboss.web" defaultHost="localhost">修改为-->
<Engine name="jboss.web" defaultHost="localhost" jvmRoute="jboss2">

/opt/jboss4.3/jboss-as/server/node2/deploy/jboss-messaging.sar/messaging-service.xml
<!--将20行的<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:0}</attribute>修改-->
<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:2}</attribute>

如果想要session同步的话,要在站点的web.xml里面加入<distributable/>

测试文件index.jsp内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding
="UTF-8"%>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
<%@page import="java.util.*"%>
 
<%@page import="java.net.InetAddress;"%>
 
<html>
 
<head>
 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
<title>Cluster App Test</title>
 
</head>
 
<body>
 
<%
 InetAddress ip 
= InetAddress.getLocalHost();
 
//out.println(ip.getHostAddress());
 
%>
 This is responsed by 
<font color="red"> <%=ip.getHostAddress() %></font><br>
 Host Name : 
<font color="red"><%=ip.getHostName() %></font><br>
 Time : 
<font color="red"><%=new Date() %></font><br>
 
<%
 ip 
= null;
 
%>
<br/> <br/> <br/> <br/>
Server Info:
<%
out.println(request.getLocalAddr() 
+ " : " + request.getLocalPort()+"<br>");%>
<%
  out.println(
"<br>Session ID " + session.getId()+"<br>");
 
// 如果有新的 Session 属性设置
 
String dataName = request.getParameter("dataName");
 
if (dataName != null && dataName.length() > 0) {
    
String dataValue = request.getParameter("dataValue");
     session.setAttribute(dataName, dataValue);
  }
  out.print(
"<br/> <b>Session 列表</b>");
  Enumeration e 
= session.getAttributeNames();
 
while (e.hasMoreElements()) {
    
String name = (String)e.nextElement();
    
String value = session.getAttribute(name).toString();
     out.println( name 
+ " = " + value+"<br>");
         System.out.println( name 
+ " = " + value);
   }
%>
 
<form action="index.jsp" method="POST">
    名称:
<input type=text size=20 name="dataName">
    
<br>
   
&nbsp;&nbsp;值:<input type=text size=20 name="dataValue">
    
<br>
   
<input type=submit>
  
</form>
 
</body>
 
</html>

Jboss动好像没什么要求,,可以两个同时启动,等启动完之后再启动NGINX就OK了!

Jboss的启动命令为(必须加参数-b ,很多配置文件都依赖于${ jboss.bind.address}这个值,也就是命令行输入的IP地址):
/usr/local/jboss/bin/run.sh -c all -b 192.168.1.251


等都启动完成,就可以防问http://192.168.1.251/cluster-test/

写一个session,刷新,如果session在不同的机器上保持不变,那就集成功了!如下图:

posted @ 2012-02-13 16:18 paulwong 阅读(1982) | 评论 (0)编辑 收藏

jboss中控制台jmx-console 登录的用户名和密码设置

默认情况访问 http://localhost:8080/jmx-console 就可以浏览jboss的部署管理的一些信息,不需要输入用户名和密码,使用起来有点安全隐患。下面我们针对此问题对jboss进行配置,使得访问jmx- console也必须要知道用户名和密码才可进去访问。步骤如下:

i) 找到JBoss安装目录/server/default/deploy/jmx-console.war/WEB-INF/jboss-web.xml文 件,去掉<security-domain>java:/jaas/jmx-console</security- domain>的注释。修改后的该文件内容为:

<jboss-web>
   
<!-- Uncomment the security-domain to enable security. You will
      need to edit the htmladaptor login configuration to setup the
      login modules used to authentication users.
-->
      
<security-domain>java:/jaas/jmx-console</security-domain>
</jboss-web>


ii)修改与i)中的jboss-web.xml同级目录下的web.xml文件,查找到<security-constraint/>节点,去掉它的注释,修改后该部分内容为:

<!-- A security constraint that restricts access to the HTML JMX console
   to users with the role JBossAdmin. Edit the roles to what you want and
   uncomment the WEB-INF/jboss-web.xml/security-domain element to enable
   secured access to the HTML JMX console.
-->
   
<security-constraint>
     
<web-resource-collection>
       
<web-resource-name>HtmlAdaptor</web-resource-name>
       
<description>An example security config that only allows users with the
         role JBossAdmin to access the HTML JMX console web application
       
</description>
       
<url-pattern>/*</url-pattern>
       
<http-method>GET</http-method>
       
<http-method>POST</http-method>
     
</web-resource-collection>
     
<auth-constraint>
       
<role-name>JBossAdmin</role-name>
     
</auth-constraint>
   
</security-constraint>

   在此处可以看出,为登录配置了角色JBossAdmin。

iii) 在第一步中的jmx-console安全域和第二步中的运行角色JBossAdmin都是在login-config.xml中配置,我们在JBoss安 装目录/server/default/conf下找到它。查找名字为:jmx-console的application-policy:

<application-policy name = "jmx-console">
       
<authentication>
          
<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
             flag 
= "required">
           
<module-option name="usersProperties">props/jmx-console-users.properties</module-option>
           
<module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
          
</login-module>
       
</authentication>
    
</application-policy>


在此处可以看出,登录的角色、用户等的信息分别在props目录下的jmx-console-roles.properties和jmx-console-users.properties文件中设置,分别打开这两个文件。
其中jmx-console-users.properties文件的内容如下:

# A sample users.properties file for use with the UsersRolesLoginModule
admin
=admin

该文件定义的格式为:用户名=密码,在该文件中,默认定义了一个用户名为admin,密码也为admin的用户,读者可将其改成所需的用户名和密码。
jmx-console-roles.properties的内容如下:

# A sample roles.properties file for use with the UsersRolesLoginModule
admin
=JBossAdmin, HttpInvoker

该文件定义的格式为:用户名=角色,多个角色以“,”隔开,该文件默认为admin用户定义了JBossAdmin和HttpInvoker这两个角色。
配置完成后读者可以通过访问: http://localhost:8088/jmx-console/ ,输入jmx-console-roles.properties文件中定义的用户名和密码,访问jmx-console的页面。

posted @ 2012-02-13 11:04 paulwong 阅读(9542) | 评论 (0)编辑 收藏

一个完整的JENKINS下的ANT BUILD.XML文件

     摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><?xml version="1.0" encoding="UTF-8"?><project name="genwar" default="all...  阅读全文

posted @ 2012-02-08 18:40 paulwong 阅读(5738) | 评论 (1)编辑 收藏

Linux SHELL环境初始化顺序总结

以ubuntu server 11.10 为例,

1) 当服务器启动时,SHELL环境的初始化过程如下:

/etc/environment –> /etc/default/ 中的配置脚本

2)当一个用户登录SHELL的时候

/etc/profile --> $HOME/.profile

如果是BASH SHELL , 则是

/etc/profile –> /etc/bash.bashrc --> $HOME/.profile --> $HOME/.bashrc

3) 如果一个用户打开一个BASH SHELL 或 使用su 切换用户身份时, 则

/etc/bash.bashrc –> $HOME/.bashrc

其中:

/etc/environment 设置全局环境变量, 重启服务器生效

/etc/default/目录中的配置脚本 设置特定的全局环境变量

/etc/profile 当用户重新登录时,该文件被执行. 并依次调用/etc/profile.d目录中的所有脚本。如果是初始化BASH SHELL , 还会调用/etc/bash.bashrc

/etc/bash.bashrc 每次启动一个BASH SHELL时都会执行该脚本

$HOME/.profile 作用等同/etc/profile

$HOME/.bashrc 作用等同/etc/bash.bashrc

$HOME/.bash_logout 当每次退出SHELL环境时被执行

posted @ 2012-02-08 13:00 paulwong 阅读(616) | 评论 (0)编辑 收藏

JENKINS使用步骤

从代码仓库获取代码用SVN,做单元测试用JUNIT,做代码检查用PMD、FINDBUGS,代码编译、打包用ANT,拷贝文件到部署服务器上用SHELL,出现BUG了通知开发人员要发EMAIL,工具一多了,整合起来用时,不断切换界面,输入命令的复杂性可想而知,有没有一站式的工具可以代劳呢?

有,这就是JENKINS,有了她,你就可以:通过统一的WEB界面做各种配置工作、查看工具的LOG输出、即使是历史的日志查看也没问题;通知配置排程,可以自动的获取代码、编译、打包和部署,发邮件,无须人工干预。
  1. 安装JENKINS,其实就是把一个WAR包放到容器中
  2. 安装插件:发邮件插件Jenkins Email Extension Plugin和部署插件Deploy to container Plugin
  3. 配置JDK和邮件服务器地址
  4. 新建任务:配置SVN地址/配置构建排程@hourly/配置构建步骤,如先用ANT编译打包再传到服务器/配置成功或失败后发邮件通知的地址
  5. 手动执行任务或等待时间到了后执行任务
各种插件的安装
  1. ANT:如果在JENKINS中使用了ANT-JUNIT,由于JENKINS是直接调用操作系统的ANT命令的,所以要在LINUX下安装ANT,配置ANT_HOME,并将BIN加入到PATH中:
    ANT_HOME=/opt/ant/apache-ant-1.8.2
    JAVA_HOME
    =/usr/java/jdk1.6.0_29
    JRE_HOME
    =/usr/java/jdk1.6.0_29/jre
    PATH
    =$ANT_HOME/bin:$JAVA_HOME/bin:JRE_HOME/bin:$PATH 
    CLASSPATH
    =.:$JAVA_HOME/lib/jt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
    export ANT_HOME JAVA_HOME JRE_HOME PATH CLASSPATH

http://hanqunfeng.iteye.com/category/138233

posted @ 2012-01-31 18:19 paulwong 阅读(8731) | 评论 (0)编辑 收藏

仅列出标题
共112页: First 上一页 85 86 87 88 89 90 91 92 93 下一页 Last