2014年12月2日星期二

MAC_023:使用dd命令测试硬盘读写速度

运行环境:MAC OS X 10.10.1

1. 测试硬盘纯写速度
time dd if=/dev/zero of=/Users/maping/Share/test bs=8k count=1000000

1000000+0 records in
1000000+0 records out
8192000000 bytes transferred in 10.653967 secs (768915456 bytes/sec)

real 0m10.666s
user 0m0.309s
sys 0m7.085s

2. 测试硬盘纯读速度
time dd if=/Users/maping/Share/test of=/dev/null bs=8k count=1000000

1000000+0 records in
1000000+0 records out
8192000000 bytes transferred in 10.045410 secs (815496836 bytes/sec)

real 0m10.047s
user 0m0.251s
sys 0m3.663s

3. 测试硬盘读写速度
time dd if=/Users/maping/Share/test of=/tmp/test bs=8k count=1000000
1000000+0 records in
1000000+0 records out
8192000000 bytes transferred in 18.354176 secs (446328943 bytes/sec)

real 0m18.364s
user 0m0.338s
sys 0m10.878s

参考文献:
1. http://blog.csdn.net/feng4656/article/details/11054595

2014年11月29日星期六

Linux_090:U盘分区格式化

运行环境:RHEL 7.0

 1. 使用fdisk -l 查看U盘设备
磁盘 /dev/sdc:8127 MB, 8127512576 字节,15874048 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0xcad4ebea

   设备 Boot      Start         End      Blocks   Id  System
/dev/sdc4   *         256    15874047     7936896    c  W95 FAT32 (LBA)

如有必要,执行 dd if=/dev/zero of=/dev/sdb bs=1M count=100,将U盘彻底重写。

2. 使用fdisk /dev/sdc 对U盘进行分区
欢迎使用 fdisk (util-linux 2.23.2)。

更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。


命令(输入 m 获取帮助):m
命令操作
   a   toggle a bootable flag
   b   edit bsd disklabel
   c   toggle the dos compatibility flag
   d   delete a partition
   g   create a new empty GPT partition table
   G   create an IRIX (SGI) partition table
   l   list known partition types
   m   print this menu
   n   add a new partition
   o   create a new empty DOS partition table
   p   print the partition table
   q   quit without saving changes
   s   create a new empty Sun disklabel
   t   change a partition's system id
   u   change display/entry units
   v   verify the partition table
   w   write table to disk and exit
   x   extra functionality (experts only)

命令(输入 m 获取帮助):p

磁盘 /dev/sdc:8127 MB, 8127512576 字节,15874048 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0xcad4ebea

   设备 Boot      Start         End      Blocks   Id  System
/dev/sdc1            2048    15874047     7936000   83  Linux

命令(输入 m 获取帮助):d
已选择分区 1
分区 1 已删除

命令(输入 m 获取帮助):n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
分区号 (1-4,默认 1):1
起始 扇区 (2048-15874047,默认为 2048):
将使用默认值 2048
Last 扇区, +扇区 or +size{K,M,G} (2048-15874047,默认为 15874047):
将使用默认值 15874047
分区 1 已设置为 Linux 类型,大小设为 7.6 GiB

如果想改为 FAT32 类型,输入 t,准备更改文件系统类型。
输入 L,查看文件系统类型 Hex code,Win95 FAT32 的 Hex code 是 b,因此输入 b

命令(输入 m 获取帮助):w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: 设备或资源忙.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
正在同步磁盘。

注意,如果出现上述提示“error 16: 设备或资源忙.”,说明U盘已经被mount了。
此时,使用 mount 命令检查U盘哪些分区被 mount了,将其 umount 后,再执行 fdisk /dev/sdc, w 操作。
比如:mount | grep sdc , umount /dev/sdc4。

3. 执行 partprobe /dev/sdb,激活新划分的分区,无需重启。

4. 使用mkfs 格式化U盘的某个分区
(1)FAT32 格式
/sbin/mkfs -t vfat -F 32 -n GLSINST /dev/sdc1
(2)ext4 格式
/sbin/mkfs ­-t ext4 -­O ^has_journal -­E resize=200000000 -­b 4096 ­-i 819200 ­-L GLSINST /dev/sdc1

参考文献:
1. http://blog.chinaunix.net/uid-26804588-id-3323285.html
2. http://blog.163.com/fj_ltls/blog/static/1380271112011525455935/

2014年11月25日星期二

Linux_089:Windows7 + RHEL7 + Fedora20 三系统启动配置

在一块物理硬盘上先后安装Windows7、RHEL7、Fedora20 三个系统。

RHEL7和Fedora20系统启动项可以互认,Fedora20可以认出Windows7和RHEL7启动项,但是RHEL7不认Windows7启动项。

因此本文介绍如何在RHEL7中配置Windows7的启动项。

1. 修改 /etc/grub.d/40_custom文件

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
# 增加如下设置
menuentry 'Windows 7' {
         insmod part_msdos
         insmod ntfs
         insmod ntldr
         set root=(hd0,1)
         chainloader +1
         boot
 }


注意,这里(hd0,1)指向的是Windows7的启动分区,根据你的机器情况做修改。

2.  重新编译生成启动菜单
 # grub2-mkconfig -o /boot/grub2/grub.cfg

参考文献:
1. http://www.fireinfo.cn/content-11-45963-1.html

2014年10月9日星期四

MAC_022:安裝cmake

运行环境:MAC OS X 10.9.5 +

cmake 下载地址:http://www.cmake.org/download/,我下载的是源码包:cmake-3.0.2.tar。

1. 编译cmake
(1)tar  -xvf cmake-3.0.2.tar
(2)cd cmake-3.0.2
(3)./bootstrap
(4)make
(5)make install

2. 编写一个hello 程序,测试一下cmake
(1)mkdir hello
(2)cd hello
(3)vi main.c,内容如下:
#include <stdio.h>

int main(void) {
    printf("Hello,World\n"
            );
    return 0;
}

 (4)vi CMakeLists.txt,内容如下:
#cmake最低版本需求,不加入此行会受到警告信息
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(HELLO) #项目名称
#把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
AUX_SOURCE_DIRECTORY(. SRC_LIST)
#生成应用程序 hello (在windows下会自动生成hello.exe)
ADD_EXECUTABLE(hello ${SRC_LIST})

(5)mkdir build
(6)cd build
(7)cmake ..
(8)make
(9)./hello


参考文献:
1. http://shitou7630.blog.163.com/blog/static/326995362012410035112/

JDG_008:解决“Cannot run program "protoc": error=2, No such file or directory”问题

环境:MAC OS X 10.9.5 + JBoss Data Grid 6.3.1

学习JBoss Data Grid 时,编译remote-query时,报告如下错误:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (compile-protoc) on project jboss-remote-query-quickstart: An Ant BuildException has occured: Execute failed: java.io.IOException: Cannot run program "protoc": error=2, No such file or directory

[ERROR] around Ant part ...... @ 5:48 in /Users/maping/Share/Software/redhat/datagrid/jboss-datagrid-6.3.1-quickstarts/remote-query/target/antrun/build-main.xml

心想这是官方发布的例子,不该编译不过吧。
于是检查了一遍环境设置,Maven设置,还是不行。

后来发现是缺少protobuf导致的,去 https://code.google.com/p/protobuf/下载protobuf-2.6.0.tar.bz2。
然后:
(1)tar jxvf protobuf-2.6.0.tar.bz2
(2)cd protobuf-2.6.0
(3)./configure
(4)make
(5)make check
(6)make install

 再次编译remote-query,终于通过了。

参考文献:
1. http://blog.csdn.net/zaitianaoxiang/article/details/7639125
2. http://blog.csdn.net/caisini_vc/article/details/5599468


2014年9月10日星期三

Linux_087:常用命令之二十六:rpm

RPM(RedHat Packge Manager)是RedHat公司的软件包管理器,使用它可以很容易地对rpm形式的软件包进行安装、升级、卸载、验证、查询等操作,安装简单,而卸载时也可以将软件安装在多处目录中的文件删除干净,因此推荐初学者尽可能使用rpm形式的软件包。
其中,-v是verbose,打印详细信息;-h是hash,用散列符显示进度。

