agapple

BlogJava 首页 新随笔 联系 聚合 管理
  13 Posts :: 1 Stories :: 1 Comments :: 0 Trackbacks

2009年1月14日 #

     摘要: 背景     前段时间在工作中,包括一些代码阅读过程中,spring aop经常性的会看到cglib中的相关内容,包括BeanCopier,BulkBean,Enancher等内容,以前虽大致知道一些内容,原理是通过bytecode,但没具体深入代码研究,只知其所用不知其所以然,所以就特地花了半天多的工作时间研究了CGLIB的相关源码,同时结合看了下 spring ...  阅读全文
posted @ 2010-11-01 22:24 agapple 阅读(1303) | 评论 (0)编辑 收藏

   最近在做offerdetail优化时,替换了数据库驱动,从c3p0 0.9.1 -> dbcp 1.4顺便研究了下dbcp的自动重连的一套机制,也做一下分享,大家周知一下。

 

数据库链接 常见的问题:

1. 数据库意外重启后,原先的数据库连接池能自动废弃老的无用的链接,建立新的数据库链接

2. 网络异常中断后,原先的建立的tcp链接,应该能进行自动切换。比如网站演习中的交换机重启会导致网络瞬断

3. 分布式数据库中间件,比如cobar会定时的将空闲链接异常关闭,客户端会出现半开的空闲链接。

 

大致思考解决思路:

1.      sql心跳检查(主动式)

2.      拿链接尝试一下,发现处理失败丢弃链接,探雷的请求会失败几个 (牺牲小我,完成大我的精神)

3.      设置合理的空闲链接的超时时间,避免半开链接(懒模式,解决半开链接)

 

 

下面我们来看看,在dbcp中是如何实现。

sql心跳检查

sql validate配置

<property name="testWhileIdle"><value>true</value></property>

<property name="testOnBorrow"><value>false</value></property>

<property name="testOnReturn"><value>false</value></property>

<property name="validationQuery"><value>select sysdate from dual</value></property>

<property name="validationQueryTimeout"><value>1</value></property>

<property name="timeBetweenEvictionRunsMillis"><value>30000</value></property>

<property name="numTestsPerEvictionRun"><value>16</value></property>

参数说明

  

   dbcp是采用了commons-pool做为其连接池管理,testOnBorrow,testOnReturn, testWhileIdlepool是提供的几种校验机制,通过外部钩子的方式回调dbcp的相关数据库链接(validationQuery)校验, dbcp相关外部钩子类:PoolableConnectionFactory,继承于common-pool PoolableObjectFactory , dbcp通过GenericObjectPool这一入口,进行连接池的borrow,return处理。

具体参数描述:

   1. testOnBorrow : 顾明思义,就是在进行borrowObject进行处理时,对拿到的connection进行validateObject校验

   2. testOnReturn : 顾明思义,就是在进行returnObject对返回的connection进行validateObject校验,个人觉得对数据库连接池的管理意义不大

   3. testWhileIdle : 关注的重点,GenericObjectPool中针对pool管理,起了一个异步Evict的TimerTask定时线程进行控制(可通过设置参数 timeBetweenEvictionRunsMillis>0),定时对线程池中的链接进行validateObject校验,对无效的链接进行关闭后,会调用ensureMinIdle,适当建立链接保证最小的minIdle连接数。

   4. timeBetweenEvictionRunsMillis,设置的Evict线程的时间,单位ms,大于0才会开启evict检查线程

   5. validateQuery, 代表检查的sql

   6. validateQueryTimeout, 代表在执行检查时,通过statement设置,statement.setQueryTimeout(validationQueryTimeout)

   7. numTestsPerEvictionRun,代表每次检查链接的数量,建议设置和maxActive一样大,这样每次可以有效检查所有的链接.

Sql心跳检查几点思考:

1.性能问题。

目前网站的应用大部分的瓶颈还是在I/O这一块,大部分的I/O还是在数据库的这一层面上,每一个请求可能会调用10来次SQL查询,如果不走事务,一个请求会重复获取链接,如果每次获取链接,比如在testOnBorrow都进行validateObject,性能开销不是很能接受,可以假定一次SQL操作消毫0.5~1ms(一般走了网络请求基本就这数)

2.成本和收益

