最近接到一个这样的需求,某个APP注册的用户数据需要同步到欧洲的另一个数据库里。
需求起源于最近欧盟的一项法规,要求在欧盟运营的软件公司,用户数据必需在欧盟本地服务器上存储一份。
我们有给西班牙客户定制一个APP,其用户数据是存储在国内的数据库里,因了这项法规,客户要求用户注册时也存储一份用户数据到他们的数据库里,同时当用户数据修改或删除时需要同步到他们数据库。
接到这个需求,第一思路是在注册、修改、和删除用户时除了修改自己的数据库,也修改欧盟那边的数据库,
可是仔细一想总觉得怪怪的,代码变得不干净了不说,用户修改还要等数据库写到欧盟的数据库,那得多慢,不行。
就算用任务队列,异步做欧盟那边的数据修改,也要改很多代码,代码变得不干净。
第二思路,定时同步用户数据到他们数据库,客户并没要求要实时同步呀,跟客户确认方案可行。
定时同步,第一个想到的是在数据库里写个定时任务,每隔五分钟,他们APP注册的用户数据有更新的,就同步过去。
数据库定时任务开写,才发现实现不了,两边数据库都是MySQL,但想把select 出来的数据跨域写到另一个数据库里是不可能的。
数据库里不能做,那只能写代码来实现了,第一个想到的是用JAVA来写,在Mybatis里配置双数据库,两个DataSource.
把从一个数据库里查出来的数据,处理后写入另一个数据库。
逻辑没问题,但想想为了这样一点点小事情,配置双数据源,值得吗?
感觉就是太重了,要是欧洲多来几个定制的APP,那不是要配置N个数据源?不行,不行!
最后想到的是,用Shell脚本来实现,从一个数据库读取数据写到服务器本地文件,再读出来写入另一个数据库。
没错,只要一个Shell脚本,Perfect!
需求起源于最近欧盟的一项法规,要求在欧盟运营的软件公司,用户数据必需在欧盟本地服务器上存储一份。
我们有给西班牙客户定制一个APP,其用户数据是存储在国内的数据库里,因了这项法规,客户要求用户注册时也存储一份用户数据到他们的数据库里,同时当用户数据修改或删除时需要同步到他们数据库。
接到这个需求,第一思路是在注册、修改、和删除用户时除了修改自己的数据库,也修改欧盟那边的数据库,
可是仔细一想总觉得怪怪的,代码变得不干净了不说,用户修改还要等数据库写到欧盟的数据库,那得多慢,不行。
就算用任务队列,异步做欧盟那边的数据修改,也要改很多代码,代码变得不干净。
第二思路,定时同步用户数据到他们数据库,客户并没要求要实时同步呀,跟客户确认方案可行。
定时同步,第一个想到的是在数据库里写个定时任务,每隔五分钟,他们APP注册的用户数据有更新的,就同步过去。
数据库定时任务开写,才发现实现不了,两边数据库都是MySQL,但想把select 出来的数据跨域写到另一个数据库里是不可能的。
数据库里不能做,那只能写代码来实现了,第一个想到的是用JAVA来写,在Mybatis里配置双数据库,两个DataSource.
把从一个数据库里查出来的数据,处理后写入另一个数据库。
逻辑没问题,但想想为了这样一点点小事情,配置双数据源,值得吗?
感觉就是太重了,要是欧洲多来几个定制的APP,那不是要配置N个数据源?不行,不行!
最后想到的是,用Shell脚本来实现,从一个数据库读取数据写到服务器本地文件,再读出来写入另一个数据库。
没错,只要一个Shell脚本,Perfect!
以下代码,献给大家,欢迎提BUG,也欢迎点赞,哈哈。
#!/bin/bash
###############欧盟数据库##############
#服务器域名
hostname_to="127.0.0.2";
#端口号
prot_to="3306";
#用户名
username_to="username";
#密码
password_to="password";
#数据库名
dbname_to="db_to";
###############自己的数据库##############
#服务器域名
hostname="127.0.0.1";
#端口号
prot="3306";
#用户名
user="username";
#密码
password="password";
#数据库名
dbname="db_from";
###############从自己的数据库中读取有更新的用户信息###############
#删除旧文件,创建新文件
data_file="/usr/local/sh/user_data_sync.data";
if [ -f ${data_file} ]; then
rm ${data_file}
fi
touch ${data_file};
echo -e "\n\n========================开始导出数据!========================\n"
sql_export="SELECT CONCAT(id, ',', userid, ',', IFNULL(pwd, ''), ',', IFNULL(mobile, ''), ',', IFNULL(email, ''), ',', IFNULL(nickname, ''), ',', IFNULL(headurl, ''), ',', IFNULL(status, '')) FROM user WHERE reg_package_name IN ('com.a.b', 'com.a.c') AND update_date > DATE_SUB(NOW(), INTERVAL 6 MINUTE)";
mysql -h${hostname} -P${prot} -u${user} -p${password} -D${dbname} --skip-column-names -e"${sql_export}" > ${data_file}
if [ $? -ne 0 ]; then
echo "读取表失败"
exit 1
fi
echo -e "\n\n========================导出数据完成!========================\n"
###############更新欧盟数据库用户信息###############
while read i
do
eval $(echo $i|awk -F',' '{ printf("a=%d\nb=%s\nc=%s\nd=%s\ne=%s\nf=%s\ng=%s\nh=%d",$1,$2,$3,$4,$5,$6,$7,$8); }')
sql_update="REPLACE INTO user(id, account, password, mobile, email, nickname, avator) VALUES($a, '$b', '$c', '$d', '$e', '$f', '$g')"
if [ $h -e 3 ]; then
sql_update="DELETE FROM user WHERE id = $a"
fi
mysql -h${hostname_to} -P${prot_to} -u${user_to} -p${password_to} -D${dbname_to} -e"${sql_update}"
done < $data_file
echo -e "\n\n========================更新数据完成!========================\n"