常用参数说明:
(1)-ivh:安装软件包并显示安装进度。
(2)-Uvh:升级软件包。
(3)-qpl:列出RPM软件包内的文件信息[Query Package list]。
(4)-qpi:列出RPM软件包的描述信息[Query Package install packages]。
(5)-qf:查找指定文件属于哪个RPM软件包[Query File]。
(6)-qc:查询已安装软件的配置文件。
(7)-Va:校验所有的RPM软件包,查找丢失的文件[View Lost]。
(8)-e:删除软件包。

常用命令举例:

(1)查询是否安装了某软件包:# rpm -qa | grep oracle,输出如下:
oracle-xe-11.2.0-1.0.x86_64
这里,oracle-xe是软件包的名字,11.2.0是软件包的版本号,1.0是发行号,x86_64是软件包运行的硬件平台。
注意,grep命令大小写敏感,比如,# rpm -qa | grep mysql,只会输出:
mysql-workbench-community-6.1.7-1.el6.x86_64
而# rpm -qa | grep MySQL,才会输出:
MySQL-client-5.6.20-1.el6.x86_64
MySQL-server-5.6.20-1.el6.x86_64
MySQL-shared-compat-5.6.20-1.el6.x86_64
MySQL-shared-5.6.20-1.el6.x86_64
MySQL-devel-5.6.20-1.el6.x86_64

(2)卸载某软件包:# rpm -e oracle-xe

(3)一次卸载相关的软件包:# rpm -qa | grep MySQL | xargs rpm -e
会提示如下信息:
error: Failed dependencies:
    libmysqlclient.so.16()(64bit) is needed by (installed) postfix-2:2.6.6-2.2.el6_1.x86_64
    libmysqlclient.so.16(libmysqlclient_16)(64bit) is needed by (installed) postfix-2:2.6.6-2.2.el6_1.x86_64
    mysql-libs is needed by (installed) postfix-2:2.6.6-2.2.el6_1.x86_64
这时,可以增加--nodeps参数,不管依赖关系,强行卸载: # rpm -qa | grep MySQL | xargs rpm -e --nodeps

(4)升级某软件包:# rpm -Uvh vim mysql-workbench-community-6.1.7-1.el6.x86_64
实际上升级其实分两步,先卸载,再安装,只不过用户看不到有关信息。
用户可以总是使用 -Uvh来安装软件包,即使没有安装过该软件包,也能正常运行。

参考文献:
1. http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/10/08/2203153.html
2. xiaotianxin132.blog.163.com/blog/static/3511125020101026105338504/

2014年9月3日星期三

Linux_086:常用命令之二十五:update-alternatives


update-alternatives 是用于在多个同类型命令中进行切换的一个脚本。

以RHEL 6.5 为例,来说明如何使用 update-alternatives。

运行:ls -l /usr/bin/java 
结果:lrwxrwxrwx. 1 root root 22 9月   1 23:02 /usr/bin/java -> /etc/alternatives/java
说明:java这个可执行命令实际是一个链接,指向了/etc/alternatives/java。

运行:ls -l /etc/alternatives/java 
结果:lrwxrwxrwx. 1 root root 46 9月   1 23:02 /etc/alternatives/java -> /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
说明:/etc/alternatives/java也是一个链接,指向了/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java,这才是最终的可执行文件。
之所以建立这样两个链接,是为了方便脚本程序的编写和系统的管理。

当我们安装了新的JDK时,特别是以解压缩的方式安装时,需要执行update-alternatives命令,切换到新安装的JDK。
以jdk-7u67-linux-x64.tar.gz为例,解压缩到/u01/app/java/jdk1.7.0_67后,
需要执行如下语句:
(1)sudo update-alternatives --install /usr/bin/java java /u01/app/java/jdk1.7.0_67/bin/java 300
(2)sudo update-alternatives --install /usr/bin/javac javac /u01/app/java/jdk1.7.0_67/bin/javac 300
(3)sudo update-alternatives --config java
(输入代表/u01/app/java/jdk1.7.0_67/bin/java 的数字)
(4)sudo update-alternatives --config javac
(输入代表/u01/app/java/jdk1.7.0_67/bin/javac 的数字)

如果有必要,还可以执行 sudo update-alternatives --remove 删除不正确的注册项。

参考文献:
1. http://paddy-w.iteye.com/blog/958062

Linux_085:常用命令之二十四:gzip gunzip

1. 压缩并保留原始文件:gzip –c filename > filename.gz 

2. 解压并保留原始文件:gunzip –c filename.gz > filename

3. 压缩当前目录每个文件(每个文件生成一个.gz压缩文件):gzip *


4. 解压当前目录每个.gz文件(每个.gz文件生成一个解压后文件):gzip -d *

5. 解压某个.gz文件:gzip -d filename.gz

6. 查看每个压缩文件的信息:gzip -l *

参考文献:
1. http://baike.baidu.com/view/966625.htm?fr=aladdin
2. http://www.jb51.net/LINUXjishu/11041.html

Cloud_023:100M宽带为何下载速度只有10M?

其实我们被电信运行商“忽悠”了,他们所说的100M,其实指的是100Mbps,注意是小写的b,而不是大写的B。

其中ps指的是“每秒”,用符号来表示就是“/s”,b是代表位,Kb代表的是千位。
Kbps指的是网络速度,也就是每秒钟传送多少个千位的信息。
电信运营商都是用Kbps来表示网络的传输速度。
 
那么大B和小b的的区别是什么呢?
这里要普及一下计算机基础知识,我们知道,计算机中的信息都是二进制的0和1来表示,其中每一个0或1被称作一个位,用小写b表示,即bit(位);大写B表示byte,即字节,1个字节=8个位,即1B=8b。

现在问题变得简单了,100Mbps的带宽,除以8,才是我们通常所理解的带宽,即约等于12M,刨去网络本身的信号的传输以及损耗,最后能够为用户使用的,最多是10MBps。

网速不仅仅与带宽有关系,跟网卡也有很大关系,我们通常所说的千兆网卡、万兆网卡,指的也是bps,而不是Bps。所以,1000Mbps的网卡,最多能用100MBps来传输数据。

参考文献:
1. http://www.weste.net/2009/3-4/14452590475.html
2. http://download.csdn.net/download/aiiaiyou/1961741
3. http://zhidao.baidu.com/link?url=2sy3lqs7bnNYmabI7nRlrYBNWXmmU2V_ITjIS3PFB8joNWZ1DXtgiYNzg1DR5XiI8gxAjPQah_wehEuGJEJ_iK

2014年8月31日星期日

MAC_021:Eclipse常用快捷键

运行环境:MAC OS X 10.9.4 + JBoss Developer Studio 5.0.2

1. Command + O:显示大纲

2. 
Command + 1:快速修复

3. 
Command + D:删除当前行


4. Command + Option + ↓:复制当前行到下一行


5. Command + Option + ↑:复制当前行到上一行

6. 
Option + ↓:当前行和下面一行交互位置


7. Option + ↑:当前行和上面一行交互位置


8. Option + ←:前一个编辑的页面

9. 
Option + →:下一个编辑的页面


10. Option + Return:显示当前选择资源的属性
 *

11. Shift + Return:在当前行的下一行插入空行

12. 
Shift + Control + Return:在当前行插入空行


13. Control + Q:定位到最后编辑的地方


14. Control + M:最大化当前的Edit或View(再按则最小化)
*

15. Command + /:注释当前行,再按则取消注释

16. 
Command + T:快速显示当前类的继承结构

17. 
Command + W:关闭当前Editer

18. 
Command + K:参照当前选中的Word快速定位到下一个


19. Command + E:快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)

20. 
Option + /:代码助手完成一些代码的插入(俗称“智能提示”)

21. 
Command + Shift + E:显示管理当前打开的所有的View的管理器

22. 
Command + J:正向增量查找(按下Command + J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在Stutes Line中显示没有找到了)

23. 
Command + Shift + J:反向增量查找


24. Command + Shift + W:关闭所有打开的Editer

25. 
Command + Shift + X:把当前选中的文本全部变为大写


26. Command + Shift + Y:把当前选中的文本全部变为小写


27. Command + Shift + F:格式化当前代码 *

