显示可用数据库 show databases;
显示表索引 show keys from TABLE_NAME;
显示表信息 show table status like 'TABLE_NAME';
授权 grant all priviledges on DB_NAME.* to 'USER_NAME'@'%' identified by 'PASSWORD' with grant option.
创建数据库 create database DB_NAME charact set utf8
创建表 carate table (...) type=INNODB
查看当前连接数 show processlist
查看服务器状态 show status
Thursday, September 11, 2008
Ubuntu/Window shell实用技巧
LINUX ------------------------------------
查找包含特定文本的文件:
grep -e *.log -R xplanner/ (在xplanner目录下查找所有包含.log字串的文件, -e表示使用pattern查询)
grep -F xplanner.log -R xplanner/ --line-number (在xplanner下查找包含固定字串xplanner.log的文件,并且显示行号)
查找文件
find /home --name cruisecontrol.sh (在/home目录包含子目录下查找cruisecontrol.sh)
查看dpkg将安装包安装到什么地方了
dpkg -L mysql-server (列出mysql-server包被安装到系统什么地方了)
dpkg -l 列出所有安装的包
>>为脚本传入参数
$1表示传入的第一个参数,$2表示第二个...$@表示传入的所有参数,$0表示脚本自己的名称。
>>Vi的十六进制编辑模式
WINDOW ------------------------------------
查找包含特定文本的文件:
grep -e *.log -R xplanner/ (在xplanner目录下查找所有包含.log字串的文件, -e表示使用pattern查询)
grep -F xplanner.log -R xplanner/ --line-number (在xplanner下查找包含固定字串xplanner.log的文件,并且显示行号)
查找文件
find /home --name cruisecontrol.sh (在/home目录包含子目录下查找cruisecontrol.sh)
查看dpkg将安装包安装到什么地方了
dpkg -L mysql-server (列出mysql-server包被安装到系统什么地方了)
dpkg -l 列出所有安装的包
>>为脚本传入参数
$1表示传入的第一个参数,$2表示第二个...$@表示传入的所有参数,$0表示脚本自己的名称。
>>Vi的十六进制编辑模式
首先以二进制方式编辑这个文件:vim -b datafile
现在用 xxd 把这个文件转换成十六进制::%!xxd
最后, 用下面的命令把它转换回来::%!xxd -
WINDOW ------------------------------------
Friday, August 29, 2008
如何部署高可用性和高伸缩性的网站?
如何部署高可用性和高可伸缩性的网站?这是一个很复杂的问题,到目前为止,我还没有实际的经验,都是自己学习和思考得到的一点结果。
前段时间,长沙一个公司做了一个彩票投注的网站,上海那边的公司就想直接拿过去用,不想再重新开发一套系统。问题是开发人员多数都有一个毛病,认为别人做的不如自己做的,上海就有这样一个,他说给我一个月时间,我就可以做出比这个更好的网站。除去有关业务有关市场的东西不谈,这位兄弟说的话的确很难让人相信,业务人员不信,我觉得他更是没弄明白部署一个生产的网站所包含的工作,显然,他认为,部署一个网站就是写完代码,然后copy到服务器上就可以了。 事情比他想象的复杂的多,如果这个网站是一个intranet的应用,可能还好说些,但是这是一个面向彩民的网站,实现一年销售2亿的网站,在部署这样一个网站的时候,可用性和伸缩性是不能不考虑的问题。在最终得到的生产环境中,网站代码可能只是很小的一部分, 你需要集群,需要cache,需要分部文件系统dfs,需要负载均衡,需要数据库集群,以及配套的一对硬件,要把这些理清楚,如果只懂java,jsp是远远不够的。
我没有实际参与部署过这种为海量用户服务的网站,心里很忐忑,一旦我们运营的网站出现这样那样 的问题怎么办? 所幸找到了一个很好的案例,这个案例不仅仅是从软件设计上说如何支持可伸缩性,而是完整的介绍了整个网站的部署,它就是livejournal,一个很早开始blog服务的网站,这是一个有8百多万用户,每秒处理2000次点击的网站。
开发livejournal的这群人值得称赞,他们分享了网站开发和部署过程中的很多心得,并且开源了他们自己开发的很多支持网站运营的工具,其中最著名的大概就应该是memcache了,这个cache系统已经在很多大型网站得到了应用,可以从这里下载他们的一个演示文档。下面按照整个部署涉及到的环节说说我的体会。
1.perlbal
一个livejournal自己开发的reverse proxy,用来进行负载均衡(big-ip好象也是用来做负载均衡,但是没搞清楚和perlbal的关系)
2. mogilefs
一个livejournal自己开发的分布式文件系统(DFS, distributed file system),分布式文件系统又包括一些不同的类型,主要是看他们解决的问题,有的用来支持高并发任务,有的使用来支持高可用性,而mofilefs是同时支持高并发和高可用性两个特性,而且支持任何本地文件系统。 问题是为什么我们要用分布式文件系统??它应该是用来处理系统产生的数据文件,最直观的大概就是系统生成的日志了,在集群环境下,如果没有dfs,那么每台主机都会产生单独的分离的日志文件,如果采用dfs,那么所有集群中的应用可以向同一个文件输出日志,而且便于维护。(老实说,这个我没有弄太清楚)
dfs与raid的关系也需要提一下,一般来说raid只是硬盘的阵列,如果部署raid的主机崩溃,那么raid也没用了,除非是有san(store area networ)支持的raid,可以跨主机。 而dfs由于本身是分布式的,是跨主机的,不存在这个问题。
3. web server cluster
这个集群是基本的,相信了解集群的人都应该知道web server的集群是最基本的
4. memcache
一个livejournal开发的分布式缓存系统,目前的应用非常广泛,可以在多台主机启动多个memcache服务,它们会自动协作,对应用程序来说就好象只有一个memcache服务。可以存储任何形式的内容(需要做深入研究)
但是对什么内容进行缓存呢?
首先要是被经常读取的内容,而这些内容可以通过查看数据库的日志,比如那些对象查询的最多等等。mysql提供了slow log的功能。
5. mysql cluster
数据库集群这块是对我影响最大的。以前一直认为是要采用大型数据库的本身支持的集群(想来应该非常昂贵),不然是实在想不出还有什么集群方式,而且既然有数据库集群,那么前面是不是也要有一个load balancer? 不过这个load balancer应该是数据库服务器本身提供,就相当于有一个逻辑数据库,应用程序面向的是这个逻辑数据库,不需要知道后端的集群有多少数据库实例,这个逻辑数据库负责组装数据,分布请求,负载均衡。。。不过,这的确应该是一个昂贵的解决方案。
后来,了解了sharding,是一种数据库分区的概念,包含水平和垂直两种shard方式(集群也包括水平和垂直两种,垂直的就是单个应用,但是起先是运行在普通的web server中,后来是运行在小型机中,而水平集群就是采用便宜的web server阵列,每个主机都部署一个应用),水平就是将一个表的列进行拆分,可能数据量大的,或者不经常使用的列拆分到一个独立的表; 垂直就是按照一个规则将表中的数据进行分区,避免一个表中的数据过大,常见的是用户表(user),比如规则是按照id的奇偶来决定将user存入哪个表,那么可能在数据库中就存在usre_odd, user_even两个表,它们的表模式一模一样,但是一个用来保存id为奇数的用户,一个用来保存id为偶数的用户。shard需要进行额外的编码,但是会带来巨大的性能提升。
一般来说采用sharding就可以不用昂贵的数据库集群方案,而且后来想到的一个问题是,数据库服务器一般会采用raid,raid本身就提供了高速的io,以及数据冗余,所以我更加倾向与raid+sharding的方案了。
当时livejournal的方案显然更复杂,除了sharding之外,mysql也做了集群,并且每个用户组都有一个数据库集群,想来只有存在海量用户的系统需要这样,实在很壮观阿。 但是从它讨论的master-salve这种数据库集群方式中,我又想通了不少问题,所以在我原来raid+sharding的方案上,我又增加一个slave,也做一个数据库集群,但是slave不一定需要raid,看具体的应用,我是想在进行统计报表的时候就可以使用slave的数据,而不需要访问master,master处理在线数据,提供实时服务,嘿嘿。。。。如果slave也需要处理在线作业,那么也可以在slave上配置raid, 当然也可以象livejournal一样,master提供读写,而slave只提供读。
数据库这库学问太深,还有很多其他的方面,我也只想了这么多,想到哪里写到哪里。。。
参考资料:
Django Master Class: http://toys.jacobian.org/presentations/2007/oscon/tutorial/
Database sharding unraveled: http://lifescaler.com/2008/04/database-sharding-unraveled-part-i/
Scalability Best Practices: Lessons from eBay: http://www.infoq.com/articles/ebay-scalability-best-practices
Scaling Your Java EE Applications: http://www.theserverside.com/tt/articles/article.tss?l=ScalingYourJavaEEApplications
前段时间,长沙一个公司做了一个彩票投注的网站,上海那边的公司就想直接拿过去用,不想再重新开发一套系统。问题是开发人员多数都有一个毛病,认为别人做的不如自己做的,上海就有这样一个,他说给我一个月时间,我就可以做出比这个更好的网站。除去有关业务有关市场的东西不谈,这位兄弟说的话的确很难让人相信,业务人员不信,我觉得他更是没弄明白部署一个生产的网站所包含的工作,显然,他认为,部署一个网站就是写完代码,然后copy到服务器上就可以了。 事情比他想象的复杂的多,如果这个网站是一个intranet的应用,可能还好说些,但是这是一个面向彩民的网站,实现一年销售2亿的网站,在部署这样一个网站的时候,可用性和伸缩性是不能不考虑的问题。在最终得到的生产环境中,网站代码可能只是很小的一部分, 你需要集群,需要cache,需要分部文件系统dfs,需要负载均衡,需要数据库集群,以及配套的一对硬件,要把这些理清楚,如果只懂java,jsp是远远不够的。
我没有实际参与部署过这种为海量用户服务的网站,心里很忐忑,一旦我们运营的网站出现这样那样 的问题怎么办? 所幸找到了一个很好的案例,这个案例不仅仅是从软件设计上说如何支持可伸缩性,而是完整的介绍了整个网站的部署,它就是livejournal,一个很早开始blog服务的网站,这是一个有8百多万用户,每秒处理2000次点击的网站。
开发livejournal的这群人值得称赞,他们分享了网站开发和部署过程中的很多心得,并且开源了他们自己开发的很多支持网站运营的工具,其中最著名的大概就应该是memcache了,这个cache系统已经在很多大型网站得到了应用,可以从这里下载他们的一个演示文档。下面按照整个部署涉及到的环节说说我的体会。
1.perlbal
一个livejournal自己开发的reverse proxy,用来进行负载均衡(big-ip好象也是用来做负载均衡,但是没搞清楚和perlbal的关系)
2. mogilefs
一个livejournal自己开发的分布式文件系统(DFS, distributed file system),分布式文件系统又包括一些不同的类型,主要是看他们解决的问题,有的用来支持高并发任务,有的使用来支持高可用性,而mofilefs是同时支持高并发和高可用性两个特性,而且支持任何本地文件系统。 问题是为什么我们要用分布式文件系统??它应该是用来处理系统产生的数据文件,最直观的大概就是系统生成的日志了,在集群环境下,如果没有dfs,那么每台主机都会产生单独的分离的日志文件,如果采用dfs,那么所有集群中的应用可以向同一个文件输出日志,而且便于维护。(老实说,这个我没有弄太清楚)
dfs与raid的关系也需要提一下,一般来说raid只是硬盘的阵列,如果部署raid的主机崩溃,那么raid也没用了,除非是有san(store area networ)支持的raid,可以跨主机。 而dfs由于本身是分布式的,是跨主机的,不存在这个问题。
3. web server cluster
这个集群是基本的,相信了解集群的人都应该知道web server的集群是最基本的
4. memcache
一个livejournal开发的分布式缓存系统,目前的应用非常广泛,可以在多台主机启动多个memcache服务,它们会自动协作,对应用程序来说就好象只有一个memcache服务。可以存储任何形式的内容(需要做深入研究)
但是对什么内容进行缓存呢?
首先要是被经常读取的内容,而这些内容可以通过查看数据库的日志,比如那些对象查询的最多等等。mysql提供了slow log的功能。
5. mysql cluster
数据库集群这块是对我影响最大的。以前一直认为是要采用大型数据库的本身支持的集群(想来应该非常昂贵),不然是实在想不出还有什么集群方式,而且既然有数据库集群,那么前面是不是也要有一个load balancer? 不过这个load balancer应该是数据库服务器本身提供,就相当于有一个逻辑数据库,应用程序面向的是这个逻辑数据库,不需要知道后端的集群有多少数据库实例,这个逻辑数据库负责组装数据,分布请求,负载均衡。。。不过,这的确应该是一个昂贵的解决方案。
后来,了解了sharding,是一种数据库分区的概念,包含水平和垂直两种shard方式(集群也包括水平和垂直两种,垂直的就是单个应用,但是起先是运行在普通的web server中,后来是运行在小型机中,而水平集群就是采用便宜的web server阵列,每个主机都部署一个应用),水平就是将一个表的列进行拆分,可能数据量大的,或者不经常使用的列拆分到一个独立的表; 垂直就是按照一个规则将表中的数据进行分区,避免一个表中的数据过大,常见的是用户表(user),比如规则是按照id的奇偶来决定将user存入哪个表,那么可能在数据库中就存在usre_odd, user_even两个表,它们的表模式一模一样,但是一个用来保存id为奇数的用户,一个用来保存id为偶数的用户。shard需要进行额外的编码,但是会带来巨大的性能提升。
一般来说采用sharding就可以不用昂贵的数据库集群方案,而且后来想到的一个问题是,数据库服务器一般会采用raid,raid本身就提供了高速的io,以及数据冗余,所以我更加倾向与raid+sharding的方案了。
当时livejournal的方案显然更复杂,除了sharding之外,mysql也做了集群,并且每个用户组都有一个数据库集群,想来只有存在海量用户的系统需要这样,实在很壮观阿。 但是从它讨论的master-salve这种数据库集群方式中,我又想通了不少问题,所以在我原来raid+sharding的方案上,我又增加一个slave,也做一个数据库集群,但是slave不一定需要raid,看具体的应用,我是想在进行统计报表的时候就可以使用slave的数据,而不需要访问master,master处理在线数据,提供实时服务,嘿嘿。。。。如果slave也需要处理在线作业,那么也可以在slave上配置raid, 当然也可以象livejournal一样,master提供读写,而slave只提供读。
数据库这库学问太深,还有很多其他的方面,我也只想了这么多,想到哪里写到哪里。。。
参考资料:
Django Master Class: http://toys.jacobian.org/presentations/2007/oscon/tutorial/
Database sharding unraveled: http://lifescaler.com/2008/04/database-sharding-unraveled-part-i/
Scalability Best Practices: Lessons from eBay: http://www.infoq.com/articles/ebay-scalability-best-practices
Scaling Your Java EE Applications: http://www.theserverside.com/tt/articles/article.tss?l=ScalingYourJavaEEApplications
Wednesday, July 09, 2008
什么是好的构建工具?
从我开始接触到linux的时候,我就知道一个叫做makefile的东西,不过从来不敢改,不敢动,因为对linux不熟悉,对c语言不熟悉。后来据说因为makefile对平台依赖性太强,又除了一个autoconfig,那些都是linux+c的东西。
再到后来就是ant了,很多项目中也都采用了ant,非常灵活,可以说只有想不到没有做不到。但是也的确存在一个问题,在大型项目中,维护ant的构建脚本本身也会变成一个沉重的负担,需要有专门的人来负责。我曾经在一个erp公司做过,其中包含很多子项目,ant脚本到处都是,而且彼此引用,光是看那些脚本,就看到的我目瞪口呆:ant这么强大,ant这么复杂。
没有在具体的项目中应用过maven,只是想要看看为什么有了ant,人们还需要maven。 ant和maven在某种意义上是两个完全相反的东西,你可以随心所以的使用ant,编写各种插件,脚本,让它来适应你的习惯,你的哲学,但是maven,如果你想要舒服的使用maven,最好就是适应它的哲学,适应它的习惯,不然,可能不是那么好驾驭。 maven一个很重要的哲学就是‘惯例比配置更重要’,我很赞同,使用惯例我们可以减少大量的配置文件,也就减少大量的脚本,减少维护的工作。 此外,maven标准化了项目的构建工作,的确,几乎所有的项目都包含这样一个构建流程:编译,测试,打包,部署。 在ant中,每个项目都需要从头开始(其实不一定,我在使用ant的时候就借鉴了interface的思想,定义了一些标准的target,保证所有的项目这些都有同样的ant target,完成同样的任务,虽然实现可以不一样。。。。毕竟,这不是工具本身支持的,需要人们手工来做,需要相关人员的理解,共识)。
对maven还不是太熟悉,但是觉得不如ant那么容易上手,pom的结构太复杂,也有可能导致一大堆xml配置文件。 maven有一个完美的思想和比较蹩脚的实现,maven1出来的时候大受好评,但是等到maven2,人们开始越来越多的抱怨它。 mavne的依赖管理是先对于ant最出色的特性(现在ant可以和ivy接合来实现包的依赖管理),但是现在看来人们正是对这块不满意,不是说包依赖管理不好,而是这个功能实现的不好,经常会导致构建的失败。人们可能莫名其妙的发现,上一次好好好的成功的构建,在没有人们变动的情况下,怎么现在就构建失败了,其实很可能是包仓库中某个依赖变化了,而修正这个问题据说是一场噩梦。
maven是比ant更高级的构建工具,虽然有那么多问题,但是目前来看,maven还是首选,至少最流行的spring项目就是采用maven构建的。
此外,有一个ruby开发的java项目构建工具,名字叫buildr,也成为了apache的incubutor项目,但是对于很多java开发人员来讲,部署一个ruby应用可能不是那么简单,其他远不如copy一份ant或者maven那么简单。
再到后来就是ant了,很多项目中也都采用了ant,非常灵活,可以说只有想不到没有做不到。但是也的确存在一个问题,在大型项目中,维护ant的构建脚本本身也会变成一个沉重的负担,需要有专门的人来负责。我曾经在一个erp公司做过,其中包含很多子项目,ant脚本到处都是,而且彼此引用,光是看那些脚本,就看到的我目瞪口呆:ant这么强大,ant这么复杂。
没有在具体的项目中应用过maven,只是想要看看为什么有了ant,人们还需要maven。 ant和maven在某种意义上是两个完全相反的东西,你可以随心所以的使用ant,编写各种插件,脚本,让它来适应你的习惯,你的哲学,但是maven,如果你想要舒服的使用maven,最好就是适应它的哲学,适应它的习惯,不然,可能不是那么好驾驭。 maven一个很重要的哲学就是‘惯例比配置更重要’,我很赞同,使用惯例我们可以减少大量的配置文件,也就减少大量的脚本,减少维护的工作。 此外,maven标准化了项目的构建工作,的确,几乎所有的项目都包含这样一个构建流程:编译,测试,打包,部署。 在ant中,每个项目都需要从头开始(其实不一定,我在使用ant的时候就借鉴了interface的思想,定义了一些标准的target,保证所有的项目这些都有同样的ant target,完成同样的任务,虽然实现可以不一样。。。。毕竟,这不是工具本身支持的,需要人们手工来做,需要相关人员的理解,共识)。
对maven还不是太熟悉,但是觉得不如ant那么容易上手,pom的结构太复杂,也有可能导致一大堆xml配置文件。 maven有一个完美的思想和比较蹩脚的实现,maven1出来的时候大受好评,但是等到maven2,人们开始越来越多的抱怨它。 mavne的依赖管理是先对于ant最出色的特性(现在ant可以和ivy接合来实现包的依赖管理),但是现在看来人们正是对这块不满意,不是说包依赖管理不好,而是这个功能实现的不好,经常会导致构建的失败。人们可能莫名其妙的发现,上一次好好好的成功的构建,在没有人们变动的情况下,怎么现在就构建失败了,其实很可能是包仓库中某个依赖变化了,而修正这个问题据说是一场噩梦。
maven是比ant更高级的构建工具,虽然有那么多问题,但是目前来看,maven还是首选,至少最流行的spring项目就是采用maven构建的。
此外,有一个ruby开发的java项目构建工具,名字叫buildr,也成为了apache的incubutor项目,但是对于很多java开发人员来讲,部署一个ruby应用可能不是那么简单,其他远不如copy一份ant或者maven那么简单。
使用diff和patch来制作补丁
首先说明使用diff和patch一般使用来处理文本文件的,对于开源项目,这两个工具是很好的帮手,比如linux的内核发布就包含很多patch,这样你不用每次都下载完整的源代码包,只需要下载目标版本和你已有版本之间的patch。
我会通过一个实际的操作示例来说明这两个工具的使用。有一个项目,名字叫testproject,已经发布了两个版本,2.2.0和2.2.1,其中上海生产环境部署了2.2.0,深圳开发中心已经发布了新版的2.2.1,现在生产环境需要升级到2.2.1,因为新版本修复了重要的bug。 方法有很多种,这里我们说明使用diff和patch的方式。
* 首先在当前工作目录下(假设为/home/jack/),从subversion上export两个版本。
> svn export http://192.168.0.253/svn/TcCenter/TcCenter/tag/2.2.0/sourcecode 2.2.0
>svn export http://192.168.0.253/svn/TcCenter/TcCenter/tag/2.2.1/sourcecode 2.2.1
* 执行diff
>diff -Nur 2.2.0 2.2.1 >220-221.patch
上面的命令会生成一个patch文件,其中-N表示如果目标目录不包含源目录中的文件,那么认为目标目录存在一个内容为空的同名文件。 -u表示生成统一的有上下文的patch文件(后面再说patch格式)。 -r表示递归处理,在处理目录的时候需要这个参数。
* 接下来,我们开始使用patch
>cp 220_221.patch 2.2.0
>cd 2.2.0
>patch -p1<220_221.patch>rm 220_221.patch
>cd ..
>diff -Nur 2.2.0 2.2.1 >220-221_new.patch
可以看到这次得到的220-221_new.patch是空文件,这就说明现在2.2.0的源代码已经被升级到2.2.1了。
* 好了,现在我们可以将这个patch文件从深圳发到上海,然后上海更新源代码,再次编译,测试,打包,部署....
===========================
subverion的diff
===========================
接下来我要试试patch能不能处理subversion的diff得到的patch文件。
* 生成subversion的diff文件,在当前工作目录下(假设为/home/jack/).
> svn diff http://192.168.0.253/svn/TcCenter/TcCenter/tag/2.2.0/sourcecode http://192.168.0.253/svn/TcCenter/TcCenter/tag/2.2.1/sourcecode > diff.patch
>cp diff.patch 2.2.0
>patch -p0rm diff.patch
>cd ..
>>diff -Nur 2.2.0 2.2.1 >220-221_new.patch
可以看到,220-221_new.patch文件为空,说明2.2.0已经升级到2.2.1了。
这里使用diff命令和使用‘svn diff’得到的patch文件格式有点不一样,使用diff得到的为:
diff -Nur 2.2.0/build.properties 2.2.1/build.properties
--- 2.2.0/build.properties 2008-04-30 15:09:14.000000000 +0800
+++ 2.2.1/build.properties 2008-06-27 15:39:36.000000000 +0800
@@ -8,7 +8,7 @@
#--------------------------------------------#
project.name=CentralPool
#DO NOT modify below setting.
-app.version=2.2.0
+app.version=2.2.1
app.vendor=Shenzhen Helper Science & Technology Co., Ltd.
builder.name=${project.name} Team
diff -Nur 2.2.0/CHANGELOG.txt 2.2.1/CHANGELOG.txt
--- 2.2.0/CHANGELOG.txt 2008-04-08 17:02:58.000000000 +0800
+++ 2.2.1/CHANGELOG.txt 2008-06-27 15:39:36.000000000 +0800
@@ -1,16 +1,16 @@
-CENTRALPOOL PROJECT CHANGELOG
+CENTRALPOOL PROJECT CHANGELOG
--------------------------------------
ChangeLog定义了当前版本相对于上一个版本之间系统发生的变更. 这些变更包括修正的bug, 系统新增的
功能,或者系统添加的补丁等等.
而使用‘svn diff’得到的patch文件为:
Index: sub-core/src/com/hengpeng/ante/game/GameFactory.java
===================================================================
--- sub-core/src/com/hengpeng/ante/game/GameFactory.java (.../2.2.0/sourcecode) (revision 241)
+++ sub-core/src/com/hengpeng/ante/game/GameFactory.java (.../2.2.1/sourcecode) (revision 241)
@@ -51,6 +51,9 @@
case Game.GAME_TYPE_SSC:
return new SSCGame(gameData);
+
+ case Game.GAME_TYPE_NUMLOTTO:
+ return new NumLottoGame(gameData);
default:
throw new HPException(AnteException.ErroCode_NoGame,
Index: sub-core/src/com/hengpeng/ante/game/Game.java
===================================================================
--- sub-core/src/com/hengpeng/ante/game/Game.java (.../2.2.0/sourcecode) (revision 241)
+++ sub-core/src/com/hengpeng/ante/game/Game.java (.../2.2.1/sourcecode) (revision 241)
@@ -75,7 +75,13 @@
*/
public static final int GAME_TYPE_SSC = 9;
+ /**
+ * 东方6+1玩法 {@value}
+ * @value 9
+ */
+ public static final int GAME_TYPE_NUMLOTTO = 10;
+
// GAME DEFINITION
public static final int GAME336 = 11;
public static final int GAME155 = 23;
幸运的是patch命令都可以处理,实际上两种都是正确的格式。
diff和patch在linux操作系统中是自带的,但是进入windows环境就没有那么容易了。不过好在有一个gunwin32的开源项目(gunwin32.sourceforge.net),gnu下的diff和patch都可以运行在window上了。
我会通过一个实际的操作示例来说明这两个工具的使用。有一个项目,名字叫testproject,已经发布了两个版本,2.2.0和2.2.1,其中上海生产环境部署了2.2.0,深圳开发中心已经发布了新版的2.2.1,现在生产环境需要升级到2.2.1,因为新版本修复了重要的bug。 方法有很多种,这里我们说明使用diff和patch的方式。
* 首先在当前工作目录下(假设为/home/jack/),从subversion上export两个版本。
> svn export http://192.168.0.253/svn/TcCenter/TcCenter/tag/2.2.0/sourcecode 2.2.0
>svn export http://192.168.0.253/svn/TcCenter/TcCenter/tag/2.2.1/sourcecode 2.2.1
* 执行diff
>diff -Nur 2.2.0 2.2.1 >220-221.patch
上面的命令会生成一个patch文件,其中-N表示如果目标目录不包含源目录中的文件,那么认为目标目录存在一个内容为空的同名文件。 -u表示生成统一的有上下文的patch文件(后面再说patch格式)。 -r表示递归处理,在处理目录的时候需要这个参数。
* 接下来,我们开始使用patch
>cp 220_221.patch 2.2.0
>cd 2.2.0
>patch -p1<220_221.patch>rm 220_221.patch
>cd ..
>diff -Nur 2.2.0 2.2.1 >220-221_new.patch
可以看到这次得到的220-221_new.patch是空文件,这就说明现在2.2.0的源代码已经被升级到2.2.1了。
* 好了,现在我们可以将这个patch文件从深圳发到上海,然后上海更新源代码,再次编译,测试,打包,部署....
===========================
subverion的diff
===========================
接下来我要试试patch能不能处理subversion的diff得到的patch文件。
* 生成subversion的diff文件,在当前工作目录下(假设为/home/jack/).
> svn diff http://192.168.0.253/svn/TcCenter/TcCenter/tag/2.2.0/sourcecode http://192.168.0.253/svn/TcCenter/TcCenter/tag/2.2.1/sourcecode > diff.patch
>cp diff.patch 2.2.0
>patch -p0
>cd ..
>>diff -Nur 2.2.0 2.2.1 >220-221_new.patch
可以看到,220-221_new.patch文件为空,说明2.2.0已经升级到2.2.1了。
这里使用diff命令和使用‘svn diff’得到的patch文件格式有点不一样,使用diff得到的为:
diff -Nur 2.2.0/build.properties 2.2.1/build.properties
--- 2.2.0/build.properties 2008-04-30 15:09:14.000000000 +0800
+++ 2.2.1/build.properties 2008-06-27 15:39:36.000000000 +0800
@@ -8,7 +8,7 @@
#--------------------------------------------#
project.name=CentralPool
#DO NOT modify below setting.
-app.version=2.2.0
+app.version=2.2.1
app.vendor=Shenzhen Helper Science & Technology Co., Ltd.
builder.name=${project.name} Team
diff -Nur 2.2.0/CHANGELOG.txt 2.2.1/CHANGELOG.txt
--- 2.2.0/CHANGELOG.txt 2008-04-08 17:02:58.000000000 +0800
+++ 2.2.1/CHANGELOG.txt 2008-06-27 15:39:36.000000000 +0800
@@ -1,16 +1,16 @@
-CENTRALPOOL PROJECT CHANGELOG
+CENTRALPOOL PROJECT CHANGELOG
--------------------------------------
ChangeLog定义了当前版本相对于上一个版本之间系统发生的变更. 这些变更包括修正的bug, 系统新增的
功能,或者系统添加的补丁等等.
而使用‘svn diff’得到的patch文件为:
Index: sub-core/src/com/hengpeng/ante/game/GameFactory.java
===================================================================
--- sub-core/src/com/hengpeng/ante/game/GameFactory.java (.../2.2.0/sourcecode) (revision 241)
+++ sub-core/src/com/hengpeng/ante/game/GameFactory.java (.../2.2.1/sourcecode) (revision 241)
@@ -51,6 +51,9 @@
case Game.GAME_TYPE_SSC:
return new SSCGame(gameData);
+
+ case Game.GAME_TYPE_NUMLOTTO:
+ return new NumLottoGame(gameData);
default:
throw new HPException(AnteException.ErroCode_NoGame,
Index: sub-core/src/com/hengpeng/ante/game/Game.java
===================================================================
--- sub-core/src/com/hengpeng/ante/game/Game.java (.../2.2.0/sourcecode) (revision 241)
+++ sub-core/src/com/hengpeng/ante/game/Game.java (.../2.2.1/sourcecode) (revision 241)
@@ -75,7 +75,13 @@
*/
public static final int GAME_TYPE_SSC = 9;
+ /**
+ * 东方6+1玩法 {@value}
+ * @value 9
+ */
+ public static final int GAME_TYPE_NUMLOTTO = 10;
+
// GAME DEFINITION
public static final int GAME336 = 11;
public static final int GAME155 = 23;

diff和patch在linux操作系统中是自带的,但是进入windows环境就没有那么容易了。不过好在有一个gunwin32的开源项目(gunwin32.sourceforge.net),gnu下的diff和patch都可以运行在window上了。
Subscribe to:
Posts (Atom)