在昨天讨论了关于目前遇到的多系统交互中关于推送文件的一些基本的要求,http://blog.itpub.net/23718752/viewspace-1814410/
虽然感觉已经提了不少的要求,基本能够做到全面的把握,但是说归说,计划归计划,实际要做的时候,问题就很具体了,有时候很可能会和自己的想法有一些出入。
#难点1 sqlldr加载数据的格式解析
首先是碰到的问题就是解析csv文件,把它包装成sqlldr可以执行的格式。
比如表的结构如下:
SQL> desc AREA_DETAILS
Name Null? Type
-------------- -------- --------------
ID NOT NULL NUMBER
AREA NOT NULL VARCHAR2(100)
PERSONNUM NOT NULL NUMBER
DATADATE NOT NULL DATE
推送的csv文件就是下面的形式。
广西,1027,2015-10-11
台湾,500,2015-10-11
湖北,1033,2015-10-11
那么需要考虑的就是日期字段的格式化,主键id列的递增,排除空行等的干扰。
所以准备的控制文件内容里面包含数据,格式就会是下面的样子。
load data
infile *
append into table xxxx_t.AREA_DETAILS
fields terminated by ","
trailing nullcols
(ID "XXX_TEST.SEQ_AREA_ID.nextval",AREA,PERSONNUM,DATADATE)
Begindata
广西,1027,2015-10-11
台湾,500,2015-10-11
湖北,1033,2015-10-11
加载的时候就直接使用sqlldr xxx/xxx control=data.ctl的形式就可以了。
#难点2 rsync的配置
如果直接没有接触过rsync的话,直接说推送还是有些摸不着头脑,但是这个需求还是合理的,所以就需要我们来配合他们。
一听说rsync需要配置自己也打退堂鼓,但是在同事的帮助下,发现还是很轻巧的。
需要配置一个文件 在/etc/rsyncd.conf,内容如下:
log file = /var/log/rsyncd.log
uid=oracle
gid=oinstall
port = 873
#limit access to private LANs
hosts allow=10.0.0.0/255.255.255.128
hosts deny=*
max connections = 30
timeout = 180
[actv_conf]
path = /U01/actv_ctl
hosts allow = 10.2.0.42
read only = false
这个文件代表的含义是为用户oracle,用户组为oinstall在/U01/actv_ctl的目录下开放读写权限,actv_conf为需要提供给开发的模块名,对10.2.0.42的客户端ip开放rsync的权限,端口为873
然后直接启动rsync即可。
# rsync --daemon
启动后,可以看到对应的进程,
# ps -ef|grep rsync
root 28951 1 0 11:04 ? 00:00:00 rsync --daemon
root 28968 23963 0 11:04 pts/1 00:00:00 grep rsync
而且响应的端口也是开放的,对于客户端还需要开放防火墙。
# netstat -lntp |grep 873
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 28951/rsync
这样服务端就配置好了,这样就可以接受客户端推送的文件了。感觉效果和svn有些类似。
作为扩展,来看看客户端是怎么推送文件的。
#难点3 客户端推送文件
客户端要推送文件,配置更简单,首先需要配置一个密码文件,只是在客户端中设置的。
放在/etc/rsyncd.passwd里面,密码根据自己情况输入即可。假设服务端的ip为10.2.100.90,模块名为actv_conf
需要推送的文件为run.sh,则只需要一个命令即可。
# rsync -avz --progress --password-file=/etc/rsyncd.passwd run.sh 10.2.100.90::actv_conf
building file list ...
1 file to consider
run.sh
133 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
sent 143 bytes received 38 bytes 120.67 bytes/sec
total size is 133 speedup is 0.73
这样文件run.sh就推送到了服务端的/U01/actv_ctl目录下。
#难点4,看似美好的字符集
起初自己为了兼容性,高标准,约定字符集为UTF-8,可发同事也很配合,尝试给我推了一个文件作为参考。
文件确实没有问题,是UTF-8格式。
$ file AREA_DETAILS.2015-10-11.csv
AREA_DETAILS.2015-10-11.csv: UTF-8 Unicode text
但是在服务端测试部署的时候,还是碰到了问题,比如
SQL*Loader-350: Syntax error at line 1.
Expecting keyword LOAD, found "黑龙汢.
黑龙江,1044,2015-10-11
^
带着疑问查看NLS_LANG就豁然开朗了。原来字符集设定是中文字符集,和UTF-8还是有一些差别。
$ echo $NLS_LANG
American_America.zhs16gbk
这个时候开发那么是统一采用UTF-8来推送,这边的应用还是会保留使用中文字符集,所以我是夹在两头中间的人,已经信誓旦旦约定了UTF-8,这下情况比预计的要复杂一些。
所以可以采用多种方式来做这个工作,比如使用java,python等语言中进行转换。另外一种相对简便的方式就是使用linux命令来处理。
比如把文件格式由UTF-8格式化为GBK,可以采用下面的形式,要格式化的文件为:AREA_DETAILS.2015-10-11.csv 格式化后的文件为:tmp_AREA_DETAILS.2015-10-11.csv.csv.ctl
iconv -f UTF-8 -t GBK AREA_DETAILS.2015-10-11.csv -o tmp_AREA_DETAILS.2015-10-11.csv.csv.ctl
使用这种方式之后,略作修改,整个工作就衔接起来了。后面的几个问题处理也是如法炮制,就很顺利了。
所以尽管在看似很严密的需求限定下,后面还是需要付出很多的努力才能实现那些看似简单的任务。有些问题还真需要好好根据实际情况来判断和分析,尽量减少拍脑袋做决定的方式。