28. 
Command + Shift + P:定位到对于的匹配符(譬如{})(从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)*

29. Option + Command + R:重命名(尤其是变量和类的Rename效果比较明显)


30. Option + Shift + M:抽取方法(这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)


31. Option + Command + C:修改函数结构(有N个函数调用了这个方法,修改一次就搞定)

32. 
Option + Command + L:抽取本地变量(可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)

33. 
Option + Shift + F:把Class中的Local变量变为Field变量(比较实用的功能)


34. Command + Z:Undo

35. Command + F:查找与替换

2014年8月26日星期二

Linux_083:RHEL下安装PostgreSQL

运行环境:RHEL 6.5  + PostgreSQL 9.3.5

安装方式有rpm方式、yum方式、源代码方式、图形化方式,这里介绍yum方式。

1. 下载PostgreSQL 9.3.5
下载地址:http://www.postgresql.org/download/,进入下载页面后,选择Red Hat Linux。
然后找到“PostgreSQL Yum Repository”,点击“repository RPM listing”,在最新的发布版本PostgreSQL 9.3中点击选择“Red Hat Enterprise Linux 6 - x86_64”下载。

2. 运行 yum install pgdg-redhat93-9.3-1.noarch.rpm 安装PostgreSQL Yum 源

3. 运行 yum install postgresql93-server 安装PostgreSQL Server

4. 初始化数据库 service postgresql-9.3 initdb

5. 开机启动 chkconfig postgresql-9.3 on

6. 查看安装 rpm -qa | grep postgresql,输出如下:postgresql93-libs-9.3.5-1PGDG.rhel6.x86_64
postgresql93-server-9.3.5-1PGDG.rhel6.x86_64
postgresql93-9.3.5-1PGDG.rhel6.x86_64

7. 启动/停止数据库 service postgresql-9.3 start|stop|restart|status
查看更多参数,可以输入service postgresql-9.3,输出如下:
Usage: /etc/init.d/postgresql-9.3 {start|stop|status|restart|upgrade|condrestart|try-restart|reload|force-reload|initdb|promote}

8. 确认数据库可以本地访问
# su - postgres
-bash-4.1$ psql
psql (9.3.5)
postgres-# \q
-bash-4.1$ psql -l
                                     资料库列表
   名称    |  拥有者  | 字元编码 |  校对规则   |    Ctype    |       存取权限  
    
-----------+----------+----------+-------------+-------------+------------------
-----
 postgres  | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 |
 template0 | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/postgres     
    +
           |          |          |             |             | postgres=CTc/post
gres
 template1 | postgres | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/postgres     
    +
           |          |          |             |             | postgres=CTc/post
gres
(3 行记录)

9. 允许远程访问PostgreSQL数据库
(1)修改 /var/lib/pgsql/9.3/data/postgresql.conf文件
将文件中的listen_addresses项值设定为“*”。
(2)修改 /var/lib/pgsql/9.3/data/pg_hba.conf文件

在host    all             all             127.0.0.1/32            ident这一行之下,增加一行,内容如下:
host    all             all             192.168.0.0/24          trust

如果你的网段地址是其它的,请修改192.168.0.0/24部分
注意,这里必须是trust,否则使用SQuirreLSQL连不上。
因为SQuirreLSQL使用的是jdbc方式连接,这里要设置成trust。
使用pgAdmin III是可以正确连接的。这主要是由于用户密码认证方式引起的,Postgresql数据库安装好后默认采用md5密码加密认证方式。
各个字段说明:
(1)TYPE:可选的值有:local、host。
前者只能允许本地的用户登陆Postgres数据库;后者可以接受远程客户登陆。
(2)DATABASE:连接用户可以使用的数据库名字。
可以使Postgres的一个具体的数据库名,也可以使用“all”来允许用户访问所有数据库。
(3)USER:可以指定某个具体的用户来连接Postgres数据库(还要结合后面的地址字段)。
可以使用“all”来允许所有用户连接数据库。
(4)DIDR-ADDRESS:IP地址与掩码的另一种表示方法。
Postgres是通过这个字段来了解,允许那些IP或IP网段连接此服务器。
它的格式是: IP地址/掩码。
这个掩码和子网掩码是一个道理,只不过是用一个小于等于32的正数来表示,表示的是子网掩码中高几位为1。
比如,255.255.255.0 就是“24”,说明高24位是1。
192.168.0.1/32 相当于 IP为192.168.0.1,子网掩码为255.255.255.255的网段,
很显然,这只表明192.168.0.1IP自己。
(5)METHOD:这是验证方法。可选的值有:
  • reject:拒绝这个IP的用户访问
  • md5:密码以md5作为hash编码
  • password:密码作为明文传输
  • krb5:密码以krb5作为hash编码
下面举例说明:
(1)host all all 192.168.0.1/32 md5
允许IP为192.168.0.1的所有用户登陆到Postgres服务器的所有数据库,采用md5验证。
(2)host testdb testuser 192.168.0.1/24 md5
允许用户testuser在192.168.0.XX的网段任意机器登陆Postgres服务器,并且只能使用数据库testdb,采用md5验证。

10. 使用SQuirreLSQL客户端连接PostgreSQL数据库
下载PostgreSQL jdbc Driver,下载地址:http://jdbc.postgresql.org/download.html。
根据说明,选择JDBC41 Postgresql Driver, Version 9.3-1102

11. 查询都有哪些schema?
SELECT nspname FROM pg_namespace;

12. 查询某schema下都有哪些表?
SELECT * FROM pg_tables WHERE schemaname ='camel';

13. 查询某个表结构?
\d camel.orders

参考文献:
1. http://www.cnblogs.com/mchina/archive/2012/06/06/2539003.html
2. http://blog.chinaunix.net/uid-354915-id-3498734.html
3. http://www.cnblogs.com/jevonsea/archive/2013/01/24/2874184.html
4. http://www.cnblogs.com/shineqiujuan/archive/2010/08/14/1799755.html
5. http://www.blogjava.net/hengic/articles/217873.html
6. http://www.360doc.com/content/13/0822/10/10384031_309039914.shtml

2014年8月24日星期日

Linux_082:常用命令之二十三:mount umount

运行环境:RHEL 6.5

mount 命令格式:mount option [-o mount_options] device dir

 1. -t vfstype 指定文件系统的类型。常用类型有:
(1)光盘或光盘镜像:iso9660
(2)DOS FAT16 文件系统:msdos
(3)Windows 9x fat32 文件系统:vfat
(4)Windows NT ntfs文件系统:ntfs
(5)Windows 文件网络共享:smbfs
(6)UNIX(LINUX)文件网络共享:nfs

2. -a 挂载 /etc/fstab文件中满足条件的文件系统
格式: mount -a -t type -o mount_options 不需要指定设备/目录

3. -f 测试 mount 系统,只检查设备和目录,并不真正挂载文件系统

4. -o options 指定设备或档案的挂接方式。常用的参数有:
(1)loop:用来把一个文件当成硬盘分区挂接上系统
(2)ro:采用只读方式挂接设备
(3)rw:采用读写方式挂接设备
(4)iocharset:指定访问文件系统所用字符集

5. device 要挂载的设备

6. dir 设备在系统上的挂载点

常用命令举例:

挂载其它设备前,首先应该使用fdisk -l 命令查看系统的硬盘和分区情况。

1. 挂载光盘或光盘iso镜像文件
(1)建立一个目录用作挂载点:# mkdir /mnt/iso
(2)# mount -o loop -t iso9660 /home/maping/cl280-rhel-6.4-r18156.iso /mnt/iso
(3)使用df -lh命令来检查/mnt/iso是否挂载了。
如果有多个光盘iso镜像文件,需要先卸载文件先挂载的iso像镜:umount /home/maping/cl280-rhel-6.4-r18156.iso,然后再挂载新的光盘iso镜像文件。

2. 挂载NTFS格式硬盘
(1)建立一个目录用作挂载点:# mkdir /mnt/ntfs
(2)# mount -t ntfs /dev/hda6 /mnt/ntfs

3. 挂载U盘
(1)建立一个目录用作挂载点:# mkdir /mnt/udisk
(2)# mount -o iocharset=utf8 /dev/sdb1 /mnt/udisk
这里使用了-o iocharset=utf8,是为了防止中文目录文件显示为问号。

