docker安装说明: https://blog.csdn.net/song_java/article/details/88061162
docker镜像地址: https://store.docker.com/community/images/season/fastdfs
宿主机IP地址: 192.168.174.129
使用docker-compose运行fastdfs
version: '2'
services:
tracker:
image: season/fastdfs:1.2
restart: always
volumes:
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
- "./tracker_data:/fastdfs/tracker/data"
network_mode: "host"
command: "tracker"
storage:
image: season/fastdfs:1.2
restart: always
volumes:
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
- "./storage_base_path:/fastdfs/storage/data"
- "./store_path0:/fastdfs/store_path"
environment:
TRACKER_SERVER: "192.168.174.129:22122"
network_mode: "host"
command: "storage"
nginx:
image: season/fastdfs:1.2
restart: always
volumes:
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
- "./nginx.conf:/etc/nginx/conf/nginx.conf"
- "./store_path0:/fastdfs/store_path"
environment:
TRACKER_SERVER: "192.168.174.129:22122"
network_mode: "host"
command: "nginx"
根据docker-compose.yml我们看到主要有3个模块: tracker storage nginx
tracker
挂载 /fastdfs/tracker/data ,这个目录对应的是 tracker.conf中的 base_path
storage
挂载/fastdfs/storage/data ,这个目录对应的是 /fdfs_conf/storage.conf中的base_path
挂载/fastdfs/store_path ,这个目录对应的是/fdfs_conf/storage.conf中的store_path0
环境变量: GROUP_NAME 对应 /fdfs_conf/storage.conf中的group_name
TRACKER_SERVER 对应 /fdfs_conf/storage.conf中的tracker_server
nginx
需要修改nginx的配置文件 /etc/nginx/conf/nginx.conf,因此在宿主机新建一个nginx.conf挂载到/etc/nginx/conf/nginx.conf
nginx.conf配置文件如下
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /group1/M00 {
root /fastdfs/storage/data;
ngx_fastdfs_module;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
注意到 nginx.conf中有下面一段代码
location /group1/M00 {
root /fastdfs/storage/data;
ngx_fastdfs_module;
}
可以看到nginx使用了storage的store_path0,因此需要将store_path0挂载到nginx中 (docker-compose.yml中的volumes下的
"./store_path0:/fastdfs/store_path" 就是干这个的)
只要运行 docker-compose up -d 即可启动这三个模块
启动之后,我们可以通过Java代码验证验证一下,下面介绍一下Java的nginx客户端的使用
(1) 引入maven依赖
net.oschina.zcx7878
fastdfs-client-java
1.27.0.0
(2)编写Java处理代码
import com.google.common.io.Files;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Map;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FastdfsClient {
private static final Logger LOG = LoggerFactory.getLogger(FastdfsClient.class);
private static StorageClient1 storageClient1 = null;
private static String trackerServerUrl = null;
//初始化FastDFS Client
static {
try {
ClientGlobal.init("src/main/resources/fdfs_client.conf");
TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
TrackerServer trackerServer = trackerClient.getConnection();
trackerServerUrl = trackerServer.getInetSocketAddress().getHostString();
LOG.info("trackerServerUrl={}",trackerServerUrl);
StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
storageClient1 = new StorageClient1(trackerServer, storageServer);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String uploadFile(File file , Map meta) {
try {
byte[] buff = readFromFile(file);
NameValuePair[] nameValuePairs = null;
if (meta != null) {
nameValuePairs = new NameValuePair[meta.size()];
int index = 0;
for (Map.Entry entry : meta.entrySet()) {
String name = entry.getKey();
String value = entry.getValue();
nameValuePairs[index++] = new NameValuePair(name, value);
}
}
String fileExt = Files.getFileExtension(file.getName()) ;
return storageClient1.upload_file1(buff, fileExt, nameValuePairs);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static int downloadFile(String fileId, String filePath) {
FileOutputStream fos = null;
try {
byte[] content = storageClient1.download_file1(fileId);
writeToFile(content, filePath);
return 0;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return -1;
}
private static byte[] readFromFile(File file) throws Exception {
try (FileInputStream inputStream = new FileInputStream(file)) {
FileChannel fileChannel=inputStream.getChannel();
int fileSize = (int)fileChannel.size() ;
ByteBuffer buffer = ByteBuffer.allocate(fileSize);
fileChannel.read(buffer);
return buffer.array();
}
}
public static void writeToFile(byte[] content, String filePath) throws Exception {
try (FileOutputStream outputStream = new FileOutputStream(filePath)) {
outputStream.write(content);
}
}
}
(3) 上述代码中使用到了配置文件 src/main/resources/fdfs_client.conf
connect_timeout = 60
network_timeout = 60
charset = UTF-8
http.tracker_http_port = 8080
http.anti_steal_token = no
#tracker服务地址
tracker_server = 192.168.174.129:22122
(4)测试验证
@Test
public void testUpload() {
File file = new File("pom.xml");
Map meta = Maps.newHashMap();
String fileid = FastdfsClient.uploadFile(file, meta);
assertNotNull(fileid);
System.out.println(fileid);
int result = FastdfsClient.downloadFile(fileid, "tmp.xml");
Assert.assertEquals(0, result);
}
文件上传成功之后会返回一个fileid,类似这样的 group1/M00/00/00/wKiugVtpZxKAXoGKAAAR-ooLxT0919.xml
文件下载时,需要将这个fieldid作为入参传入
从这段代码来看,貌似我们并没用到nginx,事实确实如此,那么nginx是干什么的呢?nginx是为了我们能够通过地址去访问文件,如上面的fileid前加上nginx所在的服务器即可在浏览器访问 (http://192.168.174.129/group1/M00/00/00/wKiugVtpZxKAXoGKAAAR-ooLxT0919.xml)