网站异常数据库重启,网络异常断开的频率是非常低的,一般也就在数据库升级,演习维护时才会进行,而且一般也是选在晚上,访问量相对比较低的请求,而且一般会有人员值班关注,所以异步的validateObject是可以接受,但一个前提需要确保能保证在一个合理的时间段内,数据库能完成自动重联。

 

请求探雷

相关配置

dbcp自身默认支持,不需要配置

原理描述

common-pools通过borrowObject , returnObject完成连接的获取和释放,正常的情况是一次请求中borrow和return是一对的,有借就有还。

但在准备returnObject时,dbcp会做一件事,就是看看这个object是否已经是坏了的,如果坏了就直接丢了,就直接给丢弃了。

 

代码层面:

1. 在dbcp中PoolingDataSource(实现DataSource接口)调用 PoolableConnection(dbcp connnection相关的pool delegate操作)进行相应关闭时,会检查_conn.isClosed(),针对DataSource如果isClosed返回为 true的则不调用returnObject,直接丢弃了链接。

2. _conn.isClosed()是否保险,从jdk的api描述中: A connection is closed if the method close has been called on it or if certain fatal errors have occurred. 里面提供两种情况,一种就是被调用了closed方法,另一种就是出现一些异常,说的比较含糊。

 

空闲链接检查

相关配置

<property name="minEvictableIdleTimeMillis"><value>18000000</value></property>

<property name="removeAbandoned"><value>true</value></property> 

<property name="removeAbandonedTimeout"><value>180</value></property>

参数说明

1.minEvictableIdleTimeMillis dbcp默认是30分,需要开启异步线程Evict,否则不生效。原理很简单,就是通过一个异步线程,每次检查connnection上一次使用的时间戳,看看是否已经超过这个timeout时间设置。

2. removeAbandoned , removeAbandonedTimeout,主要是用于在出现链接紧张时候,会扫描一些链接未超过removeAbandonedTimeout时间还未被释放,会主动的关闭该链接。

适用情况

1. 我们使用的cobar后端会有定时关闭空闲链接的操作,默认的空闲链接timeout时间为1小时,和其他oracle , mysql各不相同,所以设置好这个空闲链接的timeout时间还是挺重要.

 

2. 一般会是几种情况出现需要removeAbandoned: 

* 代码未在finally释放connection , 不过我们都用sqlmapClientTemplate,底层都有链接释放的过程

* 遇到数据库死锁。以前遇到过后端存储过程做了锁表操作,导致前台集群中连接池全都被block住,后续的业务处理因为拿不到链接所有都处理失败了。

 

 

聊聊c3p0配置

还有我们配置的c3p0所谓的自动重连的3个参数,

<prop key="acquireRetryAttempts">30</prop>

    <prop key="acquireRetryDelay">1000</prop>

    <prop key="breakAfterAcquireFailure">false</prop>

 

个人觉得就是一个误导,这几个配置只是在从连接池获取链接时,获取失败多尝试几次,因为我们从pool从获取链接最多只会等待固定timeout时间。

如果要达到自动重连的效果,必须要c3p0支持请求探雷或者是sql心跳检查功能,能自动的剔除无效的链接。 

可见c3p0官方文档描述:http://www.mchange.com/projects/c3p0/index.html#configuring_recovery

 

最后:

Dbcp将是我们以后数据库驱动选择的趋势,最后我们如何选择如何自动重连,这个也得根据我们的应用场景而定。比如只读的web系统,后台业务系统,任务系统可能处理方式就不同。

只读Web系统:可采取请求探雷的策略,也就失败连接池个数的请求,失败了页面刷新一次就好。

后台业务系统:一般业务都涉及数据库的写操作,很多数据不可重入,一次处理失败后就只能靠手工干预处理。这时候得考虑是否需要使用sql心跳检查,比如testOnBorrow或者testWhileIdle.

posted @ 2010-10-23 01:01 agapple 阅读(953) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-02-15 21:47 agapple 阅读(6387) | 评论 (1)编辑 收藏