4. 挂载光驱
 一般来说,光驱的设备文件是/dev/hdc。
(1)建立一个目录用作挂载点:# mkdir /mnt/cdrom
(2)# mount -o iocharset=utf8 /dev/hdc /mnt/cdrom

5. 挂载软驱
一般来说,软驱的设备文件是/dev/fd0。
(1)建立一个目录用作挂载点:# mkdir /mnt/floopy
(2)# mount -o iocharset=utf8 /dev/fd0 /mnt/floopy

6. 挂载nfs
(1)建立一个目录用作挂载点:# mkdir /mnt/nfs
(2)# mount -t nfs -o rw 10.140.133.9:/export/home/sunky /mnt/nfs

7. 挂载smbfs
(1)建立一个目录用作挂载点:# mkdir /mnt/samba
(2)# mount -t smbfs -o username=administrator,password=pldy123 //10.140.133.23/c$ /mnt/samba
注:administrator 和 pldy123 是IP地址为10.140.133.23 windows计算机的一个用户名和密码, c$是这台计算机的一个磁盘共享。

参考文献:
1. http://blog.csdn.net/hancunai0017/article/details/6995284
2. http://taisongts08.blog.163.com/blog/static/78134350201076111728689/
3. http://www.cnblogs.com/BloodAndBone/archive/2010/10/14/1851598.html
4. http://adelphos.blog.51cto.com/2363901/1613483/

Linux_081:常用命令之二十二:dd

运行环境:RHEL 6.5

1.  使用0填充 192.168.0.1~6机器的第1块硬盘(/dev/sda),大小为1M,填充10次,然后重启。

$ sudo -i
# for i in {1..6}
>do ssh 192.168.0.$i "dd if=/dev/zero of=/dev/sda bs=1M count=10;reboot"
>done
   
由于/dev/sda通常用作启动硬盘,因此执行上面的命令后,MBR将遭到破坏,重启时,由于没有引导分区,只能选择其它方式启动(光盘、U盘、网络)。
在重新初始化教室环境时,这个命令比较有用,所有机器重启后,选择网络安装,一次搞定多台机器环境安装。

2.  拷贝光盘内容到指定文件夹,并保存为cd.iso文件
# dd if=/dev/cdrom(hdc) of=/root/cd.iso

这样做的好处是:
(1)减轻了光驱的磨损。
(2)现在硬盘容量巨大存放几十个光盘镜像文件不成问题,使用mount/umount命令随用随调十分方便。
(3)硬盘的读取速度要远远高于光盘的读取速度,CPU占用率大大降低。

参考文献:
1. http://blog.sina.com.cn/s/blog_8b5bb24f01016y3o.html
2. http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=2325561&highlight=

2014年8月23日星期六

Linux_080:RHEL下使用vpnc连接VPN

运行环境:RHEL 6.5

1. 下载EPEL
下载地址: http://dl.fedoraproject.org/pub/epel/6/i386/
找到epel-release-6-8.noarch.rpm,点击下载。
或者用wget http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm 下载。

2. 安装EPEL
# chmod a+x epel-release-6-8.noarch.rpm
# rpm -ivh epel-release-6-8.noarch.rpm

3. 安装vpnc
# yum clean all
# yum install vpnc

4. 配置vpnc
# vi /etc/vpnc/default.conf
修改后,内容如下:

#IPSec gateway my.vpn.gateway
#IPSec ID my.ipsec.id
#IPSec secret mysecret
# your username goes here:
#Xauth username

IPSec gateway 203.114.244.92
IKE Authmode psk
IPSec ID RH-standard
IPSec secret nodnerip
IKE DH Group dh2
NAT Traversal Mode natt
Xauth username pma

5. 启动/停止vpnc
(1)启动:# vpnc
(2)停止:# vpnc-disconnect

参考文献:
1. http://www.cncentos.com/forum.php?mod=viewthread&tid=1751&extra=

MAC_020:使用vpnc连接VPN

运行环境:MAC OS X 10.9.4

之所以使用vpnc而不使用MAC自带的VPN客户端,是发现自带的VPN客户端有时候不好使。

1. 安装vpnc,运行sudo port install vpnc

注意,需要事先安装MacPorts,安装步骤请参考《MAC下安装MacPorts》。
Password:
--->  Computing dependencies for vpnc
--->  Dependencies to be installed: tuntaposx
--->  Fetching archive for tuntaposx
--->  Attempting to fetch tuntaposx-20111101_0.darwin_13.x86_64.tbz2 from http://packages.macports.org/tuntaposx
--->  Attempting to fetch tuntaposx-20111101_0.darwin_13.x86_64.tbz2.rmd160 from http://packages.macports.org/tuntaposx
--->  Installing tuntaposx @20111101_0
--->  Activating tuntaposx @20111101_0
--->  Cleaning tuntaposx
--->  Fetching archive for vpnc
--->  Attempting to fetch vpnc-0.5.3_0.darwin_13.x86_64.tbz2 from http://packages.macports.org/vpnc
--->  Attempting to fetch vpnc-0.5.3_0.darwin_13.x86_64.tbz2.rmd160 from http://packages.macports.org/vpnc
--->  Installing vpnc @0.5.3_0
--->  Activating vpnc @0.5.3_0
--->  Cleaning vpnc
--->  Updating database of binaries
--->  Scanning binaries for linking errors
--->  No broken files found.

2. 下载并安装TunTap
下载地址:http://tuntaposx.sourceforge.net/index.xhtml

3. 修改/opt/local/etc/vpnc/default.conf,修改后内容如下:
#IPSec gateway
#IPSec ID
#IPSec secret
#IKE Authmode hybrid
#Xauth username
#Xauth password

IPSec gateway 203.114.244.92
IKE Authmode psk
IPSec ID RH-standard
IPSec secret nodnerip
IKE DH Group dh2
NAT Traversal Mode natt
Xauth username pma


4. 启动/停止 vpnc
(1)启动:sudo vpnc
如果遇到如下错误:
MaPingdeMacBook-Pro:vpnc root# vpnc              
Enter password for pma@203.114.244.92:
Error binding to source port. Try '--local-port 0'
Failed to bind to 0.0.0.0:500: Address already in use
按照提示,使用sudo vpnc --local-port 0 启动vpnc,输出如下:
Enter password for pma@203.114.244.92:
Connect Banner:
| Unauthorized Access to this or any other Red Hat Inc. device
| is strictly prohibited. Violators will be prosecuted.
|

route: writing to routing socket: Can't assign requested address
add net 10.66.114.94: gateway 10.66.114.94: Can't assign requested address
add host 203.114.244.92: gateway 192.168.0.1
add net 172.16.0.0: gateway 10.66.114.94
add net 10.0.0.0: gateway 10.66.114.94
add net 10.66.127.17: gateway 10.66.114.94
add net 10.68.5.26: gateway 10.66.114.94
VPNC started in background (pid: 24992)...

(2)停止:sudo vpnc-disconnect,输出如下:
Terminating vpnc daemon (pid: 24894)       

参考文献:
1. http://vlinux.iteye.com/blog/593613
2. http://jingyan.baidu.com/article/48b37f8d4c44cb1a646488a1.html

2014年8月18日星期一

JDG_007:JDG 6.3 Quick Start 例子学习:GUI Demo

运行环境:JBoss Data Grid 6.3.0

GUI Demo 是Infinispan 6.0.2中的例子,运行在Library mode下。

下载Infinispan 6.0.2,下载地址:http://infinispan.org/。

1. 多个GUI Demo运行在一个Local Cluster之中

1.1 解压为infinispan-6.0.2.Final-all,进入bin目录,然后执行./runGuiDemo.sh。

1.2 再次执行./runGuiDemo.sh。

1.3 在1或2的GUI上操作数据,会发现在另一个GUI上都可以看到数据。

