import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
public class MinioUtils {
* 配置自己服务的IP与端口号 这里设置就是上面Nginx中 Minio API 里面的端口别搞混了
private static final String server = "http://1公网IP:9002";
* access_key
private static final String accessKey = "申请的key";
* secret_key
private static final String secretKey = "申请的key";
* MinioClient客户端
private static MinioClient client;
* 初始化连接
public static void initClient() {
try {
client = MinioClient
.builder()
.endpoint(server)
.credentials(accessKey, secretKey)
.build();
} catch (Throwable e) {
throw new RuntimeException(e);
* 获取桶列表
* @return 桶列表
public static List<Bucket> getAllBucketList() {
try {
return client.listBuckets();
} catch (Throwable e) {
throw new RuntimeException(e);
* 创建桶或者文件夹
* @param bucketName 桶名
* @param prefix 文件夹名称
public static void createBucketOrFolder(String bucketName, String prefix) {
try {
if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
if (!isFolderExits(bucketName, prefix)) {
client.putObject(PutObjectArgs.builder().bucket(bucketName).object(prefix)
.stream(new ByteArrayInputStream(new byte[]{}), 0, -1).build());
} catch (Throwable e) {
throw new RuntimeException(e);
* <p>文件上传</p>
* <li>桶的概念就类似我们PC的“此电脑”,在“此电脑”下面才会存在我们不同的盘符,不同的盘符中有不同文件夹或者文件</li>
* <li>在桶里面的文件的objectName与文件夹的objectName显示存在差异,具体可以调试桶列表查看</li>
* <li>桶里面的文件夹实际就是前缀,它后面跟随的文件夹分割符号往往与我们部署的系统环境有关</li>
* </ul>
* @param bucketName 桶名称
* @param prefix 桶内文件路径 例如: Demo桶下存在文件夹 它的objectName则为 folder/
* @param in 文件流
* @param fileFormatType 文件后缀 例如: .png .svg .xlsx 等
* @return 范围服务器端的文件随机名称 例如:35ecae61-d6a6-4ce0-8175-e506dcdbc07a.png
public static String putObject(String bucketName, String prefix, InputStream in, String fileFormatType) {
try {
String key = UUID.randomUUID().toString() + fileFormatType;
client.putObject(
PutObjectArgs
.builder()
.bucket(bucketName)
.object(prefix + key)
.stream(in, in.available(), -1)
.contentType("application/octet-stream")
.build());
return key;
} catch (Throwable e) {
throw new RuntimeException(e);
* 获取文件信息 这里就用Minio原生模板类展示
* <p>如果是存在文件路径下的文件,例如objectName = "demo/avatar.png" </p>
* @param bucketName 桶名
* @param objectName 文件名称
* @return StatObjectResponse
public static StatObjectResponse getObjectInfo(String bucketName, String objectName) {
try {
return client.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
} catch (Throwable e) {
throw new RuntimeException(e);
* 获取文件下载链接,此链接是Minio提供的链接
* @param bucketName 桶名
* @param objectName 文件名称,如果存在文件路径下的文件,例如objectName = "demo/avatar.png"
* @return String 下载链接
public static String getObjectUrl(String bucketName, String objectName) {
try {
return client.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(objectName)
.build());
} catch (Throwable e) {
throw new RuntimeException(e);
* 读取文件流的方式获取文件
* @param bucketName 桶名
* @param objectName 文件名称,如果存在文件路径下的文件,例如objectName = "demo/avatar.png"
* @return InputStream 字节输入流
public static InputStream getObjectStream(String bucketName, String objectName) {
try {
return client.getObject(
GetObjectArgs
.builder()
.bucket(bucketName)
.object(objectName)
.build());
} catch (Throwable e) {
throw new RuntimeException(e);
* 判断桶和文件夹是否存在
* @param bucketName 桶名称
* @param prefix 文件夹 格式: folder/
* @return boolean 是否存在
public static boolean isFolderExits(String bucketName, String prefix) {
try {
if (null != prefix && !"".equals(prefix)) {
Iterable<Result<Item>> results = client.listObjects(ListObjectsArgs.builder().bucket(bucketName)
.prefix(prefix).recursive(false).build());
for (Result<Item> result : results) {
Item item = result.get();
if (item.isDir()) {
return true;
} catch (Throwable e) {
throw new RuntimeException(e);
return false;
- 由于桶下面包含文件和文件夹,它们的区别就是存在文件夹分割符号,Linux / window \,具体区别可以通过上面getAllBucketList() 方法查看差异
- 上传文件最好追加文件后缀,不然获取下载链接的时候,就需要前端工作人员对流文件进行明明,由于前端不一定知道文件的类型,所以尽量还是跟上后缀比较方便
- 在业务层面要注意参数的判空处理,提升代码的质量性
- 因为我使用的是Nginx代理转发,关于前面说到的$http_host配置问题,如果不加上的话,可能转发的时候直接把URL后面的签名给丢了,导致上面的utils中的方法不可用了。
CReSCENT:CanceR单细胞表达工具包(Web应用程序)-开发人员文档
有关用户手册,请转到CReSCENT文档: ://pughlab.github.io/crescent-frontend/
Git(克隆此仓库)
克隆此minio/download并创建文件夹results , minio/download和minio/upload (错误修复)。
将sample.env复制到.env然后将react/sample.env复制到react/.env并根据需要进行自定义。
npm install安装服务器依赖项。 docker-compose up以启动服务器后端。
如果您使用的是Windows或Mac,请确保GRAPHENE_DEV中的GRAPHENE_DEV变量设置为True ,并在文件共享中从.env共享/var/lib/toil .env 。
mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现,采用Docker容器化部署。前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。后台管理系统包含商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等模块。
开发环境:
JDK 1.8
Mysql 5.7
Redis 5.0
MongoDB 4.2.5
RabbitMQ 3.7.14
Nginx 1.10
Elasticsearch 7.6.2
Logstash 7.6.2
Kibana 7.6.2
搭建步骤:
1、Windows环境部署
Windows环境搭建请参考:mall在Windows环境下的部署;
注意:只启动mall-admin,仅需安装Mysql、Redis即可;
克隆mall-admin-web项目,并导入到IDEA中完成编译:前端项目地址;
mall-admin-web项目的安装及部署请参考:mall前端项目的安装与部署。
2、Docker环境部署
使用虚拟机安装CentOS7.6请参考:虚拟机安装及使用Linux,看这一篇就够了;
Docker环境的安装请参考:开发者必备Docker命令;
本项目Docker镜像构建请参考:使用Maven插件为SpringBoot应用构建Docker镜像;
本项目在Docker容器下的部署请参考:mall在Linux环境下的部署(基于Docker容器);
本项目使用Docker Compose请参考: mall在Linux环境下的部署(基于Docker Compose);
本项目在Linux下的自动化部署请参考:mall在Linux环境下的自动化部署(基于Jenkins);
3、相关环境部署
ELK日志收集系统的搭建请参考:SpringBoot应用整合ELK实现日志收集;
使用MinIO存储文件请参考:前后端分离项目,如何优雅实现文件存储;
读写分离解决方案请参考:你还在代码里做读写分离么,试试这个中间件吧;
Redis集群解决方案请参考:Docker环境下秒建Redis集群,连SpringBoot也整上了!。
docker-compose使用示例
利用docker搭建一个mysql + java service + nginx,总共4个docker容器,如果采用docker run的方式一个一个容器去创建十分麻烦。为了能更高效的批量创建容器,docker推出了docker-compose工具,只需要定义一个docker-compose.yml文件即可快速搞定一组容器的创建,
mysql:
image: daocloud.io/yjmyzz/mysql-osx:latest
volumes:
- ./mysql/db:/var/lib/mysql
ports:
- 3306:330
docker-compsose 搭建minio集群(2021-10月-11月左右的版本)+nginx反向代理及负载均衡(配置超详细讲解)
本文章适合有一定docker基础的朋友观看,如果觉得博主创作的好,麻烦点个赞和关注下,更多内容关注动态。最好大家版本同一,避免不必要的麻烦(镜像版本在compose文件里面有,下载即可)
首先我们需要配置docker-compse文件,配置文件的路径自选(我自己的放在/home目录下的)。并且由于官方的文件地址打不开,所以我会放到我的gitee上,链接统一的放到最后