一、第一部分
linux安装
启动之后有需要开放两个端口!!!
# 下载 minio
wget https://dl.min.io/server/minio/release/linux-amd64/minio
# 添加可执行权限
chmod +x minio
# 临时启动(/home/minio/data 为你存放静态文件的目录)
./minio server /home/minio/data
# 后台启动,并打印日志
nohup ./minio server /home/minio/data > /home/minio/data/minio.log &
# 自定义端口启动
./minio server --address 192.168.9.128:9111 /home/minio/data
# 后台启动 并自定义服务端口和后台管理端口
nohup ./minio server --address :9000 --console-address :9900 /feishu/minio/data > /feishu/minio/minio.log &
# 自定义文件夹地址
export MINIO_VOLUMES="/home/minio/data"
# 自定义登录minio的 access key
export MINIO_ACCESS_KEY=minioadmin
# 自定义登录minio的 secret key
export MINIO_SECRET_KEY=minioadmin
# 默认 AccessKey 和 SecretKey
AccessKey:minioadmin
SecretKey:minioadmin
# 默认端口
9000
# 访问地址
http://127.0.0.1:9000
# 开放9000端口
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --reload
windows安装
# 下载地址
https://dl.min.io/server/minio/release/windows-amd64/minio.exe
# 1.进入 minio.exe 存放目录(D:\minio\data 为你存放静态文件的目录,即存放bucket的目录,bucket下有图片)
cd D:/minio/
# 2.执行命令 (该命令在minio.exe所在目录下执行)
minio.exe server D:\minio\data
# 启动后会打印出 AccessKey 和 SecretKey 等信息
yml中配置
minio :
endpoint : http://192.168.2.16:9000
accesskey : minioadmin
secretkey : minioadmin
解决限制文件大小
默认被限制为最大1MB
spring:
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
file-size-threshold: 100MB
相关依赖
<!-- minio 相关依赖 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>3.0.10</version>
</dependency>
<!-- alibaba的fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
<!-- 图片压缩 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
完整工具类
/**
* @Description
* @Author 金飞鹏 2021/9/22 11:44
* Made in China
*/
@Slf4j
@Component
public class MinioUtils {
private MinioClient client;
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.accesskey}")
private String accessKey;
@Value("${minio.secretkey}")
private String secretKey;
//初始化
@PostConstruct
public void init() throws InvalidPortException, InvalidEndpointException {
client = new MinioClient(endpoint,accessKey,secretKey);
}
/**
* 创建bucket
*
* @param bucketName bucket名称
*/
@SneakyThrows
public void createBucket(String bucketName) {
if (!client.bucketExists(bucketName)) {
client.makeBucket(bucketName);
}
}
/**
* 获取全部bucket
*/
@SneakyThrows
public List<Bucket> getAllBuckets() {
return client.listBuckets();
}
/**
* 根据bucketName获取信息
*
* @param bucketName bucket名称
*/
@SneakyThrows
public Optional<Bucket> getBucket(String bucketName) {
return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
}
/**
* 根据bucketName删除信息
*
* @param bucketName bucket名称
*/
@SneakyThrows
public void removeBucket(String bucketName) {
client.removeBucket(bucketName);
}
/**
* 获取文件外链
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param expires 过期时间 <=7
* @return url
*/
@SneakyThrows
public String getObjectURL(String bucketName, String objectName, Integer expires) {
return client.presignedGetObject(bucketName, objectName, expires);
}
/**
* 获取文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @return 二进制流
*/
@SneakyThrows
public InputStream getObject(String bucketName, String objectName) {
return client.getObject(bucketName, objectName);
}
/**
* 上传文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param stream 文件流
* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
*/
public void putObject(String bucketName, String objectName, InputStream stream) throws Exception {
client.putObject(bucketName, objectName, stream, stream.available(), "application/octet-stream");
}
/**
* 上传文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param stream 文件流
* @param size 大小
* @param contextType 类型
* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
*/
public void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception {
client.putObject(bucketName, objectName, stream, size, contextType);
}
/**
* 获取文件信息
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject
*/
public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception {
return client.statObject(bucketName, objectName);
}
/**
* 删除文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject
*/
public void removeObject(String bucketName, String objectName) throws Exception {
client.removeObject(bucketName, objectName);
}
/**
* 上传文件
*
* @param file 文件
* @param bucketName 存储桶
* @return
*/
public JSONObject uploadFile(MultipartFile file, String bucketName) throws Exception {
JSONObject res = new JSONObject();
res.put("code", 0);
// 判断上传文件是否为空
if (null == file || 0 == file.getSize()) {
res.put("msg", "上传文件不能为空");
return res;
}
// 判断存储桶是否存在
createBucket(bucketName);
// 文件名
String originalFilename = file.getOriginalFilename();
// 新的文件名
String fileName = bucketName + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));
// 开始上传
client.putObject(bucketName, fileName, file.getInputStream(), file.getContentType());
res.put("code", 1);
res.put("msg", endpoint + "/" + bucketName + "/" + fileName);
return res;
}
/**
* 判断文件是否为图片
*/
public boolean isPicture(String imgName) {
boolean flag = false;
if ("".equals(imgName) || null == imgName) {
return false;
}
String[] arr = {"bmp", "dib", "gif", "jfif", "jpe", "jpeg", "jpg", "png", "tif", "tiff", "ico"};
for (String item : arr) {
if (item.equals(imgName)) {
flag = true;
break;
}
}
return flag;
}
/**
* 压缩上传文件
*
* @param file 文件
* @return
*/
public JSONObject compressionUploadFile(MultipartFile file) throws Exception {
JSONObject res = new JSONObject();
res.put("code", 500);
// 判断上传文件是否为空
if (null == file || 0 == file.getSize()) {
res.put("msg", "上传文件不能为空");
return res;
}
// 判断存储桶是否存在
if (!client.bucketExists("jinfeipeng")) {
client.makeBucket("jinfeipeng");
}
// 拿到文件后缀名,例如:png
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
// UUID 作为文件名
String uuid = String.valueOf(UUID.randomUUID());
// 新的文件名
SimpleDateFormat sp =new SimpleDateFormat("yyyyMMdd");
String date = sp.format(new Date());
String fileName = date + uuid + "." + suffix;
/**
* 判断是否是图片
* 判断是否超过了 100K
*/
if (isPicture(suffix) && (1024 * 1024 * 0.1) <= file.getSize()) {
// 在项目根目录下的 upload 目录中生成临时文件
File newFile = new File(ClassUtils.getDefaultClassLoader().getResource("static").getPath() + uuid + "." + suffix);
// 小于 1M 的
if ((1024 * 1024 * 0.1) <= file.getSize() && file.getSize() <= (1024 * 1024)) {
Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.3f).toFile(newFile);
}
// 1 - 2M 的
else if ((1024 * 1024) < file.getSize() && file.getSize() <= (1024 * 1024 * 2)) {
Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.2f).toFile(newFile);
}
// 2M 以上的
else if ((1024 * 1024 * 2) < file.getSize()) {
Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.1f).toFile(newFile);
}
// 获取输入流
FileInputStream input = new FileInputStream(newFile);
// 转为 MultipartFile
MultipartFile multipartFile = new MockMultipartFile("file", newFile.getName(), "text/plain", input);
// 开始上传
client.putObject("jinfeipeng", fileName, multipartFile.getInputStream(), file.getContentType());
// 删除临时文件
newFile.delete();
// 返回状态以及图片路径
res.put("code", 200);
res.put("msg", "上传成功");
res.put("url", endpoint + "/" + fileName);
}
// 不需要压缩,直接上传
else {
// 开始上传
client.putObject("jinfeipeng", fileName, file.getInputStream(), file.getContentType());
// 返回状态以及图片路径
res.put("code", 200);
res.put("msg", "上传成功");
res.put("url", endpoint + "/" + fileName);
}
return res;
}
}
示例
@Controller
public class MyController {
@Autowired
private MinioUtils minioUtils;
@GetMapping("/index")
public String index(){
return "index";
}
@PostMapping("/upload")
@ResponseBody
public String upload(@RequestParam(value = "file",required = false) MultipartFile file) {
System.out.println(file);
JSONObject res = null;
try {
res = minioUtils.compressionUploadFile(file);
} catch (Exception e) {
e.printStackTrace();
res.put("code", 0);
res.put("msg", "上传失败");
}
return res.toJSONString();
}
}
二、 第二部分
部署客户端mc (自此以下的文章部分,可不阅读)
wget http://dl.minio.org.cn/client/mc/release/linux-amd64/mc
chmod +x mc
./mc --help
mv mc /usr/local/sbin/
# 剪切到/usr/local/sbin 这个目录下的原因是可以在客户端任何地方使用
配置mc
mc 将所有的配置信息都存储在 ~/.mc/config.json 文件中
# 查询mc host配置
mc config host ls
# 添加minio服务
mc config host add minio-server http://192.168.3.14:9000 admin 12345678
### 解释:
#### 1.minio-server 是 你这个minio服务的别名
#### 2.http://192.168.3.14:9000 是你这个minio的访问链接,如果配置了https,这个ip需要改为域名。
#### 3.admin 12345678 是你这个minio的账号密码
# 删除host
mc config host remove minio-server
mc命令使用
上传下载
# 查询minio服务上的所有buckets(文件和文件夹)
mc ls minio-server
# 下载文件
mc cp minio-server/tulingmall/fox/fox.jpg /tmp/
# 删除文件
mc rm minio-server/tulingmall/fox/fox.jpg
# 上传文件
mc cp zookeeper.out minio-server/tulingmall/
Bucket管理
# 创建bucket
mc mb minio-server/bucket01
# 删除bucket
mc rb minio-server/bucket02
# bucket不为空,可以强制删除 慎用
mc rb --force minio-server/bucket01
# 查询bucket03磁盘使用情况
mc du minio-server/bucket03