每天进步一点点---------畅购商城第三天 文件微服务(单机版)

在练习畅购商城项目,依赖畅购商城的文件微服务,边学变练,做一个整理,目前是单机部署,集群还未尝试。

文件微服务架构

自己理解的部署图,可能并不标准,哪位大神懂的话,可以指点一下,其中,Web或者其它微服务会调用文件微服务,需要头信息的Content=Type为Multipart/form-data,文件微服务相当于FastDFS的客户端,调用FastDFS tracker,Tracker调用Storage,实现文件的存储,Storage需要安装nginx和fastdfs-nginx-module实现文件同步,此尝试全部在一台虚拟机使用。
每天进步一点点---------畅购商城第三天 文件微服务(单机版)_第1张图片

安装

(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脚本可以直接安装成功,具体目录如下:
每天进步一点点---------畅购商城第三天 文件微服务(单机版)_第2张图片
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() {
	# 启动tracker
	su -s /bin/bash -c "${fastdfsInstallDIR}/fastdfs/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf.sample start" ${fastdfsUserName}
	#启动storage
	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即可。
每天进步一点点---------畅购商城第三天 文件微服务(单机版)_第3张图片
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,进程也处于启动状态。
每天进步一点点---------畅购商城第三天 文件微服务(单机版)_第4张图片
(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包。
每天进步一点点---------畅购商城第三天 文件微服务(单机版)_第5张图片

<!-- 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)排除数据库的自动加载
每天进步一点点---------畅购商城第三天 文件微服务(单机版)_第6张图片
(2)上传时浏览器报错:net::ERR_SSL_PROTOCOL_ERROR
为跨域问题,在Controller上添加@CrossOrigin

@RestController
@RequestMapping("file")
@Slf4j
@CrossOrigin
public class FileController {
}

(3)上传文件时报错,查看错误日志如下,原因是Storage没有启动,
每天进步一点点---------畅购商城第三天 文件微服务(单机版)_第7张图片
定位原因如下,可以看到tracker和storage都没有启动,启动后重试
每天进步一点点---------畅购商城第三天 文件微服务(单机版)_第8张图片
(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.输出异常和文件的上传后的信息。
在这里插入图片描述

你可能感兴趣的:(畅购商城,微服务,java,microservices)