1.4 默认情况下,GUI Demo使用的配置文件是etc/config-samples/gui-demo-cache-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<infinispan
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="urn:infinispan:config:6.0 http://www.infinispan.org/schemas/infinispan-config-6.0.xsd"
      xmlns="urn:infinispan:config:6.0">

   <global>
      <transport clusterName="demoCluster"/>
      <globalJmxStatistics enabled="true"/>
   </global>

   <default>
      <jmxStatistics enabled="true"/>
      <clustering mode="distribution">
         <l1 enabled="true" lifespan="60000"/>
         <hash numOwners="2" />
         <sync/>
      </clustering>
   </default>
</infinispan>

说明:
(1)你可以根据需要多次执行./runGuiDemo.sh,所有的GUI Demo实例都在一个Local Cluster之中。
(2)你也可以指定自己的配置文件:-Dinfinispan.demo.cfg=file:/path/to/config.xml

2. 多个GUI Demo运行在多个Local Cluster之中

2.1 进入bin目录,然后执行./runGuiDemo.sh ../etc/config-samples/relay1.xml两次

<?xml version="1.0" encoding="UTF-8"?>
<infinispan
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="urn:infinispan:config:6.0 http://www.infinispan.org/schemas/infinispan-config-6.0.xsd"
      xmlns="urn:infinispan:config:6.0">
  
   <global>
      <transport clusterName="demoCluster1">
         <properties>
            <property name="configurationFile" value="config-samples/jgroups-relay1.xml" />
         </properties>
      </transport>
      <globalJmxStatistics enabled="true"/>
   </global>

   <default>
      <jmxStatistics enabled="true"/>
      <clustering mode="distribution">
         <l1 enabled="false" lifespan="10000"/>
         <hash numOwners="2" />
         <!--<hash numOwners="2" class="org.infinispan.distribution.ch.TopologyAwareConsistentHash"/>-->
         <async/>
      </clustering>
   </default>
</infinispan>

2.2 进入bin目录,然后执行./runGuiDemo.sh ../etc/config-samples/relay2.xml两次

<?xml version="1.0" encoding="UTF-8"?>
<infinispan
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="urn:infinispan:config:6.0 http://www.infinispan.org/schemas/infinispan-config-6.0.xsd"
      xmlns="urn:infinispan:config:6.0">
  
   <global>
      <transport clusterName="demoCluster2">
         <properties>
            <property name="configurationFile" value="config-samples/jgroups-relay2.xml" />
         </properties>
      </transport>
      <globalJmxStatistics enabled="true"/>
   </global>

   <default>
      <jmxStatistics enabled="true"/>
      <clustering mode="distribution">
         <l1 enabled="false" lifespan="10000"/>
         <hash numOwners="2" />
         <!--<hash numOwners="2" class="org.infinispan.distribution.ch.TopologyAwareConsistentHash"/>-->
         <async/>
      </clustering>
   </default>
</infinispan>

参考文献:
1. http://infinispan.org/docs/6.0.x/getting_started/getting_started.html

JDG_006:JDG 6.3 Quick Start 例子学习:Clustered Cache

运行环境:JBoss Data Grid 6.3.0

Clustered Cache 是Infinispan Quick Start中的例子,运行在Library mode下。
代码地址:https://github.com/infinispan/infinispan-quickstart/tree/master/clustered-cache。

下载后,进入clustered-cache目录,然后

1. 编译
mvn clean compile dependency:copy-dependencies -DstripVersion

2. 运行在replication模式下
 (1)java -cp "target/classes:target/dependency/*" org.infinispan.quickstart.clusteredcache.Node -r A
 (2)java -cp "target/classes:target/dependency/*" org.infinispan.quickstart.clusteredcache.Node -r B
 (2)java -cp "target/classes:target/dependency/*" org.infinispan.quickstart.clusteredcache.Node -r C

可以继续启动多个节点,各个节点之间彼此全复制所有的缓存项目。


3. 运行在distribution模式下
 (1)java -cp "target/classes:target/dependency/*" org.infinispan.quickstart.clusteredcache.Node -d A
 (2)java -cp "target/classes:target/dependency/*" org.infinispan.quickstart.clusteredcache.Node -d B
 (2)java -cp "target/classes:target/dependency/*" org.infinispan.quickstart.clusteredcache.Node -d C 
可以继续启动多个节点,以分布式的方式在各个节点上存储数据,每个缓存项目数据有2份。

4. Node.java
package org.infinispan.quickstart.clusteredcache;

import org.infinispan.Cache;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.quickstart.clusteredcache.util.LoggingListener;
import org.infinispan.util.logging.BasicLogFactory;
import org.jboss.logging.BasicLogger;
import org.jboss.logging.Logger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class Node {

    private static final BasicLogger log = Logger.getLogger(Node.class);

    private final boolean useXmlConfig;
    private final String cacheName;
    private final String nodeName;
    private volatile boolean stop = false;

    public Node(boolean useXmlConfig, String cacheName, String nodeName) {
        this.useXmlConfig = useXmlConfig;
        this.cacheName = cacheName;
        this.nodeName = nodeName;
    }

    public static void main(String[] args) throws Exception {
        boolean useXmlConfig = false;
        String cache = "repl";
        String nodeName = null;

        for (String arg : args) {
            if ("-x".equals(arg)) {
                useXmlConfig = true;
            } else if ("-p".equals(arg)) {
                useXmlConfig = false;
            } else if ("-d".equals(arg)) {
                cache = "dist";
            } else if ("-r".equals(arg)) {
                cache = "repl";
            } else {
                nodeName = arg;
            }
        }
        new Node(useXmlConfig, cache, nodeName).run();
    }

    public void run() throws IOException, InterruptedException {
        EmbeddedCacheManager cacheManager = createCacheManager();
        final Cache cache = cacheManager.getCache(cacheName);
        System.out.printf("Cache %s started on %s, cache members are now %s\n", cacheName, cacheManager.getAddress(),
                cache.getAdvancedCache().getRpcManager().getMembers());

        // Add a listener so that we can see the puts to this node
        cache.addListener(new LoggingListener());

        printCacheContents(cache);

        Thread putThread = new Thread() {
            @Override
            public void run() {
                int counter = 0;
                while (!stop) {
                    try {
                        cache.put("key-" + counter, "" + cache.getAdvancedCache().getRpcManager().getAddress() + "-" + counter);
                    } catch (Exception e) {
                        log.warnf("Error inserting key into the cache", e);
                    }
                    counter++;

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        break;
                    }
                }
            }
        };
        putThread.start();

        System.out.println("Press Enter to print the cache contents, Ctrl+D/Ctrl+Z to stop.");
        while (System.in.read() > 0) {
            printCacheContents(cache);
        }

        stop = true;
        putThread.join();
        cacheManager.stop();
        System.exit(0);
    }

    /**
     * {@link org.infinispan.Cache#entrySet()}
     *
     * @param cache
     */
    private void printCacheContents(Cache cache) {
        System.out.printf("Cache contents on node %s\n", cache.getAdvancedCache().getRpcManager().getAddress());

        ArrayList> entries = new ArrayList>(cache.entrySet());
        Collections.sort(entries, new Comparator>() {
            @Override
            public int compare(Map.Entry o1, Map.Entry o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });
        for (Map.Entry e : entries) {
            System.out.printf("\t%s = %s\n", e.getKey(), e.getValue());
        }
        System.out.println();
    }

    private EmbeddedCacheManager createCacheManager() throws IOException {
        if (useXmlConfig) {
            return createCacheManagerFromXml();
        } else {
            return createCacheManagerProgrammatically();
        }
    }

    private EmbeddedCacheManager createCacheManagerProgrammatically() {
        System.out.println("Starting a cache manager with a programmatic configuration");
        DefaultCacheManager cacheManager = new DefaultCacheManager(
                GlobalConfigurationBuilder.defaultClusteredBuilder()
                .transport().nodeName(nodeName).addProperty("configurationFile", "jgroups.xml")
                .build(),
                new ConfigurationBuilder()
                .clustering()
                .cacheMode(CacheMode.REPL_SYNC)
                .build()
        );
        // The only way to get the "repl" cache to be exactly the same as the default cache is to not define it at all
        cacheManager.defineConfiguration("dist", new ConfigurationBuilder()
                .clustering()
                .cacheMode(CacheMode.DIST_SYNC)
                .hash().numOwners(2)
                .build()
        );
        return cacheManager;
    }

    private EmbeddedCacheManager createCacheManagerFromXml() throws IOException {
        System.out.println("Starting a cache manager with an XML configuration");
        System.setProperty("nodeName", nodeName);
        return new DefaultCacheManager("infinispan.xml");
    }

}
 

