在练习畅购商城项目,依赖畅购商城的文件微服务,边学变练,做一个整理,目前是单机部署,集群还未尝试。
文件微服务架构
自己理解的部署图,可能并不标准,哪位大神懂的话,可以指点一下,其中,Web或者其它微服务会调用文件微服务,需要头信息的Content=Type为Multipart/form-data,文件微服务相当于FastDFS的客户端,调用FastDFS tracker,Tracker调用Storage,实现文件的存储,Storage需要安装nginx和fastdfs-nginx-module实现文件同步,此尝试全部在一台虚拟机使用。
安装
(1)fastDFS分布式文件系统组件安装 在redhat7.6安装fastDFS如下,以非root用户fastdfs执行,无法ssh登录,安装在/opt/fasf/DFS目录下,用户id为13000,由于redhat7.6本地镜像未找到libevent-devel,手动下载libevent-devel的rpm包放到安装包中,redhat选择Basic Web Server模式安装后,执行Install脚本可以直接安装成功,具体目录如下: fdfsInstall.conf配置文件如下:
fastdfsGroupId=13000
fastdfsUserId=13000
fastdfsGroupName=fastdfs
fastdfsUserName=fastdfs
fastdfsPassword=XXXX
fastdfsInstallDIR="/opt/fasfDFS/"
fastDFSInstall.sh如下:
#!/bin/bash
source ./../utils.sh
source ./fdfsInstall.conf
function addFastDFSUser() {
if id -u ${fastdfsUserName} >/dev/null 2>&1; then
return 0
else
groupadd -g "${fastdfsGroupId}" "${fastdfsGroupName}"
useradd -M "${fastdfsUserName}" -u "${fastdfsUserId}" -s /sbin/nologin -g "${fastdfsGroupId}" -p "${fastdfsPassword}"
echo "${fastdfsPassword}" | passwd --stdin "${fastdfsUserName}"
fi
}
function checkRpm() {
local rpmName=$1
if [ -z "$(yum list installed | grep ${rpmName})" ]; then
local result=$(echo y | yum install ${rpmName})
log_info "${rpmName} is not installed,yum insall ${rpmName} result is: ${result}"
if [[ "${result}" =~ "fail" ]]; then
log_error "${rpmName} install failed"
return 1
else
log_info "${rpmName} is not installed,now installed success"
return 0
fi
else
log_info "${rpmName} is already installed,check pass"
return 0
fi
}
function checkEnv() {
checkRpm "gcc"
checkRpm "libevent"
if [ -z "$(yum list installed | grep libevent-devel)" ]; then
rpm -Uvh ./libevent-devel-*.rpm
fi
log_info "env check success"
}
function installlibfastcommon() {
if [ ! -f ./libfastcommon-*.tar.gz ]; then
log_error "libfastcommon package not exist,exit"
exit
fi
if [ -d ${fastdfsInstallDIR} ]; then
log_info "libfastcommon has installed,continue"
return 0
fi
tar -zxf ./libfastcommon-*.tar.gz
cd ./libfastcommon*/
sed -i "1 i\DESTDIR=${fastdfsInstallDIR}/libfastcommon/" make.sh
./make.sh clean && ./make.sh && ./make.sh install
chown ${fastdfsUserName}:${fastdfsGroupName} -R ${fastdfsInstallDIR}
chmod 755 -R ${fastdfsInstallDIR}
ln -s ${fastdfsInstallDIR}/libfastcommon/usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
ln -s ${fastdfsInstallDIR}/libfastcommon/usr/lib64/libfastcommon.so /usr/lib64/libfastcommon.so
ln -s ${fastdfsInstallDIR}/libfastcommon/usr/include/fastcommon/ /usr/include/fastcommon
chown ${fastdfsUserName}:${fastdfsGroupName} /usr/lib/libfastcommon.so
chmod 755 /usr/lib/libfastcommon.so
chown ${fastdfsUserName}:${fastdfsGroupName} /usr/lib/libfastcommon.so
chmod 755 /usr/lib64/libfastcommon.so
cd -
}
function installfastDFS() {
if [ ! -f ./fastdfs-*.tar.gz ]; then
log_error "fastdfs package not exist,exit"
return 0
fi
tar -zxf ./fastdfs-*.tar.gz
cd ./fastdfs*/
export DESTDIR="${fastdfsInstallDIR}/fastdfs/"
export LD_LIBRARY_PATH="${fastdfsInstallDIR}/libfastcommon/usr/include/fastcommon/"
./make.sh clean && ./make.sh && ./make.sh install
cd -
cp storage.conf.sample /etc/fdfs/
cp tracker.conf.sample /etc/fdfs/
mkdir -p /opt/changgou/fdfs/data/
mkdir -p /opt/changgou/fdfs/storage/
mkdir -p /opt/changgou/fdfs/tracker/
ln -s ${fastdfsInstallDIR}/fastdfs/usr/include/fastdfs/ /usr/include/fastdfs
ln -s ${fastdfsInstallDIR}/fastdfs/usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so
ln -s ${fastdfsInstallDIR}/fastdfs/usr/lib64/libfdfsclient.so /usr/lib64/libfdfsclient.so
chown ${fastdfsUserName}:${fastdfsGroupName} -R ${fastdfsInstallDIR}
chmod 755 -R ${fastdfsInstallDIR}
chown ${fastdfsUserName}:${fastdfsGroupName} -R /opt/changgou/fdfs/
chmod 755 -R /opt/changgou/fdfs/
chown ${fastdfsUserName}:${fastdfsGroupName} -R /etc/fdfs/
chmod 755 -R /etc/fdfs/
(
crontab -l | grep -v "fdfs_trackerd"
echo "@reboot su -s /bin/bash -c \"${fastdfsInstallDIR}/fastdfs/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf.sample start\" ${fastdfsUserName}"
) | crontab -
(
crontab -l | grep -v "fdfs_storaged"
echo "@reboot su -s /bin/bash -c \"${fastdfsInstallDIR}/fastdfs/usr/bin/fdfs_storaged /etc/fdfs/storage.conf.sample start\" ${fastdfsUserName}"
) | crontab -
}
function configFastDFS() {
echo ""
}
function start() {
su -s /bin/bash -c "${fastdfsInstallDIR}/fastdfs/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf.sample start" ${fastdfsUserName}
su -s /bin/bash -c "${fastdfsInstallDIR}/fastdfs/usr/bin/fdfs_storaged /etc/fdfs/storage.conf.sample start" ${fastdfsUserName}
}
function main() {
checkEnv
addFastDFSUser
installlibfastcommon
installfastDFS
start
}
main
(2)nginx安装 nginx安装时需要fastdfs-nginx-module,需要依赖fastdfs,所以需要先按照fastdfs,再按照nginx,同样创建nginx用户,安装到/opt/nginx目录,同样在redhat7.6安装成功,直接执行install.sh即可。 nginxInstall.conf如下:
nginxDIR="/opt/nginx"
nginxUser="nginx"
nginxGrup="nginx"
nginxUserId=13001
nginxGroupID=13001
nginxPassword="XXXXX"
nginxInstall.sh如下:
#!/bin/bash
source ../utils.sh
source ./nginxInstall.conf
function checkRpm() {
local rpmName=$1
if [ -z "$(yum list installed | grep ${rpmName})" ]; then
local result=$(echo y | yum install ${rpmName})
log_info "${rpmName} is not installed,yum insall ${rpmName} result is: ${result}"
if [[ "${result}" =~ "fail" ]]; then
log_error "${rpmName} install failed"
return 1
else
log_info "${rpmName} is not installed,now installed success"
return 0
fi
else
log_info "${rpmName} is already installed,check pass"
return 0
fi
}
function checkEnv() {
checkRpm "zlib"
checkRpm "zlib-devel"
checkRpm "pcre"
checkRpm "pcre-devel"
}
function addFastDFSUser() {
if id -u ${nginxUser} >/dev/null 2>&1; then
log_info "nginx User has existed,no need create"
return 0
else
groupadd -g "${nginxGroupID}" "${nginxGrup}"
useradd -M "${nginxUser}" -u "${nginxUserId}" -s /sbin/nologin -g "${nginxGroupID}" -p "${nginxPassword}"
echo "${nginxPassword}" | passwd --stdin "${nginxUser}"
log_info "add nginx User success"
fi
}
function nginxInstall() {
if [ ! -f ./nginx-*.tar.gz ]; then
log_error "nginx package not exist,exit"
exit
fi
if [ ! -f ./fastdfs-nginx-*.zip ]; then
log_error "fastdfs-nginx package not exist,exit"
exit
fi
if [ -d ${nginxDIR} ]; then
log_info "nginx has installed,continue"
return 0
fi
checkEnv
addFastDFSUser
tar -zxvf nginx-*.tar.gz >/dev/null 2>&1
unzip fastdfs-nginx-module*.zip >/dev/null 2>&1
cd nginx*
./configure --prefix=${nginxDIR} --add-module=$(pwd)/../fastdfs-nginx-module*/src >/dev/null 2>&1
make
make install
cd -
cp ./nginx.conf ${nginxDIR}/conf/
chown -R ${nginxUser}:${nginxGrup} ${nginxDIR}
chmod -R 755 ${nginxDIR}
su -s /bin/bash -c "cd ${nginxDIR}/sbin/;./nginx" ${nginxUser}
(
crontab -l | grep -v "nginx"
echo "@reboot su -s /bin/bash -c \"cd ${nginxDIR}/sbin/;./nginx\" ${nginxUser}"
) | crontab -
log_info "nginx install success,and started"
}
nginxInstall
安装完成后如下: 安装目录,定时任务,nginx的编译包含fastdfs-nginx-module,进程也处于启动状态。 (3)fastDFS配置 配置未实现自动化,需要手动更改IP等信息 文件位置为:/etc/fdfs/storage.conf.sample /etc/fdfs/tracker.conf.sample /opt/nginx/conf/nginx.conf 此处方法不再赘述,百度很多详解。 (4)测试上传 直接在fastdfs安装目录测试上传即可。 可以看到测试通过。
文件微服务
fastdfs-client选型 (1)开源软件是有生命周期的,可以分为成长期、成熟期、衰退期,尽量引入成长期和成熟期的软件,使用有社区维护的版本,次选稳定版本,无法找到稳定版本时,使用最新版本 (2)选择有许可证的、没有病毒的、来源准确的版本,选择主流社区版本(apache/linux/openstack),防止存在病毒。 (3)开源协议选择apache、BSD,此类没有约束,LGPL,MPL有一定约束,GPL就不要使用了。 按照上面的搜索条件检索之后,选择apache和Spring的插件,最终选择oschina的jar包。
<!-- https://mvnrepository.com/artifact/net.oschina.zcx7878/fastdfs-client-java -->
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
服务构建
FAQ
(1)不需要datasource时,使用@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)排除数据库的自动加载 (2)上传时浏览器报错:net::ERR_SSL_PROTOCOL_ERROR 为跨域问题,在Controller上添加@CrossOrigin
@RestController
@RequestMapping("file")
@Slf4j
@CrossOrigin
public class FileController {
}
(3)上传文件时报错,查看错误日志如下,原因是Storage没有启动, 定位原因如下,可以看到tracker和storage都没有启动,启动后重试 (4)上传文件不成功定位方法 a.手动上传文件尝试是否可以上传成功,尝试后发现可以上传成功 b.调试代码,获取tracker后,等待一段时间,可以看到tarcker的日志 file: tracker_nio.c, line: 218, client ip: 1XXXX, recv timeout. after the connection is established, you must send a request before 60s timeout, maybe connections leak in you application. 此日志说明程序和Tracker连接成功。 c.输出异常和文件的上传后的信息。
|