1. 下载rsync  (http://rsync.samba.org/)

安装:
./configure
make
make install

2. 开启rsync服务,修改/etc/xinetd.d/rsync
disable = no # replace <yes>
重启xinetd 服务
service xinetd restart


3. 配置server端,/etc/rsyncd.conf
# touch rsyncd.conf
# vi rsyncd.conf
uid = ljh  #表示以什么用户运行,注意必须确保该用户有对模块的读写权限
gid = ljh
use chroot = false
max connectionts = 6
read only = no
pid file = /home/ljh/server/rsync/rsynnd.pid
lock file = /home/ljh/server/rsync/rsyncd.lock
log file = /home/ljh/server/rsync/rsyncd.log
[test]
comment = test
path = /home/ljh/server/rsync/data/test
ignore error
list = true
#auth users = ljh
#secrets file = /home/ljh/server/rsync/passwd/rsyncd.passwd

 

配置参数介绍
comment
给模块指定一个描述,该描述连同模块名在客户连接得到模块列表时显示给客户。默认没有描述定义。
path
指定该模块的供备份的目录树路径,该参数是必须指定的。
use chroot
如 果"use chroot"指定为true,那么rsync在传输文件以前首先chroot到path参数所指定的目录下。这样做的原因是实现额外的安全防护,但是缺点是需要以roots权限,并且不能备份指向外部的符号连接所指向的目录文件。默认情况下chroot值为true。
uid
该选项指定当该模块传输文件时守护进程应该具有的uid,配合gid选项使用可以确定哪些可以访问怎么样的文件权限,默认值是"nobody"。
gid
该选项指定当该模块传输文件时守护进程应该具有的gid。默认值为"nobody"。
max connections
指定该模块的最大并发连接数量以保护服务器,超过限制的连接请求将被告知随后再试。默认值是0,也就是没有限制。
list
该选项设定当客户请求可以使用的模块列表时,该模块是否应该被列出。如果设置该选项为false,可以创建隐藏的模块。默认值是true。
read only
该选项设定是否允许客户上载文件。如果为true那么任何上载请求都会失败,如果为false并且服务器目录读写权限允许那么上载是允许的。默认值为true。
exclude
用 来指定多个由空格隔开的多个文件或目录(相对路径),并将其添加到exclude列表中。这等同于在客户端命令中使用--exclude来指定模式,一个 模块只能指定一个exclude选项。但是需要注意的一点是该选项有一定的安全性问题,客户很有可能绕过exclude列表,如果希望确保特定的文件不能 被访问,那就最好结合uid/gid选项一起使用。
exclude from [file]
指定一个包含exclude模式的定义的文件名,服务器从该文件中读取exclude列表定义。
include
用来指定不排除符合要求的文件或目录。这等同于在客户端命令中使用--include来指定模式,结合include和exclude可以定义复杂的exclude/include规则。
include from [file]
指定一个包含include模式的定义的文件名,服务器从该文件中读取include列表定义。
auth users
该选项指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块。这里的用户和系统用户没有任何关系。如果"auth users"被设置,那么客户端发出对该模块的连接请求以后会被rsync请求challenged进行验证身份这里使用的 challenge/response认证协议。用户的名和密码以明文方式存放在"secrets file"选项指定的文件中。默认情况下无需密码就可以连接模块(也就是匿名方式)。
secrets file
该选项指定一个包含定义用户名:密码对的文件。只有在"auth users"被定义时,该文件才有作用。文件每行包含一个username:passwd对。一般来说密码最好不要超过8个字符。没有默认的 secures file名,需要限式指定一个(例如:/etc/rsyncd.passwd)。注意:该文件的权限一定要是600,否则客户端将不能连接服务器
strict modes
该选项指定是否监测密码文件的权限,如果该选项值为true那么密码文件只能被rsync服务器运行身份的用户访问,其他任何用户不可以访问该文件。默认值为true。
hosts allow
该选项指定哪些IP的客户允许连接该模块。客户模式定义可以是以下形式:单个IP地址,例如:192.167.0.1
hosts deny
指定不允许连接rsync服务器的机器,可以使用hosts allow的定义方式来进行定义。默认是没有hosts deny定义。
ignore errors
指定rsyncd在判断是否运行传输时的删除操作时忽略server上的IO错误,一般来说rsync在出现IO错误时将将跳过--delete操作,以防止因为暂时的资源不足或其它IO错误导致的严重问题。
lock file
指定支持max connections参数的锁文件,默认值是/var/run/rsyncd.lock。
timeout
通过该选项可以覆盖客户指定的IP超时时间。通过该选项可以确保rsync服务器不会永远等待一个崩溃的客户端。超时单位为秒钟,0表示没有超时定义,这也是默认值。对于匿名rsync服务器来说,一个理想的数字是600。
dont compress
用来指定那些不进行压缩处理再传输的文件,默认值是*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

 

4. 客户端配置
访问remote rsync列表
rsync rsync://10.0.64.162/test
简单的执行同步命令
sync -auv --delete --password-file=/home/admin2/soft/rsync/passwd/rsyncd.passwd ~/rysnc/* ljh@10.0.64.162::test

比较实际的例子:
echo "hello" > /tmp/password.txt ;chmod 600 /tmp/password.txt
cp /home/ewalletbops/fatrix/crm/* /home/ewalletbops/fatrix/putxml/search
rsync -azv /home/ewalletbops/bops-daemon/bin/adxml/search/ /home/ewalletbops/fatrix/putxml/search
rsync -auv --delete --password-file=/tmp/password.txt /home/ewalletbops/fatrix/putxml/search yangzhen@127.0.0.1::everest/adxml
rm /tmp/password.txt


 

选项说明
-v, --verbose 详细模式输出
-q, --quiet 精简输出模式
-c, --checksum 打开校验开关,强制对文件传输进行校验
-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD
-r, --recursive 对子目录以递归模式处理
-R, --relative 使用相对路径信息
-b, --backup 创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename。可以使用--suffix选项来指定不同的备份文件前缀。
--backup-dir 将备份文件(如~filename)存放在在目录下。
-suffix=SUFFIX 定义备份文件前缀
-u, --update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件)
-l, --links 保留软链结
-L, --copy-links 想对待常规文件一样处理软链结
--copy-unsafe-links 仅仅拷贝指向SRC路径目录树以外的链结
--safe-links 忽略指向SRC路径目录树以外的链结
-H, --hard-links 保留硬链结
-p, --perms 保持文件权限
-o, --owner 保持文件属主信息
-g, --group 保持文件属组信息
-D, --devices 保持设备文件信息
-t, --times 保持文件时间信息
-S, --sparse 对稀疏文件进行特殊处理以节省DST的空间
-n, --dry-run现实哪些文件将被传输
-W, --whole-file 拷贝文件,不进行增量检测
-x, --one-file-system 不要跨越文件系统边界
-B, --block-size=SIZE 检验算法使用的块尺寸,默认是700字节
-e, --rsh=COMMAND 指定替代rsh的shell程序
--rsync-path=PATH 指定远程服务器上的rsync命令所在路径信息
-C, --cvs-exclude 使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件
--existing 仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件
--delete 删除那些DST中SRC没有的文件
--delete-excluded 同样删除接收端那些被该选项指定排除的文件
--delete-after 传输结束以后再删除
--ignore-errors 及时出现IO错误也进行删除
--max-delete=NUM 最多删除NUM个文件
--partial 保留那些因故没有完全传输的文件,以是加快随后的再次传输
--force 强制删除目录,即使不为空
--numeric-ids 不将数字的用户和组ID匹配为用户名和组名
--timeout=TIME IP超时时间,单位为秒
-I, --ignore-times 不跳过那些有同样的时间和长度的文件
--size-only 当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间
--modify-window=NUM 决定文件是否时间相同时使用的时间戳窗口,默认为0
-T --temp-dir=DIR 在DIR中创建临时文件
--compare-dest=DIR 同样比较DIR中的文件来决定是否需要备份
-P 等同于 --partial
--progress 显示备份过程
-z, --compress 对备份的文件在传输时进行压缩处理
--exclude=PATTERN 指定排除不需要传输的文件模式
--include=PATTERN 指定不排除而需要传输的文件模式
--exclude-from=FILE 排除FILE中指定模式的文件
--include-from=FILE 不排除FILE指定模式匹配的文件
--version 打印版本信息
--address 绑定到特定的地址
--config=FILE 指定其他的配置文件,不使用默认的rsyncd.conf文件
--port=PORT 指定其他的rsync服务端口
--blocking-io 对远程shell使用阻塞IO
--stats 给出某些文件的传输状态
--progress 在传输时现实传输过程
--log-format=formAT 指定日志文件格式
--password-file=FILE 从FILE中得到密码
--bwlimit=KBPS 限制I/O带宽,KBytes per second
-h, --help 显示帮助信息

 

 

 

 

 

 

 

 

 

posted @ 2009-01-14 14:12 agapple 阅读(731) | 评论 (0)编辑 收藏