5. infinispan.xml

<?xml version="1.0" encoding="UTF-8"?>
<infinispan
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:infinispan:config:6.0 http://www.infinispan.org/schemas/infinispan-config-6.0.xsd"
    xmlns="urn:infinispan:config:6.0">
    <global>
        <transport nodeName="${nodeName}">
            <properties>
                <property name="configurationFile" value="jgroups.xml"/>
            </properties>
        </transport>
    </global>

    <default>
        <!-- Configure a synchronous replication cache -->
        <clustering mode="replication">
            <sync/>
        </clustering>
    </default>

    <namedCache name="repl">
        <!-- Use the configuration of the default cache as it is -->
    </namedCache>

    <namedCache name="dist">
        <!-- Configure a synchronous distribution cache -->
        <clustering mode="distribution">
            <sync/>
            <hash numOwners="2"/>
        </clustering>
    </namedCache>

</infinispan>

2014年8月17日星期日

MAC_019:安装和使用PostgreSQL

运行环境:MAC OS X 10.9.4 + PostgreSQL 9.3.4

1. 使用brew安装:brew install postgresql -v
运行后,会提示如下信息:
Warning: postgresql-9.3.4 already installed
说明我的MAC已经自带了PostgreSQL 9.3.4,那就直接使用吧。

2. 启动PostgreSQL

pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start

3. 停止PostgreSQL
pg_ctl -D /usr/local/var/postgres stop -s -m fast

4. 创建用户:rhqadmin
createuser rhqadmin -P,输出如下:
Enter password for new role:
Enter it again:

5.创建数据库:rhqdb,owner为rhqadmin
createdb rhqdb -O rhqadmin -E UTF8 -e,输出如下:
CREATE DATABASE rhqdb OWNER rhqadmin ENCODING 'UTF8';

更多数据库创建信息可以 "createdb --help" 查看。

6. 连接数据库:rhqdb,用户:rhqadmin
psql -U rhqadmin -d rhqdb -h 127.0.0.1,输出如下:
psql (9.3.4)
Type "help" for help.

rhqdb=>

7. 连接PostgreSQL数据库后,进入数据库操作
(1)显示已创建的数据库:\l
在不连接进 PostgreSQL 数据库的情况下,也可以在终端上查看显示已创建的列表:psql -l
(2)显示数据库表:\c rhqdb
(3)创建一个名为 test 的表:CREATE TABLE test(id int, text VARCHAR(50));
(4)插入一条记录:INSERT INTO test(id, text) VALUES(1, 'sdfsfsfsdfsdfdf');
(5)查询记录:SELECT * FROM test WHERE id = 1;
(6)更新记录:UPDATE test SET text = 'aaaaaaaaaaaaa' WHERE id = 1;
(7)删除指定的记录:DELETE FROM test WHERE id = 1;
(8)删除表:DROP TABLE test;
(9)删除数据库:DROP DATABASE dbname;
在不连接进 PostgreSQL 数据库的情况下,也可以在终端上删除数据库:dropdb -U rhqadmin rhqdb

参考文献:
1. http://dhq.me/mac-postgresql-install-usage

MAC_018:制作U盘启动盘

运行环境:MAC OS X 10.9.4

1. 把iso文件转换为dmg格式
语法如下:
hdiutil convert -format UDRW -o /path/to/generate/img/file /path/to/your/iso/file
例如:
hdiutil convert -format UDRW -o ./rhel-server-6.5-x86_64-dvd.img ./rhel-server-6.5-x86_64-dvd.iso
该命令会生成一个.img的磁盘镜像文件,MAC OS X会默认追加一个.dmg,即生成的文件后缀是.img.dmg。

2. 查看U盘的盘符:diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *500.3 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS Macintosh HD            499.4 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                            RHEL_6.4 x86_64        *3.7 GB     disk1
/dev/disk2
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     Apple_partition_scheme                        *7.3 MB     disk2
   1:        Apple_partition_map                         32.3 KB    disk2s1
   2:                  Apple_HFS Adobe Flash Player I... 7.3 MB     disk2s2
/dev/disk3
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *16.0 GB    disk3
   1:             Windows_FAT_32 雨林木风 GH             16.0 GB    disk3s4

可以看出,我这里的U盘的盘符是/dev/disk3。

3.  卸载U盘:diskutil unmountDisk /dev/disk3

4. 将镜像写入U盘:sudo dd if=rhel-server-6.5-x86_64-dvd.img.dmg of=/dev/rdisk3 bs=1m
此处要注意,of参数指定的设备名千万别写错了,否则悔之晚矣。
of参数指定的设备名,可以用上面找到的/dev/disk3,也可以用/dev/rdisk3,此处的“r”据说会写入较快。

5. 推出U盘:diskutil eject /dev/disk3

现在,可以用U盘引导启动并进行RHEL 6.5系统的安装啦!

参考文献:
1. http://jiangbo.me/blog/2011/11/09/create_ubuntu_usb_startdisk_on_mac/
2. http://blog.csdn.net/jiangbo_hit/article/details/6952151
3. http://www.linuxidc.com/Linux/2013-04/82973.htm

2014年8月15日星期五

JDG_005:JDG 6.3 Quick Start 例子学习:Football

运行环境:JBoss Data Grid 6.3.0

Football运行在remote client-server 模式下,展示了如何使用Hot Rod、Memcached、Rest客户端来访问Cache。

学习重点:

1. 配置Cache
(1)配置datasource
<subsystem xmlns="urn:jboss:domain:datasources:1.1">
            <!-- Define this Datasource with jndi name java:jboss/dataso urces/ExampleDS -->
            <datasources>
                <datasource jndi-name="java:jboss/datasources/ExampleDS"
                            pool-name="ExampleDS" enabled="true" use-java-context="true">
                    <!-- The connection URL uses H2 Database Engine with in-memory database called test -->
                    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>
                    <!-- JDBC driver name -->
                    <driver>h2</driver>
                    <!-- Credentials -->
                    <security>
                        <user-name>sa</user-name>
                        <password>sa</password>
                    </security>
                </datasource>
                <!-- Define the JDBC driver called 'h2' -->
                <drivers>
                    <driver name="h2" module="com.h2database.h2">
                        <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
                    </driver>
                </drivers>
            </datasources>        
      </subsystem>

(2)配置Cache
        <subsystem xmlns="urn:infinispan:server:core:6.1" default-cache-container="local">
            <cache-container name="local" default-cache="default" statistics="true">
                <local-cache name="default" start="EAGER">
                    <locking isolation="NONE" acquire-timeout="30000" concurrency-level="1000" striping="false"/>
                    <transaction mode="NONE"/>
                </local-cache>
                <local-cache name="memcachedCache" start="EAGER" statistics="true">
                    <locking isolation="NONE" acquire-timeout="30000" concurrency-level="1000" striping="false"/>
                    <transaction mode="NONE"/>
                </local-cache>
                <local-cache name="namedCache" start="EAGER" statistics="true"/>
                <!-- ADD a local cache called 'teams' -->
                <local-cache name="teams" start="EAGER"
                             batching="false" statistics="true">
                    <!-- Disable transactions for this cache -->
                    <transaction mode="NONE" />
                    <!-- Define the JdbcBinaryStores to point to the ExampleDS previously defined -->
                    <string-keyed-jdbc-store datasource="java:jboss/datasources/ExampleDS" passivation="false"
                                             preload="false" purge="false">
                        <!-- Define the database dialect -->
                        <property name="databaseType">H2</property>
                        <!-- specifies information about database table/column names and data types -->
                        <string-keyed-table prefix="JDG">
                            <id-column name="id" type="VARCHAR"/>
                            <data-column name="datum" type="BINARY"/>
                            <timestamp-column name="version" type="BIGINT"/>
                        </string-keyed-table>
                    </string-keyed-jdbc-store>
                </local-cache>
                <!-- End of local cache called 'teams' definition -->
            </cache-container>
            <cache-container name="security"/>
</subsystem>

