The NoteBook of EricKong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

#

不同的JVM及其选项会输出不同的日志。

GC 日志

生成下面日志使用的选项: -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:d:/GClogs/tomcat6-gc.log

4.231: [GC 4.231: [DefNew: 4928K->512K(4928K), 0.0044047 secs] 6835K->3468K(15872K), 0.0045291 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
 
4.445: [Full GC (System) 4.445: [Tenured: 2956K->3043K(10944K), 0.1869806 secs] 4034K->3043K(15872K), [Perm : 3400K->3400K(12288K)], 0.1870847 secs] [Times: user=0.05 sys=0.00, real=0.19 secs] 

最前面的数字 4.231  4.445 代表虚拟机启动以来的秒数。

[GC  [Full GC 是垃圾回收的停顿类型,而不是区分是新生代还是年老代,如果有 Full 说明发生了 Stop-The-World 。如果是调用 System.gc() 触发的,那么将显示的是 [Full GC (System) 

接下来的 [DefNew, [Tenured, [Perm 表示 GC 发生的区域,区域的名称与使用的 GC 收集器相关。 Serial 收集器中新生代名为 "Default New Generation",显示的名字为 "[DefNew"。对于ParNew收集器,显示的是 "[ParNew",表示 “Parallel New Generation”。 对于 Parallel Scavenge 收集器,新生代名为 "PSYoungGen"。年老代和永久代也相同,名称都由收集器决定。

方括号内部显示的 “4928K->512K(4928K)” 表示 “GC 前该区域已使用容量 -> GC 后该区域已使用容量 (该区域内存总容量) ”。

再往后的 “0.0044047 secs” 表示该区域GC所用时间,单位是秒。

再往后的 “6835K->3468K(15872K)” 表示 “GC 前Java堆已使用容量 -> GC后Java堆已使用容量 (Java堆总容量)”。

再往后的 “0.0045291 secs” 是Java堆GC所用的总时间。

最后的 “[Times: user=0.00 sys=0.00, real=0.00 secs]” 分别代表 用户态消耗的CPU时间、内核态消耗的CPU时间 和 操作从开始到结束所经过的墙钟时间。墙钟时间包括各种非运算的等待耗时,如IO等待、线程阻塞。CPU时间不包括等待时间,当系统有多核时,多线程操作会叠加这些CPU时间,所以user或sys时间会超过real时间。

堆的分代

JVM-heap-generations

在上图中:

  • young区域就是新生代,存放新创建对象;
  • tenured是年老代,存放在新生代经历多次垃圾回收后仍存活的对象;
  • perm是永生代,存放类定义信息、元数据等信息。

当GC发生在新生代时,称为Minor GC,次收集;当GC发生在年老代时,称为Major GC,主收集。 一般的,Minor GC的发生频率要比Major GC高很多。

posted @ 2015-06-18 11:28 Eric_jiang 阅读(239) | 评论 (0)编辑 收藏

     摘要: 这个是之前处理过的一个线上问题,处理过程断断续续,经历了两周多的时间,中间各种尝试,总结如下。这篇文章分三部分: 1、问题的场景和处理过程;2、GC的一些理论东西;3、看懂GC的日志 先说一下问题吧 问题场景:线上机器在半夜会推送一个700M左右的数据,这个时候有个数据置换的过程,也就是说有700M*2的数据在heap区域中,线上系统超时比较多,导致了很严重(严重程度就不说了)的问题。 问...  阅读全文
posted @ 2015-06-18 11:24 Eric_jiang 阅读(288) | 评论 (0)编辑 收藏

VM性能的快速测试方法


核心提示: 经常有同行问怎么样去做这些性能评测。其实这些性能评测都很简单,任何一个具备Linux基础知识的工程师都可以完成。我们通常使用UnixBench来评估虚拟机CPU性能,mbw来评估内存性能,iozone来评估文件IO性能,iperf来评估网络性能,pgbench来评估数据库性能。在这里我将我自己做性能测试的过程整理一下,供各位同行参考。

中国IDC圈10月30日报道 前段时间陆续发布了一些对公有云服务性能评测的数据。经常有同行问怎么样去做这些性能评测。其实这些性能评测都很简单,任何一个具备Linux基础知识的工程师都可以完成。我们通常使用UnixBench来评估虚拟机CPU性能,mbw来评估内存性能,iozone来评估文件IO性能,iperf来评估网络性能,pgbench来评估数据库性能。在这里我将我自己做性能测试的过程整理一下,供各位同行参考。

(0)安装必要的软件

假定VM的操作系统是Ubuntu,可以按照如下步骤安装必要的软件:

20141030104942

(1)CPU性能测试

我们使用UnixBench来进行CPU性能测试。UnixBench是一套具有悠久历史的性能测试工具,其测试结果反映的是一台主机的综合性能。从理论上来说UnixBench测试结果与被测试主机的CPU、内存、存储、操作系统都有直接的关系。但是根据我们的观察,对于现代的计算机系统来说,UnixBench测试结果受CPU 处理能力的影响更大一些。因此,在这里我们用UnixBench测试结果来代表虚拟机的vCPU 处理能力。每个UnixBench测试结果包括两个数据,一个是单线程测试结果,另一个是多线程测试结果(虚拟机上有几颗虚拟CPU,就有几个并发的测试线程)。

cd ~/UnixBench

./Run

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3)。我们分别测试了宿主机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在本地磁盘上的虚拟机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在NFS上的虚拟机的CPU性能。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存,运行Ubuntu 12.04 AMD64 Server操作系统。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优。

14982672_201410291058471naZq

 

从如上测试结果可以看出,在没有进行任何性能调优的情况下,在单线程CPU性能方面,宿主机 >> 本地磁盘上的虚拟机 >> NFS服务上的虚拟机;在多线程CPU性能方面,宿主机 >> 本地磁盘上的虚拟机 = NFS服务上的虚拟机。需要注意的是,在多线程测试结果方面,宿主机所占的优势完全是由于宿主机比虚拟机多占用了两个物理线程,也就是一个物理核心。可以认为,在如上所述测试中,物理机和虚拟机的CPU性能基本上是一致的,虚拟化基本上没有导致CPU性能损失。

(2)文件IO性能测试

我们使用iozone来进行文件IO性能测试。iozone性能测试结果表示的是文件IO的吞吐量(KBps),但是通过吞吐量可以估算出IOPS.在如下命令中,我们评估的是以256K为数据块大小对文件进行写、重写、读、重读、随机读、随机写性能测试,在测试过程当中使用/io.tmp作为临时测试文件,该测试文件的大小是4 GB.需要注意的是,命令中所指定的测试文件是带路径的,因此我们可以测试同一虚拟机上不同文件系统的性能。例如我们通过NFS将某一网络共享文件系统挂载到虚拟机的/mnt目录,那么我们可以将该测试文件的路径设定为/mnt/io.tmp.

cd ~/iozone3_414/src/current

./iozone -Mcew -i0 -i1 -i2 -s4g -r256k -f /io.tmp

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3)。我们分别测试了宿主机、NFS、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在本地磁盘上的虚拟机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在NFS上的虚拟机、以及从虚拟机内部挂载宿主机NFS服务(虚拟网卡启用了virtio)的磁盘IO性能。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存,运行Ubuntu 12.04 AMD64 Server操作系统。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优。

14982672_201410291058472o0uv

从如上测试结果可以看出,在如上所述特定测试场景中,在文件IO性能方面,宿主机 > NFS > 虚拟机中的NFS > 本地磁盘上的虚拟机 >NFS服务上的虚拟机。值得注意的是,即使是从虚拟机中挂载NFS服务,其文件IO性能也远远超过本地磁盘上的虚拟机。
        

[特别说明]需要注意的是,当我们说文件(或者磁盘)IO性能的时候,我们指的通常是应用程序(例如iozone)进行文件读写操作时所看到的IO性能。这个性能通常是与系统相关的,包括了多级缓存(磁盘自身的缓存机制、操作系统的缓存机制)的影响,而不仅仅是磁盘本身。利用iozone进行文件IO性能测试时,测试结果与主机的内存大小、测试数据块的大小、测试文件的大小都有很大的关系。如果要全面地描述一个特定系统(CPU、内存、硬盘)的文件IO性能,往往需要对测试数据块的大小和测试文件的大小进行调整,进行一系列类似的测试并对测试结果进行全面分析。本文所提供的仅仅是一个快速测试方法,所提供的测试参数并没有针对任何特定系统进行优化,仅仅是为了说明iozone这个工具的使用方法。如上所述之测试数据,仅仅在如上所述之测试场景下是有效的,并不足以定性地说明任何虚拟化场景下宿主机和虚拟机的文件IO性能差异。建议读者在掌握了iozone这个工具的使用方法的基础上,对被测试对象进行更加全面的测试。(感谢saphires网友的修改建议。)

(3)内存性能测试

我们使用mbw来测试虚拟机的内存性能。mbw通常用来评估用户层应用程序进行内存拷贝操作所能够达到的带宽(MBps)。

mbw 128

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3),虚拟机运行Ubuntu 12.04 AMD64 Server操作系统。我们分别测试了宿主机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在本地磁盘上的虚拟机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在NFS上的虚拟机的内存性能。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优。

14982672_201410291058473O2O9

从如上测试结果可以看出,在没有进行任何性能调优的情况下,宿主机、本地磁盘上的虚拟机、NFS服务上的虚拟机在内存性能方面基本上是一致的,虚拟化基本上没有导致内存性能损失。

(4)网络带宽测试

我们使用iperf来测试虚拟机之间的网络带宽(Mbps)。测试方法是在一台虚拟机上运行iperf服务端,另外一台虚拟机上运行iperf客户端。假设运行服务端的虚拟机的IP地址是192.168.1.1,运行客户端的虚拟机的IP地址是192.168.1.2.

在服务端执行如下命令:

iperf -s

在客户端执行如下命令:

iperf -c 192.168.1.1

测试完成后,在客户端会显示两台虚拟机之间的网络带宽。

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3)。我们分别测试了宿主机之间、宿主机与虚拟机之间、虚拟机与虚拟机之间的内网带宽。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存,运行Ubuntu 12.04 AMD64 Server操作系统。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优,但是虚拟机的网卡启用了virtio.

从如上测试结果可以看出,宿主机之间的内网带宽接近内网交换

14982672_201410291058474jZZA

机的极限。在启用了virtio的情况下,宿主机与虚拟机之间内网带宽有小幅度的性能损失,基本上不会影响数据传输能力;虚拟机与虚拟机之间的内网带宽有接近15%的损失,对数据传输能力影响也不是很大。

(5)数据库性能测试

postgresql是一个著名的开源数据库系统。在MySQL被Sun 公司收购并进一步被Oracle公司收购之后,越来越多的公司正在从MySQL迁移到postgresql.pgbench是一个针对postgresql的性能测试工具,其测试结果接近于TPC-B.pgbench的优点之一在于它能够轻易地进行多线程测试,从而充分利用多核处理器的处理能力。

在虚拟机上以postgres用户登录:

su -l postgres

将/usr/lib/postgresql/9.1/bin加入到路径PATH当中。

创建测试数据库:

createdb pgbench

初始化测试数据库:

pgbench -i -s 16 pgbench

执行单线程测试:

pgbench -t 2000 -c 16 -U postgres pgbench

执行多线程测试,在下面的命令中将N替换为虚拟机的vCPU数量:

pgbench -t 2000 -c 16 -j N -U postgres pgbench

下面是一个可供参考的测试结果。在这个测试中使用了两台物理机,每台物理机各配置一颗Intel Core i3 540 @ 3.07 GHz (双核四线程),16 GB内存(DDR3 @ 1333 MHz),一块Seagate ST2000DL003-9VT1硬盘(SATA,2TB,5900RPM),运行Ubuntu 10.04 AMD64 Server操作系统,使用的文件系统为ext4,使用的Hypervisor为KVM(qemu-kvm-0.12.3),虚拟机运行Ubuntu 12.04 AMD64 Server操作系统。我们分别测试了宿主机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在本地磁盘上的虚拟机、磁盘映像以文件格式(RAW格式,没有启用virtio)存储在NFS上的虚拟机的数据库性能。虚拟机的配置为2 颗vCPU(占用两个物理线程,也就是一个物理核心)和4 GB内存,运行Ubuntu 12.04 AMD64 Server操作系统。在这个测试中没有对操作系统、文件系统、NFS、KVM等等进行任何性能调优。

14982672_201410291058475a5wk

从如上测试结果可以看出,在没有进行任何性能调优的情况下,在数据库性能方面,宿主机 >> 本地磁盘上的虚拟机 >> NFS服务上的虚拟机。


 

posted @ 2015-06-16 10:50 Eric_jiang 阅读(172) | 评论 (0)编辑 收藏

本文是参考logstash官方文档实践的笔记,搭建环境和所需组件如下:

  • Redhat 5.7 64bit / CentOS 5.x
  • JDK 1.6.0_45
  • logstash 1.3.2 (内带kibana)
  • elasticsearch 0.90.10
  • redis 2.8.4

搭建的集中式日志分析平台流程如下: 

安装logstash+kibana+elasticsearch+redis搭建日志分析平台 - 傲风 - 0与1构筑世界,程序员创造时代

 

elasticsearch

1、下载elasticsearch。

wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.10.tar.gz 

2、解压后,进入bin目录。执行如下命令,让elasticsearch以前台方式启动:

./elasticsearch -f 
[2014-01-16 16:21:31,825][INFO ][node                     ] [Saint Elmo] version[0.90.10], pid[32269], build[0a5781f/2014-01-10T10:18:37Z] [2014-01-16 16:21:31,826][INFO ][node                     ] [Saint Elmo] initializing ... [2014-01-16 16:21:31,836][INFO ][plugins                  ] [Saint Elmo] loaded [], sites [] [2014-01-16 16:21:35,425][INFO ][node                     ] [Saint Elmo] initialized [2014-01-16 16:21:35,425][INFO ][node                     ] [Saint Elmo] starting ... [2014-01-16 16:21:35,578][INFO ][transport                ] [Saint Elmo] bound_address {inet[/0.0.0.0:9300]}, publish_address {inet[/10.0.2.15:9300]} 

Redis

1、其安装方式可以参考我的另一篇文章Redis编译安装

2、进入其bin目录,执行如下命令,使之在控制台输出debug信息:

./redis-server --loglevel verbose 
[32470] 16 Jan 16:45:57.330 * The server is now ready to accept connections on port 6379 [32470] 16 Jan 16:45:57.330 - 0 clients connected (0 slaves), 283536 bytes in use 

logstash日志生成器(shipper)

1、新建一个配置文件:shipper.conf,其内容如下:

input {     stdin {         type => "example"     } }  output {     stdout {         codec => rubydebug     }     redis {         host => "127.0.0.1"         port => 6379         data_type => "list"         key => "logstash"     } } 

2、启动shipper。执行如下命令:

java -jar logstash-1.3.2-flatjar.jar agent -f shipper.conf  

终端窗口将出现如下提示信息:

Using milestone 2 output plugin 'redis'. This plugin should be stable, but if you see strange behavior, please let us know! For more information on plugin milestones, see http://logstash.net/docs/1.3.2/plugin-milestones {:level=>:warn} 

然后在终端窗口直接按回车,将出现如下信息:

{        "message" => "",       "@version" => "1",     "@timestamp" => "2014-01-16T08:15:19.400Z",           "type" => "example",           "host" => "redhat" } 

这个json信息将发送给redis, 同时redis的终端窗口将出现类似下面的提示信息:

[32470] 16 Jan 17:09:23.604 - Accepted 127.0.0.1:44640 [32470] 16 Jan 17:09:27.127 - DB 0: 1 keys (0 volatile) in 4 slots HT. [32470] 16 Jan 17:09:27.127 - 1 clients connected (0 slaves), 304752 bytes in use 

logstash日志索引器(indexer)

1、新建一个配置文件:indexer.conf,其内容如下:

input {   redis {     host => "127.0.0.1"     # these settings should match the output of the agent     data_type => "list"     key => "logstash"      # We use the 'json' codec here because we expect to read     # json events from redis.     codec => json   } }  output {   stdout { debug => true debug_format => "json"}    elasticsearch {     host => "127.0.0.1"   } } 

2、启动日志索引器。执行如下命令:

java -jar logstash-1.3.2-flatjar.jar agent -f indexer.conf  

终端窗口将出现如下提示信息:

Using milestone 2 input plugin 'redis'. This plugin should be stable, but if you see strange behavior, please let us know! For more information on plugin milestones, see http://logstash.net/docs/1.3.2/plugin-milestones {:level=>:warn} You are using a deprecated config setting "debug_format" set in stdout. Deprecated settings will continue to work, but are scheduled for removal from logstash in the future.  If you have any questions about this, please visit the #logstash channel on freenode irc. {:name=>"debug_format", :plugin=>, :level=>:warn} 

索引器从Redis接收到信息,在终端窗口会显示类似如下的信息:

{"message":"","@version":"1","@timestamp":"2014-01-16T17:10:03.831+08:00","type":"example","host":"redhat"}{"message":"","@version":"1","@timestamp":"2014-01-16T17:13:20.545+08:00","type":"example","host":"redhat"}{ 

logstash WEB界面(kibana)

1、启动kibana。执行如下命令:

java -jar logstash-1.3.2-flatjar.jar web 

2、打开浏览器(须支持HTML5),输入地址:http://127.0.0.1:9292/index.html#/dashboard/file/logstash.json。界面效果如下: 

安装logstash+kibana+elasticsearch+redis搭建日志分析平台 - 傲风 - 0与1构筑世界,程序员创造时代
 

参考资料

posted @ 2015-06-12 11:30 Eric_jiang 阅读(477) | 评论 (0)编辑 收藏

Fluentd是一个开源收集事件和日志系统,它目前提供150+扩展插件让你存储大数据用于日志搜索,数据分析和存储。

官方地址http://fluentd.org/  插件地址http://fluentd.org/plugin/

Kibana 是一个为 ElasticSearch 提供日志分析的 Web ui工具,可使用它对日志进行高效的搜索、可视化、分析等各种操作。官方地址http://www.elasticsearch.org/overview/kibana/

elasticsearch 是开源的(Apache2协议),分布式的,RESTful的,构建在Apache Lucene之上的的搜索引擎.

官方地址http://www.elasticsearch.org/overview/    中文地址 http://es-cn.medcl.net/


具体的工作流程就是利用fluentd 监控并过滤hadoop集群的系统日志,将过滤后的日志内容发给全文搜索服务ElasticSearch, 然后用ElasticSearch结合Kibana 进行自定义搜索web页面展示.

下面开始说部署方法和过程。以下安装步骤在centos 5 64位测试通过

一、  elasticsearch安装部署

elasticsearch 官方提供了几种安装包,适用于windows的zip压缩包,适用于unix/linux的tar.gz压缩包,适用于centos系统的rpm包和ubuntu的deb包。大家可以自己选择安装使用。

因为elasticsearch 需要java环境运行,首先需要安装jdk,安装步骤就省略了。

使用.tar.gz压缩包安装部署的话,先下载压缩包

# wget  https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.5.tar.gz

# tar zxvf elasticsearch-0.90.5.tar.gz

////////////如果是单机部署

# cd elasticsearch-0.90.5

# elasticsearch-0.90.5/bin/elasticsearch -f

就可以启动搜索服务了,查看端口9200是否打开,如果打开说明启动正常。

////////////////如果是部署集群的话,需要进行配置

例如在192.168.0.1   192.168.0.2 两台服务器部署,两台服务器都安装好jdk,下载elasticsearch 解压缩,然后编辑配置文件

//////////////////////192.168.0.1   服务器编辑文件

vi elasticsearch-0.90.5/config/elasticsearch.yml

删除cluster.name 前面注释,修改集群名称 

cluster.name: es_cluster

删除node.name前注释 ,修改节点名称,不修改的话,系统启动后会生成随即node名称。

node.name: "elastic_inst1"

node.master: true    设置该节点为主节点


/////////////////////////192.168.0.2  编辑文件

vi elasticsearch-0.90.5/config/elasticsearch.yml

删除cluster.name 前面注释,修改集群名称 

cluster.name: es_cluster

删除node.name前注释 ,修改节点名称,不修改的话,系统启动后会生成随即node名称。

node.name: "elastic_inst2"

node.master: false    设置该节点为主节点


分别启动两台服务器的服务后,在192.168.0.2的日志中会看到

 [elastic_inst2] detected_master [elastic_inst1]     日志信息。说明集群连接成功。


二、安装部署fluentd

在需要监控分析的hadoop集群节点中安装fluentd,安装步骤很简单


curl -L http://toolbelt.treasure-data.com/sh/install-redhat.sh | sh

安装完成后,编辑配置文件

# vim /etc/td-agent/td-agent.conf

  1. <source>  
  2.   type tail  #### tail方式采集日志  
  3.   path /var/log/hadoop/mapred/hadoop-mapred-tasktracker-node-128-70.log   ### hadoop日志路径  
  4.   pos_file /var/log/td-agent/task-access.log.pos  
  5.   tag task.mapred  
  6.   format /^(?<message>.+(WARN|ERROR).+)$/   #### 收集error 或者warn 日志。  
  7. </source>  
  8.   
  9. <match task.**>  
  10.   host 192.168.0.1  #####  <span style="font-family:Arial,Helvetica,sans-serif">elasticsearch 服务器地址</span>  
  11.   type elasticsearch  
  12.   logstash_format true  
  13.   flush_interval 5s  
  14.   include_tag_key true  
  15.   tag_key mapred  
  16. </match>  

启动fluentd 服务

# service td-agent start


三、安装部署kibana 3

kibana 3 是使用html 和javascript 开发的web ui前端工具。

下载 wget http://download.elasticsearch.org/kibana/kibana/kibana-latest.zip

解压缩 unzip kibana-latest.zip

安装apache    yum -y install httpd

cp -r  kibana-latest /var/www/html

因为我将kibana3 安装在和elasticsearch同一台服务器中,所以不用修改配置文件

启动apache  service httpd start

打开浏览器 http://ip/kibana 就可以看到kibana 界面

初次使用kibana 需要自己定义模块




posted @ 2015-06-12 11:05 Eric_jiang 阅读(801) | 评论 (0)编辑 收藏

前言
    持续集成这个概念已经成为软件开发的主流,可以更频繁的进行测试,尽早发现问题并提示。自动化部署就更不用说了,可以加快部署速度,并可以有效减少人为操作的失误。之前一直没有把这个做起来,最近的新项目正好有机会,费了一番功夫总算搞好了,特此记录。

1. 开发环境
    我这边建立的标准开发环境如下:
    1. Maven做项目管理;
    2. Git做代码管理;
    3. SpringMVC+Spring+Mybatis搭建的程序框架;
    4. Mysql作为数据存储,Druid做连接池;
    5. unitils作为测试框架;
    6. Hibernate Validator作为数据验证;

    7. log4j作为日志输出。
    注:其实这套东西非常像Grails,但不敢用太激进的技术和框架,担心招人的问题-_-!

2. Jenkins的部署
    Jenkins原名是Hudson,这个渊源这里就不追溯了,网上多得是,但是千万别下错了,官网地址是http://jenkins-ci.org/。建议直接下载最新版本。

    这个软件的安装是我见过最简单的了,直接取war包放到tomcat下,启动tomcat即可。相应的工程配置会在~/.jenkins目录中。(当然你根据官网给的那种安装方法也行,只是在debian的那个弄法还要去下载openjdk等等,多下了很多东西,相关配置也按linux目录标准分开的,还要去找。)

    另外提醒一下,建议把Jenkins安装在Linux上,这样就不会出现ssh等命令找不到的问题,否则还要想办法去处理。

3. Jenkins的插件
    安装好后直接访问“http://yourhost:8080/jenkins”即可进入主界面,点击“系统管理”->“管理插件”,首次进入都是空白的,要等1分钟左右才能看到内容,在后台估计是在做更新或者下载,然后重新再进此界面就能看到内容了。

3.1 Git插件
    在“可选插件”中找到“GIT plugin”安装,最下面有个安装完重启的勾选项,选中即可。这里最搞笑的是检测网络是否连通的办法是去尝试打开google,岂不知天朝是打不开的,还好不影响下载。。。

3.2 Email插件
    这个事情非常蛋疼,之前测试怎么都发布出来邮件,最后升级了一下默认插件就行了,狂汗。在“可更新”中找到“Mailer Plugin”选中并更新即可。另外如果想有更丰富的邮件内容,就去“可选插件”中安装“Email Extension Plugin”,具体邮件内容配置网上大把可以搜。

3.3 其他插件
    默认就装了很多常用插件,比如Maven、Junit等等,如果使用感觉有问题可以尝试升级一下版本,但是没有升级说明,也不知道升级了什么东西。


4. 系统设置
    主界面点击“系统管理”->“系统设置”即可进入。重点配置以下内容:
    1. Java、Git、Maven的目录位置,确保可以正确找到命令;

    2. Jenkins URL,自动生成的,检查一下即可;
    3. 邮件的设置。这里注意一下,上面有一个“系统管理员邮件地址”需要填写,另外“Extended E-mail Notification”中填写配置,原来的“邮件配置”就不用再理会了。

5. 项目设置
    在主界面直接“新建”,就会有一个新的项目。重点配置以下内容:

    1. 源码管理:选择Git,填写“Repository URL”,并加上相应的“Credentials”,其中认证信息用私钥的话干脆直接把私钥内容填上去就行了,省的不知道目录查找规则还不知道出的啥问题。

    2. 构建触发器:这个地方要把“Build periodically”和“Poll SCM”都选上,时间格式都填写成一样的即可,比如“H/15  * * * *”,下面会有个具体执行时间的提示,Build动作会自动比Poll延迟3分40秒,这个设定还是很合理的。

    3. 构建:增加两个构建步骤,分别是“Execute shell”和“Invoke top-level Maven target”,注意先后顺序,可以拖拽摆放的。脚本执行根据自己需要,比如我需要去修改数据库连接配置,官方建议是自己在工程里面写好脚本,这里直接调用,而不是在这写一个完整的脚本。Maven构建就加上“clean test”即可,就是运行“mvn clean test”的命令。

    4. Publish Junit test result report:在测试报告(XML)上加上“**/target/surefire-reports/*.xml”即可,这样就会每次测试完自动找到测试报告,在Jenkins上即可在每个构建结构里面查看到。

    5. 邮件通知:在构建后增加“Editable Email Notification”,填写邮件的接受者、内容格式可以直接用全局变量,重点是配置一下发送触发条件。

6. 安全性配置
    经过以上配置进行一次构建就会发现,Jenkins可以看到太多内容了,包括pull到的源码,所以非常有必要增加权限控制。进入“系统管理”->“Configure Global Security”中进行如下步骤:
    1. 启用安全;

    2. Jenkins专有用户数据库,先允许用户注册;
    3. 授权策略选择“安全矩阵”,新加一个“admin”的用户,把所有权限都开给admin用户;
    4. 在主界面的用户中找到admin,进行配置,设置登陆密码;
    5. 先重新登陆测试一下是否admin正常,没有问题就关闭允许用户注册,把匿名用户的所有权限都去掉。

7. 自动化部署
    这里我没有让Jenkins每次测试都去部署,一方面是考虑到单元测试基本已经满足需要了,另一方面因为测试太频繁了,一直部署也搞得Stage测试环境要经常重启,反而影响正常的人工测试。所以自己写了个脚本,在必要的时候去运行一下去自动完成整个部署工作。
#!/bin/sh 
  
# update code 
git pull 
  
# package 
mvn clean 
mvn package -Dmaven.test.skip=true
  
# deploy 
WAR=`ls target | grep war` 
TOMCAT=/home/test/apache-tomcat-6.0.41 
mv target/$WAR $TOMCAT 
cd $TOMCAT 
# invoke another deploy script 
sh deploy-war.sh $WAR webapps

 

8. 一个非常蛋疼的问题
    这个和以上问题都无关,只是极其不解的是这个错误在Windows下不出现,在Linux下打成War也不会出现,只有在Linux下直接执行Maven test就会出错。其实问题的根源就是配置书写不够规范,但是错误出现的不一致性实在让人蛋疼。报错如下:
1 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): xxx

    这个就是Mybatis找不到绑定的类,但是xml是正确打包的,怎么看都是没大问题,并且windows也是对的,最后发现是我在写模糊路径的时候,classpath后面必须要加个*才是标准写法,正确写法如下:

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
        <property name="basePackage" value="com.gzxitao.demo.*.dao"/> 
    </bean> 
  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
        <property name="dataSource" ref="dataSource"/> 
        <property name="configLocation" value="classpath:configuration.xml"/> 
        <!-- 这里是要扫描多个目录下的文件,必须声明成“classpath*”,否则在某些情况下会报错 -->
        <property name="mapperLocations" value="classpath*:com/gzxitao/demo/*/dao/*.xml" /> 
    </bean>

Maven权威指南_中文完整版清晰PDF  http://www.linuxidc.com/Linux/2014-06/103690.htm

Maven 3.1.0 发布,项目构建工具 http://www.linuxidc.com/Linux/2013-07/87403.htm

Linux 安装 Maven http://www.linuxidc.com/Linux/2013-05/84489.htm

Maven3.0 配置和简单使用 http://www.linuxidc.com/Linux/2013-04/82939.htm

Ubuntu下搭建sun-jdk和Maven2 http://www.linuxidc.com/Linux/2012-12/76531.htm

Maven使用入门 http://www.linuxidc.com/Linux/2012-11/74354.htm

Jenkins的分布式构建及部署——节点  http://www.linuxidc.com/Linux/2015-05/116903.htm

Jenkins 的详细介绍请点这里
Jenkins 的下载地址请点这里

本文永久更新链接地址http://www.linuxidc.com/Linux/2015-06/118606.htm

posted @ 2015-06-12 10:59 Eric_jiang 阅读(430) | 评论 (0)编辑 收藏

《目录》

一、安装Jenkins

二、配置Jenkins

三、自动编译

四、自动测试

五、自动部署

一、安装Jenkins

地址http://mirrors.jenkins-ci.org/下载适合的Jenkins版本。

Windows最新稳定版的Jenkins地址为:http://mirrors.jenkins-ci.org/windows-stable/jenkins-1.409.1.zip

Jenkins 1.409.1版解压,把得到的war包直接扔到tomcat下,启动tomcatJenkins就安装完毕,是不是很简单啊。

二、配置Jenkins

1、打开http://10.3.15.78:8080/jenkins/,第一次进入里面没有数据,我们需要创建job,我们这有2个项目,需要创建2jobhttp://10.3.34.163:9890/jenkins/

2、点击左上角的new job,在new job页面需要选择job的类型,Jenkins支持几种类型,我们选择“构建一个maven2/3项目”

3、点击OK按钮后,进会进入详细配置界面,详细配置界面的配置项很多,不过不用怕,大部分使用默认配置就可以了,下面就说说我们需要修改的几个地方:

3.1Source Code Management

因为我们使用SVN管理源码,所以这里选择Subversion,并在Repository URL中输入我们的SVN地址:

http://10.3.34.163:9880/XXXX/trunk/

输入SVN库的URL地址后,Jenkins会自动验证地址,并给予提示。

点击红色字体部分的enter credential链接,进入页面

设置好访问SVN库的用户名和密码后,点击OK按钮

设置成功。点击Close按钮,返回之前的Source Code Management页面。此时不再有红色警告信息了。

3.2)配置自动构建的计划,假设我们想让项目中每天12点和晚上8点自动构建一次,只需要在Build Triggers中选择Build periodically,并在Schedule中输入 0 12,20 * * *

我配置的是每晚8点自动构建

注:Schedule的配置规则是有5个空格隔开的字符组成,从左到右分别代表:分年。*代表所有,0 12,20 * * * 表示“在任何年任何月任何天的12200分”进行构建。

3.3)配置到这里,可能有人发现在Build配置节点,有红色错误信息,提示

Jenkins needs to know where your Maven2 is installed.
Please do so from the system configuration.

是因为Jenkins找不到maven的原因,点击"system configuration",是system configurationmaven配置中添加maven目录就OK。

我设置了JRE 6MAVEN 3的安装目录。

点击左下角的SAVE按钮,保存设置。

3.4)保存好所有配置后,我们第1job就算是完成了。

3.5)创建第2job,配置和上面的配置相同。只需把svn地址改成:http://localhost/svn/Web

三、自动编译

在经过上面的配置后,回到Jenkins首页,在首页可以看到刚才添加的2job

点击某1job后后面的"Schedule a build"图片手动构建,点击完后,会在左边的Build Queue或者Build Executor Status显示正在构建的任务,在自动构建完后,刷新页面,就可以看到构建结果了,如何某个项目构建失败,点击项目后面的构建数字(1开始递增)进入项目的"Console Output "可以查看项目构建失败的原因。当然我们也可以配置把构建失败的结果发到邮箱。

到目前为止,1个简单的自动构建环境就搭建好了,很简单吧。

posted @ 2015-06-12 10:49 Eric_jiang 阅读(269) | 评论 (0)编辑 收藏

简介

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

 

使用方法

awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

 

调用awk

有三种方式调用awk

复制代码
1.命令行方式 awk [-F  field-separator]  'commands'  input-file(s) 其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。 在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。  2.shell脚本方式 将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。 相当于shell脚本首行的:#!/bin/sh 可以换成:#!/bin/awk  3.将所有的awk命令插入一个单独文件,然后调用: awk -f awk-script-file input-file(s) 其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。
复制代码

 本章重点介绍命令行方式。

 

入门实例

假设last -n 5的输出如下

[root@www ~]# last -n 5 <==仅取出前五行 root     pts/1   192.168.1.100  Tue Feb 10 11:21   still logged in root     pts/1   192.168.1.100  Tue Feb 10 00:46 - 02:28  (01:41) root     pts/1   192.168.1.100  Mon Feb  9 11:41 - 18:30  (06:48) dmtsai   pts/1   192.168.1.100  Mon Feb  9 11:41 - 11:41  (00:00) root     tty1                   Fri Sep  5 14:09 - 14:10  (00:01)

如果只是显示最近登录的5个帐号

#last -n 5 | awk  '{print $1}'
root
root
root
dmtsai
root

awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键",所以$1表示登录用户,$3表示登录用户ip,以此类推。

 

如果只是显示/etc/passwd的账户

#cat /etc/passwd |awk  -F ':'  '{print $1}'   root daemon bin sys

这种是awk+action的示例,每行都会执行action{print $1}。

-F指定域分隔符为':'。

 

如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割

#cat /etc/passwd |awk  -F ':'  '{print $1"\t"$7}' root    /bin/bash daemon  /bin/sh bin     /bin/sh sys     /bin/sh

 

如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh"。

复制代码
cat /etc/passwd |awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7} END {print "blue,/bin/nosh"}' name,shell root,/bin/bash daemon,/bin/sh bin,/bin/sh sys,/bin/sh .... blue,/bin/nosh
复制代码

awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。

 

搜索/etc/passwd有root关键字的所有行

#awk -F: '/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash

这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。

搜索支持正则,例如找root开头的: awk -F: '/^root/' /etc/passwd

 

搜索/etc/passwd有root关键字的所有行,并显示对应的shell

# awk -F: '/root/{print $7}' /etc/passwd              /bin/bash

 这里指定了action{print $7}

 

awk内置变量

awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

复制代码
ARGC               命令行参数个数 ARGV               命令行参数排列 ENVIRON            支持队列中系统环境变量的使用 FILENAME           awk浏览的文件名 FNR                浏览文件的记录数 FS                 设置输入域分隔符,等价于命令行 -F选项 NF                 浏览记录的域的个数 NR                 已读的记录数 OFS                输出域分隔符 ORS                输出记录分隔符 RS                 控制记录分隔符
复制代码

 此外,$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。

 

统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

#awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh

 

使用printf替代print,可以让代码更加简洁,易读

 awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

 

print和printf

awk中同时提供了print和printf两种打印输出的函数。

其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。

printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

 

 awk编程

 变量和赋值

除了awk的内置变量,awk还可以自定义变量。

下面统计/etc/passwd的账户人数

awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd root:x:0:0:root:/root:/bin/bash ...... user count is  40

count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。

 

这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:

awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd [start]user count is  0 root:x:0:0:root:/root:/bin/bash ... [end]user count is  40

 

统计某个文件夹下的文件占用的字节数

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
[end]size is  8657198

 

如果以M为单位显示:

ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}' 
[end]size is  8.25889 M

注意,统计不包括文件夹的子目录。

 

条件语句

 awk中的条件语句是从C语言中借鉴来的,见如下声明方式:

复制代码
if (expression) {     statement;     statement;     ... ... }  if (expression) {     statement; } else {     statement2; }  if (expression) {     statement1; } else if (expression1) {     statement2; } else {     statement3; }
复制代码

 

统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹):

ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}' 
[end]size is  8.22339 M

 

循环语句

awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同。

 

数组

  因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。

 

显示/etc/passwd的账户

复制代码
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd 0 root 1 daemon 2 bin 3 sys 4 sync 5 games ......
复制代码

这里使用for循环遍历数组

 

awk编程的内容极多,这里只罗列简单常用的用法,更多请参考 http://www.gnu.org/software/gawk/manual/gawk.html

posted @ 2015-06-11 22:29 Eric_jiang 阅读(182) | 评论 (0)编辑 收藏

linux tee 命令详解
功能说明:读取标准输入的数据,并将其内容输出成文件。
语法:tee [-ai][--help][--version][文件...]
补充说明:tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
参数:
 -a或--append  附加到既有文件的后面,而非覆盖它.
 -i-i或--ignore-interrupts  忽略中断信号。
 --help  在线帮助。
 --version  显示版本信息。

 

用途说明

在执行Linux命令时,我们可以把输出重定向到文件中,比如 ls >a.txt,这时我们就不能看到输出了,如果我们既想把输出保存到文件中,又想在屏幕上看到输出内容,就可以使用tee命令了。tee命令读取标准输入,把这些内容同时输出到标准输出和(多个)文件中(read from standard input and write to standard output and files. Copy standard input to each FILE, and also to standard output. If a FILE is -, copy again to standard output.)。在info tee中说道:tee命令可以重定向标准输出到多个文件(`tee': Redirect output to multiple files. The `tee' command copies standard input to standard output and also to any files given as arguments.  This is useful when you want not only to send some data down a pipe, but also to save a copy.)。要注意的是:在使用管道线时,前一个命令的标准错误输出不会被tee读取。

 

常用参数

格式:tee

只输出到标准输出,因为没有指定文件嘛。

 

格式:tee file

输出到标准输出的同时,保存到文件file中。如果文件不存在,则创建;如果已经存在,则覆盖之。(If a file being written to does not already exist, it is created. If a file being written to already exists, the data it previously
contained is overwritten unless the `-a' option is used.)

 

格式:tee -a file

输出到标准输出的同时,追加到文件file中。如果文件不存在,则创建;如果已经存在,就在末尾追加内容,而不是覆盖。

 

格式:tee -

输出到标准输出两次。(A FILE of `-' causes `tee' to send another copy of input to standard output, but this is typically not that useful as the copies are interleaved.)

 

格式:tee file1 file2 -

输出到标准输出两次,同时保存到file1和file2中。


posted @ 2015-06-11 11:43 Eric_jiang 阅读(161) | 评论 (0)编辑 收藏

一 初级

1)Notepad++ (编辑和查看Perl)

2)Komobo Edit (编辑和执行Perl) 

 

二 高级

A  Perl Express

主页:http://www.perl-express.com/

使用: 很简单


B Eclipse+EPIC+PadWalker

a) 下载解压Eclipse

b)下载EPIC插件之设置 (help->install new software)

 

c)下载EPIC插件之下载 


d)EPIC设置(菜单windows->preferences)

 

c)下载perl模块PadWalker (用来在debug时显示变量值)

 ppm install PadWalker 或cpan> install PadWalker (注意模块名字的大小写)

d)运行和调试perl 

 

 

完! 

posted @ 2015-06-10 15:01 Eric_jiang 阅读(312) | 评论 (0)编辑 收藏

仅列出标题
共57页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last