#!/bin/bash
#Date:2018-01-08
#Author:xxxxxx
#Function:xxxxxx
#Change:2018-01-17
# #设置忽略CTRL+C信号
trap 'my_exit;exit' SIGINT SIGTERM SIGQUIT #开启DEBUG模式
#set -x #如果有命令执行返回值为非0,那么脚本将结束,不再继续执行
# set -e #导入rsync使用的密码
export RSYNC_PASSWORD='xxxxxx' #设置脚本涉及的目录变量
pathdir=$(cd $(dirname $0);pwd)
#源主机同步到本机的临时目录
tmpdir='/data/migrate_tmp'
# tmpdir='/data/migrate_tmp/tmp' #测试用
#管理机
domain_m=("cms.domain.com" "pic.domain.com")
youxi_m=("/data1/www/abc.test.com" "/data1/www/pic.domain.com")
# youxi_m=("/data/migrate_tmp/abc.test.com" "/data/migrate_tmp/pic.domain.com") #测试用
#模板机
domain_t='cms.domain.com'
youxi_t='/data2/www/abc.test.com'
#web机
domain_web=''
youxi_web='/data/webapps'
#youxi_web='/data/migrate_tmp/webapps' #测试用
#图片机
domain_pic='pic.domain.com'
youxi_pic='/data/webapps/pic.domain.com' #判断临时目录是否存在,若不存在则创建
[ -d ${tmpdir} ] && rm -rf ${tmpdir}/* || mkdir -p ${tmpdir} #备份目录
# [ -d /data/fabuqi_bak ] && mkdir /data/fabuqi_bak #进入到脚本所在的目录
cd ${pathdir} #定义grep查找需要替换的文件列表正则
grep_re="img.dwstatic.com|img[1-5].dwstatic.com|pic[1-5].domain.com|pic[0-5]1.domain.com|public.domain.com|pic.domain.(com|cn)" #trap的执行函数
function my_exit(){
echo trap_handle_time: $(date "+%Y-%m-%d %H:%M:%S")
echo "exit"
} #脚本使用说明函数
function usage(){
echo "Usage: $0 [OPTIONS]"
echo " - Here to display help info ."
echo " - The args is only two ."
echo " - OPTIONS: [ all | zhuanqu_ID | 专区ID ] ."
echo " example: /bin/bash migrate.sh zxyzxy "
exit 1
} #logger function
function log_info(){
DATA_N=$(date "+%Y-%m-%d %H:%M:%S")
USER_N=$(whoami)
echo "${DATA_N} ${USER_N} execute $0 [INFO] $@" | tee -a ${pathdir}/migrate.log
} #配置变量函数,sync_dir是同步的源主机子目录,destdir是新发布器目标目录。
function config_and_rsync_single(){
#从源主机的哪个机器同步数据
rsync_from=${2}
#目标同步的目录
if [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
#拉取单个专区文件资源,保留文件时间属性
for i in `seq 0 $(expr ${#domain_m[*]} - 1)`
do
log_info "set the sync_dir and destdir value ..."
sync_dir=${domain_m[$i]}
destdir=${youxi_m[$i]}
#备份目录
log_info "backup the destdir ..."
cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,如果临时目录已经存在,就直接拷贝文件,如果不存在就创建临时目录在拷贝目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
log_info "create tmpdir ..."
[ -d ${tmpdir}/${sync_dir} ] && \cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} 2>>${pathdir}/migrate.log || mkdir -p ${tmpdir}/${sync_dir} && \cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} 2>>${pathdir}/migrate.log log_info "Start to get ${1} files ......"
rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/${sync_dir} | tee -a ${pathdir}/migrate.log
log_info "Start to execute update_single_id function ......"
update_single_id ${tmpdir}/${sync_dir} ${1} ${destdir}
done
log_info "建立专区对应的软连接 ..."
ln -nfs /data1/www/abc.test.com/${id} /data1/webapps/${id}.domain.com 2>>${pathdir}/migrate.log
chown -R www-data:www-data /data1/webapps/${id}.domain.com
elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
log_info "set the sync_dir and destdir value ..."
sync_dir=${domain_t}
destdir=${youxi_t}
#备份目录
log_info "backup the destdir ..."
cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
log_info "create tmpdir ..."
\cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log log_info "Start to get ${1} files ......"
rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/ | tee -a ${pathdir}/migrate.log
log_info "Start to execute update_single_id function ......"
update_single_id ${tmpdir} ${1} ${destdir}
log_info "建立专区对应的软连接 ..."
ln -snf ${destdir}/${id} /data/data1/www/abc.test.com/${id}.domain.com 2>>${pathdir}/migrate.log
chown -R www-data:www-data /data/data1/www/abc.test.com/${id}.domain.com
elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
log_info "set the sync_dir and destdir value ..."
sync_dir=${domain_web}
destdir=${youxi_web}
#备份目录
log_info "backup the destdir ..."
cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
log_info "create tmpdir ..."
\cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log log_info "Start to get ${1} files ......"
rsync -avuzt game_test@${rsync_from}::game_test/${1}.domain.com ${tmpdir}/ | tee -a ${pathdir}/migrate.log
log_info "Start to execute update_single_id function ......"
update_single_id ${tmpdir} ${1}.domain.com ${destdir} log_info "Start to backup ${1} nginx configure file......"
[ -d /data/services/nginx_vhost_bak ] || mkdir -p /data/services/nginx_vhost_bak
\cp -pvu /data/services/nginx_vhost/${1}.*.conf /data/services/nginx_vhost_bak/ 2>>${pathdir}/migrate.log
log_info "Start to rsync ${1} nginx configure file ......"
rsync -avuzt game_test@${rsync_from}::nginx_test/${1}.*.conf /data/services/nginx_vhost/
log_info "update the ${1} nginx conf,please to reload nginx service by manual ..."
# service nginx reload
else
log_info "set the sync_dir and destdir value ..."
sync_dir=${domain_pic}
destdir=${youxi_pic}
#备份目录
log_info "backup the destdir ..."
cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
log_info "create tmpdir ..."
\cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log log_info "Start to get ${1} files ......"
rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/ | tee -a ${pathdir}/migrate.log
log_info "Start to execute update_single_id function ......"
update_single_id ${tmpdir} ${1} ${destdir}
fi
} #迁移单个专区函数
function update_single_id(){
_tmpdir=${1}
id=${2}
_destdir=${3}
cd ${_tmpdir}
log_info "replace contexts in the files that in the ${id} directory ..."
#判断目录是否为空
if [ "`ls -A ${_tmpdir}/${id}`" = "" ]; then
log_info "the ${id} is indeed empty."
#判断目录及其子目录是否为空
elif [ "`find ${_tmpdir}/${id}/* -type f`" = "" ]; then
log_info "the ${id} and subdir are empty."
#判断是否有文件需要做内容替换
elif [ "`grep -rEl ${grep_re} ${_tmpdir}/${id}/*`" = "" ]; then
log_info "the ${id} not files need to replace."
#不为空时执行修改文件内容操作
else
log_info "Start to sed ......"
sed -i -e 's/img\.dwstatic\.com/img\.game\.dwstatic\.com/g' \
-e 's/img\(.\)\.dwstatic\.com/img\1\.game\.dwstatic\.com/g' \
-e 's/pic\(.\)\.domain\.com/img\1\.game\.dwstatic\.com/g' \
-e 's/pic01\.domain\.com/img\.game\.dwstatic\.com/g' \
-e 's/pic\(.\)\(.\)\.domain\.com/img\1\.game\.dwstatic\.com/g' \
-e 's/public\.domain\.com/publicgame\.domain\.com/g' \
-e 's/pic\.domain\.\(com\|cn\)/img\.game\.dwstatic\.com/g' $(grep -rEl ${grep_re} ${_tmpdir}/${id}/*)
fi if [ -d ${_destdir}/${id} ];then
log_info "the ${id} is a exist id,backup old ${id} dirs ..."
[ -d /data/fabuqi_bak/${id}_bak ] && log_info "the ${id}_bak is exist,not need to backup ..." || cp -rfp ${_destdir}/${id} /data/fabuqi_bak/${id}_bak
log_info "replace old ${id} dirs by new ${id} dirs ..."
#同步专区目录到新发布器目标目录中,只会在源文件的更改时间较目标文件更新时或是目标文件并不存在时,才复制文件,保留文件时间属性
\cp -rpvu ${_tmpdir}/${id}/* ${_destdir}/${id}/ | tee -a ${pathdir}/migrate.log
chown -R www-data:www-data ${_destdir}/${id}
else
log_info "the ${id} is a new id,not to backup."
#同步专区目录到新发布器目标目录中
\cp -rpvu ${_tmpdir}/${id} ${_destdir}/${id} | tee -a ${pathdir}/migrate.log
chown -R www-data:www-data ${_destdir}/${id}
fi log_info "update_single_id task done."
} #配置变量函数,sync_dir是同步的源主机子目录,destdir是新发布器目标目录。
function config_and_rsync_all(){
#从源主机的哪个机器同步数据
rsync_from=${1}
#目标同步的目录
if [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
#拉取所有专区文件资源,保留文件时间属性
for i in `seq 0 $(expr ${#domain_m[*]} - 1)`
do
log_info "set the sync_dir and destdir value ..."
sync_dir=${domain_m[$i]}
destdir=${youxi_m[$i]}
#备份目录
log_info "backup the destdir ..."
cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,如果临时目录已经存在,就直接拷贝文件,如果不存在就创建临时目录在拷贝目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
log_info "create tmpdir ..."
[ -d ${tmpdir}/${sync_dir} ] && \cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} || mkdir -p ${tmpdir}/${sync_dir} && \cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} log_info "Start to get ${sync_dir} all files ......"
rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/${sync_dir} | tee -a ${pathdir}/migrate.log
log_info "Start to execute update_all_id ${sync_dir} function ......"
update_all_id ${tmpdir}/${sync_dir} ${destdir}
done
for id in $(ls ${tmpdir}/${domain_m[0]})
do
log_info "建立专区对应的软连接 ..."
ln -nfs /data1/www/abc.test.com/${id} /data1/webapps/${id}.domain.com
chown -R www-data:www-data /data1/webapps/${id}.domain.com
done
elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
log_info "set the sync_dir and destdir value ..."
sync_dir=${domain_t}
destdir=${youxi_t}
#备份目录
log_info "backup the destdir ..."
cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
log_info "create tmpdir ..."
\cp -rpvu ${destdir}/* ${tmpdir}/ log_info "Start to get all files ......"
rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log
log_info "Start to execute update_all_id function ......"
update_all_id ${sync_dir} ${destdir}
for id in $(ls ${tmpdir}/${sync_dir})
do
log_info "建立专区对应的软连接 ..."
ln -snf ${destdir}/${id} /data/data1/www/abc.test.com/${id}.domain.com
chown -R www-data:www-data /data/data1/www/abc.test.com/${id}.domain.com
done
elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
log_info "set the sync_dir and destdir value ..."
sync_dir=${domain_web}
destdir=${youxi_web}
#备份目录
log_info "backup the destdir ..."
cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
log_info "create tmpdir ..."
\cp -rpvu ${destdir}/* ${tmpdir}/ log_info "Start to get all files ......"
rsync -avuzt game_test@${rsync_from}::game_test/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log
log_info "Start to execute update_all_id function ......"
update_all_id ${sync_dir} ${destdir} log_info "Start to backup all nginx configure file......"
\cp -r /data/services/nginx_vhost /data/services/nginx_vhost_bak
log_info "Start to rsync all nginx configure file ......"
rsync -avuzt game_test@${rsync_from}::nginx_test/* /data/services/nginx_vhost/
log_info "update the nginx conf,please to reload nginx service by manual ..."
# service nginx reload
else
log_info "set the sync_dir and destdir value ..."
sync_dir=${domain_pic}
destdir=${youxi_pic}
#备份目录
log_info "backup the destdir ..."
cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
log_info "create tmpdir ..."
\cp -rpvu ${destdir}/* ${tmpdir}/ log_info "Start to get all files ......"
rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log
log_info "Start to execute update_all_id function ......"
update_all_id ${sync_dir} ${destdir}
fi
} #批量迁移所有专区的函数
function update_all_id(){
_tmpdir=${1}
_destdir=${2}
cd ${_tmpdir}
for id in $(ls ${_tmpdir}/)
do
if [[ ${id} == "ssss" || ${id} == "testsslj" ]]; then
log_info "skip the ${id}."
elif [[ -f ${_tmpdir}/${id} ]]; then
log_info "the ${_tmpdir}/${id} is a file,not dir,please check it and sync by manual."
else
log_info "migrate ${id} start..."
cd ${_tmpdir}/${id}
log_info "replace contexts in the files that in the ${id} directory ..."
#判断目录是否为空
if [ "`ls -A ${_tmpdir}/${id}`" = "" ]; then
log_info "the ${id} is indeed empty."
#判断目录及其子目录是否为空
elif [ "`find ${_tmpdir}/${id}/* -type f`" = "" ]; then
log_info "the ${id} and subdir are empty."
#判断是否有文件需要做内容替换
elif [ "`grep -rEl ${grep_re} ${_tmpdir}/${id}/*`" = "" ]; then
log_info "the ${id} not files need to replace."
#不为空时执行修改文件内容操作
else
log_info "Start to sed ......"
sed -i -e 's/img\.dwstatic\.com/img\.game\.dwstatic\.com/g' \
-e 's/img\(.\)\.dwstatic\.com/img\1\.game\.dwstatic\.com/g' \
-e 's/pic\(.\)\.domain\.com/img\1\.game\.dwstatic\.com/g' \
-e 's/pic01\.domain\.com/img\.game\.dwstatic\.com/g' \
-e 's/pic\(.\)\(.\)\.domain\.com/img\1\.game\.dwstatic\.com/g' \
-e 's/public\.domain\.com/publicgame\.domain\.com/g' \
-e 's/pic\.domain\.\(com\|cn\)/img\.game\.dwstatic\.com/g' $(grep -rEl ${grep_re} ${_tmpdir}/${id}/*)
fi if [ -d ${_destdir}/${id} ]; then
log_info "the ${id} is a exist id,backup old ${id} dirs ..."
[ -d /data/fabuqi_bak/${id}_bak ] && log_info "the ${id}_bak is exist,not need to backup ..." || cp -rfp ${_destdir}/${id} /data/fabuqi_bak/${id}_bak
log_info "replace old ${id} dirs by new ${id} dirs ..."
#同步专区目录到新发布器目标目录中,只会在源文件的更改时间较目标文件更新时或是目标文件并不存在时,才复制文件,保留文件时间属性
\cp -rpvu ${tmpdir}/${1}/${id}/* ${_destdir}/${id}/ | tee -a ${pathdir}/migrate.log
chown -R www-data:www-data ${_destdir}/${id}
else
log_info "the ${id} is a new id,not to backup."
#同步专区目录到新发布器目标目录中
\cp -rpvu ${tmpdir}/${1}/${id} ${_destdir}/${id} | tee -a ${pathdir}/migrate.log
chown -R www-data:www-data ${_destdir}/${id}
fi log_info "migrate ${id} end..."
fi
done
log_info "update_all_id task done."
} #主函数
function main(){
domain_ip=("xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx")
youxi_ip=("xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx")
#限制执行脚本的ip,并且制定对应的新管理机从源主机管理机拉取文件,其他类型的机器一样,否则,不执行脚本。
for index in `seq 0 $(expr ${#domain_ip[*]} - 1)`
do
if [ $(ifconfig | grep ${youxi_ip[$index]} | wc -l) -eq 1 ]; then
ip=${domain_ip[$index]}
break
else
ip="error_x"
continue
fi
done if [ $# -ne 1 ]; then
usage
# elif [[ ${1} == "all" ]]; then
# config_and_rsync_all ${2}
elif [[ ${1} == "ssss" || ${1} == "testsslj" ]]; then
log_info "skip the ${1}."
else
if [[ ${ip} == "error_x" ]]; then
log_info "this host $(ifconfig | grep 'inet addr'|awk '{print $2}'| awk -F: '{print $2}'| grep -vE '^$' | head -1) no exist youxi_ip list,please add this ip to youxi_ip on this scripts."
else
config_and_rsync_single ${1} ${ip}
fi
fi
} #执行主函数
main $@

【原创】一个shell脚本记录(实现rsync生产文件批量迁移功能)的更多相关文章

  1. Shell脚本:使用rsync备份文件/目录

    本文我们介绍一个shell脚本,用来使用rsync命令将你本地Linux机器上的文件/目录备份到远程Linux服务器上.使用该脚本会以交互的方式实施备份,你需要提供远程备份服务器的主机名/ip地址和文 ...

  2. 向大家分享一个shell脚本的坑

    打算在跳板机上写一个shell脚本,批量检查远程服务器上的main进程是否在健康运行中. 先找出其中一台远程机器,查看main进程运行情况 [root@two002 tmp]# ps -ef|grep ...

  3. shell脚本中执行另一个shell脚本

    分类: 可以在一个shell脚本中执行另一个shell脚本(或非可执行文件,主要用于取得一些变量的值),方法是: . 文件名(包括路径) 或 变量=文件名(包括路径) . $变量   注意,圆点后面有 ...

  4. 编写第一个 Shell 脚本

    什么是 Shell 脚本? 一个 shell 脚本就是一个包含一系列命令的文件.shell 读取这个文件,然后执行 文件中的所有命令,就好像这些命令已经直接被输入到了命令行中一样. 怎样编写一个 Sh ...

  5. Shell教程 之第一个shell脚本

    1.第一个shell脚本 打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行 输入一些代码 #!/bi ...

  6. 编写第一个Shell脚本【TLCL】

    怎样编写一个 Shell 脚本 编写一个脚本 使脚本文件可执行 把脚本放到Shell能够找到的地方 脚本文件格式 #!/bin/bash # This is our first script. ech ...

  7. Linux Shell系列教程之(二)第一个Shell脚本

    本文是Linux Shell系列教程的第(二)篇,更多shell教程请看:Linux Shell系列教程 通过上一篇教程的学习,相信大家已经能够对shell建立起一个大体的印象了,接下来,我们通过一个 ...

  8. Shell脚本调用ftp上传文件

    Shell脚本调用ftp上传文件 1.脚本如下 ftp -n<<! open x.x.x.x ###x.x.x.x为ftp地址 user username password ###user ...

  9. 每秒执行一个shell脚本(转载)

      上周迁移了一台服务器,发现其中一个项目的数据没有更新,查询原服务器的数据,数据有更新,并找到了rsync服务,从其他服务器传输数据,那么如何找到这台服务器?因为是从远程传输到本地,而且不是很频繁, ...

随机推荐

  1. SignalR的简单实现(一)

    原文:SignalR的简单实现(一) ASP.NET SignalR是ASP.NET开发人员的一个新库,它使您的应用程序添加实时Web功能变得非常简单.什么是"实时网络"功能?能够 ...

  2. Hadoop Streaming框架学习(二)

    1.常用Streaming命令介绍 使用下面的命令运行Streaming MapReduce程序: 1: $HADOOP_HOME/bin/hadoop/hadoop streaming args 其 ...

  3. “流”的5个例子(TStream是抽象类,写到文件里和内存里,都是一样的)

    http://www.cnblogs.com/keyvip/category/270215.html

  4. Ubuntu Linux服务器搭建SSL/TLS(https)(在StartSSL可以得到免费证书)

    目录 1 生成公钥和私钥对 2 公钥提交到CA机构签发一个crt证书 3 配置证书链 4 在Apache里开启SSL支持并配置crt证书和私钥 5 配置HSTS (可选) 6 总结 首先SSL/TLS ...

  5. 用了WS_EX_LAYERED 后所有Twincontrl的wm_paint消息会停止(官方Layered Windows文档很多内容)good

    fmx 和 vcl 不一样, fmx 的阴影可以通过2D显示出来. VCL 无标题栏窗口的阴影很麻烦 280425268 我也是用两个窗口做阴影,并重绘了非客户区,不过阴影是基础自TwinContro ...

  6. qtablewidget qss加上这个,QHeaderView::section

     qtablewidget  qss加上这个,QHeaderView::section {    color: white;    padding: 4px;    height:24px;    b ...

  7. 细谈unity资源加载和卸载

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.概要 在了解unity的资源管理方式之后,接下来细谈一下Unity的资源是如何从磁盘中加载到运行时的内存中,以及又是如 ...

  8. mysql数据库之表关系

    外键 前戏之一对多关系 # 定义一张部门员工表id name gender dep_name dep_desc1 jason male 教学部 教书育人2 egon male 外交部 漂泊游荡3 ta ...

  9. spring boot 2.x 系列 —— spring boot 整合 kafka

    文章目录 一.kafka的相关概念: 1.主题和分区 2.分区复制 3. 生产者 4. 消费者 5.broker和集群 二.项目说明 1.1 项目结构说明 1.2 主要依赖 二. 整合 kafka 2 ...

  10. string类总结第二部分实战练习

    第二部门:实战练习 昨天由于时间原因,这个部分应该在同一个文章中的,无奈只能今天再开一个了,今天主要是讲一些面试题 一:equals和==的区别 最简单的面试题,也是最基础的,我估计每个学习java的 ...