可以看出,Hot Rod 和 REST endpoints 使用名为teams的Cache,而memcached endpoint默认使用memcachedCache。

(3)配置rest-connector,去掉认证
 <subsystem xmlns="urn:infinispan:server:endpoint:6.1">
            <hotrod-connector socket-binding="hotrod" cache-container="local">
                <topology-state-transfer lazy-retrieval="false" lock-timeout="1000" replication-timeout="5000"/>
            </hotrod-connector>
            <memcached-connector socket-binding="memcached" cache-container="local"/>
            <rest-connector virtual-server="default-host" cache-container="local" />
 </subsystem>

2. 启动JBoss Data Grid 6.3
(1)cd /Users/maping/Redhat/Datagrid/jboss-datagrid-6.3.0-server/bin
(2)./standalone.sh -c standalone-football.xml

3. 运行客户端
分别进入hotrod-endpoint、memcached-endpoint、rest-endpoint,然后执行:mvn exec:java

JDG_004:JDG 6.3 Quick Start 例子学习:Carmart(Transactional)

运行环境:JBoss Data Grid 6.3.0

Carmart(Transactional)与Carmart基本一样,但是多了事务,不同于数据库事务,这里是内存级的事务。
Carmart(Transactional)只能运行在library mode下,因为目前只有library mode支持事务。

学习重点:

1. 事务是如何配置开启的?

@ApplicationScoped
public class JBossASCacheContainerProvider implements CacheContainerProvider {
    private Logger log = Logger.getLogger(this.getClass().getName());

    private BasicCacheContainer manager;

    public BasicCacheContainer getCacheContainer() {
        if (manager == null) {
            GlobalConfiguration glob = new GlobalConfigurationBuilder()
                .nonClusteredDefault() //Helper method that gets you a default constructed GlobalConfiguration, preconfigured for use in LOCAL mode
                .globalJmxStatistics().enable() //This method allows enables the jmx statistics of the global configuration.
                .jmxDomain("org.infinispan.carmart.tx")  //prevent collision with non-transactional carmart
                .build(); //Builds  the GlobalConfiguration object
            Configuration loc = new ConfigurationBuilder()
                .jmxStatistics().enable() //Enable JMX statistics
                .clustering().cacheMode(CacheMode.LOCAL) //Set Cache mode to LOCAL - Data is not replicated.
                .transaction().transactionMode(TransactionMode.TRANSACTIONAL).autoCommit(false) //Enable Transactional mode with autocommit false
                .lockingMode(LockingMode.OPTIMISTIC).transactionManagerLookup(new GenericTransactionManagerLookup()) //uses GenericTransactionManagerLookup - This is a lookup class that locate transaction managers in the most  popular Java EE application servers. If no transaction manager can be found, it defaults on the dummy transaction manager.
                .locking().isolationLevel(IsolationLevel.REPEATABLE_READ) //Sets the isolation level of locking
                .eviction().maxEntries(4).strategy(EvictionStrategy.LIRS) //Sets  4 as maximum number of entries in a cache instance and uses the LIRS strategy - an efficient low inter-reference recency set replacement policy to improve buffer cache performance
                .persistence().passivation(false).addSingleFileStore().purgeOnStartup(true) //Disable passivation and adds a SingleFileStore that is purged on Startup
                .build(); //Builds the Configuration object
            manager = new DefaultCacheManager(glob, loc, true);
            log.info("=== Using DefaultCacheManager (library mode) ===");
        }
        return manager;
    }

    @PreDestroy
    public void cleanUp() {
        manager.stop();
        manager = null;
    }
}


2. 事务是如何保证的?

@Model
public class CarManager {

    private Logger log = Logger.getLogger(this.getClass().getName());

    public static final String CACHE_NAME = "carcache";

    public static final String CAR_NUMBERS_KEY = "carnumbers";

    @Inject
    private CacheContainerProvider provider;

    /*
     * Injects the javax.transaction.UserTransaction - The TransactionManager lookup is configured on
     * JBossASCacheContainerProvider/TomcatCacheContainerProvider impl classes for CacheContainerProvider
     */
    @Inject
    private UserTransaction utx;

    private BasicCache carCache;

    private String carId;
    private Car car = new Car();

    public CarManager() {
    }

    public String addNewCar() {
        carCache = provider.getCacheContainer().getCache(CACHE_NAME);
        try {
            utx.begin();
            List carNumbers = getNumberPlateList(carCache);
            carNumbers.add(car.getNumberPlate());
            carCache.put(CAR_NUMBERS_KEY, carNumbers);
            carCache.put(CarManager.encode(car.getNumberPlate()), car);
            utx.commit();
        } catch (Exception e) {
            if (utx != null) {
                try {
                    utx.rollback();
                } catch (Exception e1) {
                }
            }
        }
        return "home";
    }

    public String addNewCarWithRollback() {
        boolean throwInducedException = true;
        carCache = provider.getCacheContainer().getCache(CACHE_NAME);
        try {
            utx.begin();
            List carNumbers = getNumberPlateList(carCache);
            carNumbers.add(car.getNumberPlate());
            // store the new list of car numbers and then throw an exception -> roll-back
            // the car number list should not be stored in the cache
            carCache.put(CAR_NUMBERS_KEY, carNumbers);
            if (throwInducedException)
                throw new RuntimeException("Induced exception");
            carCache.put(CarManager.encode(car.getNumberPlate()), car);
            utx.commit();
        } catch (Exception e) {
            if (utx != null) {
                try {
                    utx.rollback();
                    log.info("Rolled back due to: " + e.getMessage());
                } catch (Exception e1) {
                }
            }
        }
        return "home";
    }

    /**
     * Operate on a clone of car number list so that we can demonstrate transaction roll-back.
     */
    @SuppressWarnings("unchecked")
    private List getNumberPlateList(BasicCache carCacheLoc) {
        List result = null;
        List carNumberList = (List) carCacheLoc.get(CAR_NUMBERS_KEY);
        if (carNumberList == null) {
            result = new LinkedList();
        } else {
            result = new LinkedList(carNumberList);
        }
        return result;
    }

    public String showCarDetails(String numberPlate) {
        carCache = provider.getCacheContainer().getCache(CACHE_NAME);
        try {
            utx.begin();
            this.car = (Car) carCache.get(encode(numberPlate));
            utx.commit();
        } catch (Exception e) {
            if (utx != null) {
                try {
                    utx.rollback();
                } catch (Exception e1) {
                }
            }
        }
        return "showdetails";
    }

    public List getCarList() {
        List result = null;
        try {
            utx.begin();
            // retrieve a cache
            carCache = provider.getCacheContainer().getCache(CACHE_NAME);
            // retrieve a list of number plates from the cache
            result = getNumberPlateList(carCache);
            utx.commit();
        } catch (Exception e) {
            if (utx != null) {
                try {
                    utx.rollback();
                } catch (Exception e1) {
                }
            }
        }
        return result;
    }

    public String removeCar(String numberPlate) {
        carCache = provider.getCacheContainer().getCache(CACHE_NAME);
        try {
            utx.begin();
            carCache.remove(encode(numberPlate));
            List carNumbers = getNumberPlateList(carCache);
            carNumbers.remove(numberPlate);
            carCache.put(CAR_NUMBERS_KEY, carNumbers);
            utx.commit();
        } catch (Exception e) {
            if (utx != null) {
                try {
                    utx.rollback();
                } catch (Exception e1) {
                }
            }
        }
        return null;
    }

    public void setCarId(String carId) {
        this.carId = carId;
    }

    public String getCarId() {
        return carId;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    public Car getCar() {
        return car;
    }

    public static String encode(String key) {
        try {
            return URLEncoder.encode(key, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String decode(String key) {
        try {
            return URLDecoder.decode(key, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}

JDG_003:JDG 6.3 Quick Start 例子学习:Carmart

运行环境:JBoss Data Grid 6.3.0

Carmart既可以运行在Library mode下,也可以运行在Remote Client-Server mode下。

学习重点:

1. Library mode和Remote Client-Server mode编译时是如何切换的?
(1)编译前,选择library-jbossas profile,profile具体信息查看pom.xml。

@ApplicationScoped
public class LocalCacheContainerProvider extends CacheContainerProvider {
    private Logger log = Logger.getLogger(this.getClass().getName());

    private BasicCacheContainer manager;

    public BasicCacheContainer getCacheContainer() {
        if (manager == null) {
            GlobalConfiguration glob = new GlobalConfigurationBuilder()
                .nonClusteredDefault() //Helper method that gets you a default constructed GlobalConfiguration, preconfigured for use in LOCAL mode
                .globalJmxStatistics().enable() //This method allows enables the jmx statistics of the global configuration.
                .build(); //Builds  the GlobalConfiguration object
            Configuration loc = new ConfigurationBuilder()
                .jmxStatistics().enable() //Enable JMX statistics
                .clustering().cacheMode(CacheMode.LOCAL) //Set Cache mode to LOCAL - Data is not replicated.
                .locking().isolationLevel(IsolationLevel.REPEATABLE_READ) //Sets the isolation level of locking
                .eviction().maxEntries(4).strategy(EvictionStrategy.LIRS) //Sets  4 as maximum number of entries in a cache instance and uses the LIRS strategy - an efficient low inter-reference recency set replacement policy to improve buffer cache performance
                .persistence().passivation(false).addSingleFileStore().purgeOnStartup(true) //Disable passivation and adds a SingleFileStore that is Purged on Startup
                .build(); //Builds the Configuration object
            manager = new DefaultCacheManager(glob, loc, true);
            log.info("=== Using DefaultCacheManager (library mode) ===");
        }
        return manager;
    }

    @PreDestroy
    public void cleanUp() {
        manager.stop();
        manager = null;
    }
}

(2)编译前,选择remote-jbossas profile,profile具体信息查看pom.xml。
@ApplicationScoped
public class RemoteCacheContainerProvider extends CacheContainerProvider {

    private Logger log = Logger.getLogger(this.getClass().getName());

    private BasicCacheContainer manager;

    public BasicCacheContainer getCacheContainer() {
        if (manager == null) {
            ConfigurationBuilder builder = new ConfigurationBuilder();
            builder.addServer()
                 .host(jdgProperty(DATAGRID_HOST))
                 .port(Integer.parseInt(jdgProperty(HOTROD_PORT)));
            manager = new RemoteCacheManager(builder.build());
            log.info("=== Using RemoteCacheManager (Hot Rod) ===");
        }
        return manager;
    }

    @PreDestroy
    public void cleanUp() {
        manager.stop();
        manager = null;
    }
}

2. 依赖注入到CarManager中的CacheContainerProvider,使用的到底是哪个实现?
@Inject
private CacheContainerProvider provider;
选择不同的profile进行编译时,只有一个实现,要么是library mode,要么是remote client-server mode,所以不会冲突。

3. EmbeddedCacheManager 返回的是Cache类型的缓存实例,RemoteCacheManager返回的是 RemoteCache类型的缓存实例,二者有共同的接口吗?
有,BasicCache。
private BasicCache carCache;

4. 编译、部署、运行

4.1 library mode
(1)编译:选择library-jbossas profile
(2)启动JBoss EAP 6.3
cd /Users/maping/Redhat/Eap/jboss-eap-6.3-jdg-carmart/bin
./standalone.sh。
(3)访问:http://localhost:8080/jboss-carmart。

4.2 remote client-server mode
(1)编译:选择remote-jbossas profile
(2)启动JBoss EAP 6.3
cd /Users/maping/Redhat/Eap/jboss-eap-6.3-jdg-carmart/bin
./standalone.sh
(3)修改JBoss Data Grid 6.3中的配置文件 standalone.xml,增加carcache
<subsystem xmlns="urn:infinispan:server:core:6.1" default-cache-container="local">
            <cache-container name="local" default-cache="default" statistics="true">
                <local-cache name="carcache" start="EAGER"
                             batching="false"
                             statistics="true">
                    <eviction strategy="LIRS" max-entries="4"/>
                </local-cache>
                <local-cache name="default" start="EAGER">
                    <locking isolation="NONE" acquire-timeout="30000" concurrency-level="1000" striping="false"/>
                    <transaction mode="NONE"/>
                </local-cache>
                <local-cache name="memcachedCache" start="EAGER">
                    <locking isolation="NONE" acquire-timeout="30000" concurrency-level="1000" striping="false"/>
                    <transaction mode="NONE"/>
                </local-cache>
                <local-cache name="namedCache" start="EAGER"/>
            </cache-container>
            <cache-container name="security"/>
</subsystem>

(4)启动JBoss Data Grid 6.3
/Users/maping/Redhat/Datagrid/jboss-datagrid-6.3.0-server/bin
./standalone.sh -c standalone-carmart.xml

(5)访问:http://localhost:8080/jboss-carmart。

JDG_002:JDG 6.3 Quick Start 例子学习:Hello World

运行环境:JBoss Data Grid 6.3.0

Hello World 只能运行在Library mode下。

学习重点:

1. 如何从Servlet访问Cache ? 
使用CDI依赖注入到Servlet中。
@Inject
DefaultCacheManager m;

2. 如何从JSF页面访问Cache ? 
使用CDI依赖注入到Managed Bean中,然后JSF通过Managed Bean访问Cache。
 @Inject
 DefaultCacheManager m;

3.  如何设置DefaultCacheManager ?

@ApplicationScoped
public class MyCacheManagerProvider {

    private static final long ENTRY_LIFESPAN = 60 * 1000; // 60 seconds

    @Inject
    private Logger log;

    private DefaultCacheManager manager;

    public DefaultCacheManager getCacheManager() {
        if (manager == null) {
            log.info("\n\n DefaultCacheManager does not exist - constructing a new one\n\n");

            GlobalConfiguration glob = new GlobalConfigurationBuilder().clusteredDefault() // Builds a default clustered configuration
                    .transport().addProperty("configurationFile", "jgroups-udp.xml") // provide a specific JGroups configuration
                    .globalJmxStatistics().allowDuplicateDomains(true).enable() // This method enables the jmx statistics of the global configuration and allows for duplicate JMX domains
                    .build(); // Builds the GlobalConfiguration object
            Configuration loc = new ConfigurationBuilder().jmxStatistics().enable() // Enable JMX statistics
                    .clustering().cacheMode(CacheMode.DIST_SYNC) // Set Cache mode to DISTRIBUTED with SYNCHRONOUS replication
                    .hash().numOwners(2) // Keeps two copies of each key/value pair
                    .expiration().lifespan(ENTRY_LIFESPAN) // Set expiration - cache entries expire after some time (given by the lifespan parameter) and are removed from the cache (cluster-wide).
                    .build();
            manager = new DefaultCacheManager(glob, loc, true);
        }
        return manager;
    }

    @PreDestroy
    public void cleanUp() {
        manager.stop();
        manager = null;
    }

}

注意,这里的配置使用了集群方式。

4.  在Servlet和Managed Bean中依赖注入的 DefaultCacheManage 是如何与 MyCacheManagerProvider关联的?

public class Resources {

    @Inject
    MyCacheManagerProvider cacheManagerProvider;

    @Produces
    Logger getLogger(InjectionPoint ip) {
        String category = ip.getMember().getDeclaringClass().getName();
        return Logger.getLogger(category);
    }

    @Produces
    DefaultCacheManager getDefaultCacheManager() {
        return cacheManagerProvider.getCacheManager();
    }

}
这里使用了@Produces,为各种资源“注入”了Logger和DefaultCacheManager对象。

5. 启动JBoss EAP 6.3
(1)启动JBoss EAP Server1
cd /Users/maping/Redhat/Eap/jboss-eap-6.3-jdg-helloworld-1/bin
./standalone.sh
(2)启动JBoss EAP Server 2
cd /Users/maping/Redhat/Eap/jboss-eap-6.3-jdg-helloworld-2/bin
./standalone.sh -Djboss.socket.binding.port-offset=100

6.编译和部署 jboss-helloworld-jdg.war到JBoss EAP Server1和Server2上。


7. 运行
(1)http://localhost:8080/jboss-helloworld-jdg
(2)http://localhost:8180/jboss-helloworld-jdg
无论在哪个Server上操作,另外一个Server上都能“看到”操作后的结果。