springboot集成minio完全版瞧柔,坑點(diǎn)很多

本文我們使用springboot集成minio,這里我們沒(méi)有直接使用其starter睦裳,因?yàn)樵趍aven倉(cāng)庫(kù)當(dāng)中只有兩個(gè)版本,且使用不廣泛撼唾。這里我們可以自己寫一個(gè)starter廉邑,其他項(xiàng)目直接引用就可以了。

先說(shuō)一坑,minio的中文文檔版本跟最新的版本完全匹配不上蛛蒙,而英文官網(wǎng)呢糙箍,我有始終無(wú)法訪問(wèn),不知道小伙伴是不是碰到同樣的問(wèn)題牵祟。

關(guān)于minio的搭建參考我的前一篇文章:http://www.reibang.com/p/63dc2947ef91

話不多說(shuō)深夯,進(jìn)入正題。

一诺苹、pom依賴

我是用的版本:

<!-- https://mvnrepository.com/artifact/io.minio/minio -->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.2.1</version>
</dependency>

這里有一坑啊咕晋,本來(lái)我使用的是最新的8.3.0版本,當(dāng)所有代碼都寫完后收奔,發(fā)現(xiàn)啟動(dòng)報(bào)錯(cuò):

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    io.minio.S3Base.<clinit>(S3Base.java:105)

The following method did not exist:

    okhttp3.RequestBody.create([BLokhttp3/MediaType;)Lokhttp3/RequestBody;

The method's class, okhttp3.RequestBody, is available from the following locations:

    jar:file:/D:/apache-maven-3.6.3/repo/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar!/okhttp3/RequestBody.class

It was loaded from the following location:

    file:/D:/apache-maven-3.6.3/repo/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of okhttp3.RequestBody

2021-08-25 13:01:29.975 [graph-editor: N/A] [ERROR] com.vtc.core.analysis.Slf4jFailureAnalysisReporter - 

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    io.minio.S3Base.<clinit>(S3Base.java:105)

The following method did not exist:

    okhttp3.RequestBody.create([BLokhttp3/MediaType;)Lokhttp3/RequestBody;

The method's class, okhttp3.RequestBody, is available from the following locations:

    jar:file:/D:/apache-maven-3.6.3/repo/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar!/okhttp3/RequestBody.class

It was loaded from the following location:

    file:/D:/apache-maven-3.6.3/repo/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of okhttp3.RequestBody

我以為是okhttp這個(gè)版本或者包重復(fù)的問(wèn)題掌呜,一頓鼓搗,發(fā)現(xiàn)沒(méi)用坪哄,最終解決方案是降低了minio的版本到8.2.1质蕉,遇到的小伙伴可以嘗試降版本。

二翩肌、配置文件

我們需要準(zhǔn)備以下內(nèi)容模暗,配置文件yaml中的配置,分別是minio服務(wù)地址念祭,用戶名兑宇,密碼,桶名稱:

minio:
  endpoint: http://172.16.3.28:10000
  accessKey: admin
  secretKey: 12345678
  bucketName: aaa

另外一部分,設(shè)置spring的上傳文件最大限制棒卷,如果仍然不行顾孽,請(qǐng)考慮是否是網(wǎng)關(guān),或nginx仍然需要配置比规,nginx配置在最后的配置文件中我給出了100m的大腥艉瘛:

spring:
  # 配置文件上傳大小限制
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB

三、配置類

此處工需要兩個(gè)配置類蜒什,分別是屬性配置测秸,用來(lái)讀取yaml的配置;另外是初始化MinioClient到spring容器:

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * description: minio配置類
 *
 * @author: weirx
 * @time: 2021/8/25 9:47
 */
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioPropertiesConfig {

    /**
     * 端點(diǎn)
     */
    private String endpoint;
    /**
     * 用戶名
     */
    private String accessKey;
    /**
     * 密碼
     */
    private String secretKey;

    /**
     * 桶名稱
     */
    private String bucketName;
}
import io.minio.MinioClient;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;


/**
 * description: 獲取配置文件信息
 *
 * @author: weirx
 * @time: 2021/8/25 9:50
 */
@Configuration
@EnableConfigurationProperties(MinioPropertiesConfig.class)
public class MinioConfig {

    @Resource
    private MinioPropertiesConfig minioPropertiesConfig;


    /**
     * 初始化 MinIO 客戶端
     */
    @Bean
    public MinioClient minioClient() {
        MinioClient minioClient = MinioClient.builder()
                .endpoint(minioPropertiesConfig.getEndpoint())
                .credentials(minioPropertiesConfig.getAccessKey(), minioPropertiesConfig.getSecretKey())
                .build();
        return minioClient;
    }
}

四灾常、工具類

提供一個(gè)簡(jiǎn)易的工具類供其他服務(wù)直接調(diào)用霎冯,包括上傳、下載:

import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.vtc.core.utils.DownLoadUtils;
import io.minio.*;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @description: minio工具類
 * @author:weirx
 * @date:2021/8/25 10:03
 * @version:3.0
 */
@Component
public class MinioUtil {

    @Value("${minio.bucketName}")
    private String bucketName;

    @Autowired
    private MinioClient minioClient;

    /**
     * description: 判斷bucket是否存在钞瀑,不存在則創(chuàng)建
     *
     * @return: void
     * @author: weirx
     * @time: 2021/8/25 10:20
     */
    public void existBucket(String name) {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * description: 上傳文件
     *
     * @param multipartFile
     * @return: java.lang.String
     * @author: weirx
     * @time: 2021/8/25 10:44
     */
    public List<String> upload(MultipartFile[] multipartFile) {
        List<String> names = new ArrayList<>(multipartFile.length);
        for (MultipartFile file : multipartFile) {
            String fileName = file.getOriginalFilename();
            String[] split = fileName.split("\\.");
            if (split.length > 1) {
                fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];
            } else {
                fileName = fileName + System.currentTimeMillis();
            }
            InputStream in = null;
            try {
                in = file.getInputStream();
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .stream(in, in.available(), -1)
                        .contentType(file.getContentType())
                        .build()
                );
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            names.add(fileName);
        }
        return names;
    }

    /**
     * description: 下載文件
     *
     * @param fileName
     * @return: org.springframework.http.ResponseEntity<byte [ ]>
     * @author: weirx
     * @time: 2021/8/25 10:34
     */
    public ResponseEntity<byte[]> download(String fileName) {
        ResponseEntity<byte[]> responseEntity = null;
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            out = new ByteArrayOutputStream();
            IOUtils.copy(in, out);
            //封裝返回值
            byte[] bytes = out.toByteArray();
            HttpHeaders headers = new HttpHeaders();
            try {
                headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, Constants.UTF_8));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            headers.setContentLength(bytes.length);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setAccessControlExposeHeaders(Arrays.asList("*"));
            responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseEntity;
    }
}

關(guān)于上面的下載文件的返回值問(wèn)題沈撞,我們前端統(tǒng)一返回是這樣,如果其他項(xiàng)目想要使用可以自行修改啊雕什,直接ResponseBody下載缠俺,等等的显晶。此處主要參考如何使用MinioClient上傳,下載文件就好了壹士。

五磷雇、測(cè)試一波

我們使用了springboot集成knife4j,直接通過(guò)網(wǎng)關(guān)訪問(wèn)接口文檔躏救,postman也是一樣的啊唯笙。我提供下面幾個(gè)簡(jiǎn)單的接口來(lái)測(cè)試一下。

    @ApiOperation(value = "minio上傳測(cè)試")
    @PostMapping("/upload")
    public List<String> upload(@RequestParam(name = "multipartFile") MultipartFile[] multipartFile) {
        return minioUtil.upload(multipartFile);
    }

    @ApiOperation(value = "minio下載測(cè)試")
    @GetMapping("/download")
    public ResponseEntity<byte[]> download(@RequestParam String fileName) {
        return minioUtil.download(fileName);
    }

    @ApiOperation(value = "minio創(chuàng)建桶")
    @PostMapping("/existBucket")
    public void existBucket(@RequestParam String bucketName) {
        minioUtil.existBucket(bucketName);
    }

接口頁(yè)面上傳文檔看看:

上傳

一個(gè)坑來(lái)了盒使,發(fā)現(xiàn)返回成功了崩掘,文件名稱。但是在minio的控制臺(tái)沒(méi)有數(shù)據(jù)爸也馈呢堰?

image.png

一看后臺(tái)報(bào)錯(cuò)了,好長(zhǎng)一片:

error occurred
ErrorResponse(code = SignatureDoesNotMatch, message = The request signature we calculated does not match the signature you provided. Check your key and signing method., bucketName = esmp, objectName = null, resource = /esmp, requestId = 169E753DE01FE2AF, hostId = 29aa9dc9-661b-432e-a25f-9856ad3a8250)
request={method=GET, url=http://172.16.3.28:10000/esmp?location=, headers=Host: 172.16.3.28:10000
Accept-Encoding: identity
User-Agent: MinIO (Windows 10; amd64) minio-java/8.2.1
Content-MD5: 1B2M2Y8AsgTpgAmY7PhCfg==
x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date: 20210825T052344Z
Authorization: AWS4-HMAC-SHA256 Credential=*REDACTED*/20210825/us-east-1/s3/aws4_request, SignedHeaders=content-md5;host;x-amz-content-sha256;x-amz-date, Signature=*REDACTED*
}
response={code=403, headers=Server: nginx/1.20.1
Date: Wed, 25 Aug 2021 05:23:43 GMT
Content-Type: application/xml
Content-Length: 367
Connection: keep-alive
Accept-Ranges: bytes
Content-Security-Policy: block-all-mixed-content
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
Vary: Accept-Encoding
X-Amz-Request-Id: 169E753DE01FE2AF
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
}

    at io.minio.S3Base.execute(S3Base.java:667)
    at io.minio.S3Base.getRegion(S3Base.java:691)
    at io.minio.S3Base.putObject(S3Base.java:2003)
    at io.minio.S3Base.putObject(S3Base.java:1153)
    at io.minio.MinioClient.putObject(MinioClient.java:1666)
    at com.vtc.minio.util.MinioUtil.upload(MinioUtil.java:72)
    at com.mvtech.graph.ui.GraphCanvasUI.upload(GraphCanvasUI.java:84)
    at com.mvtech.graph.ui.GraphCanvasUI$$FastClassBySpringCGLIB$$5138ff62.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at com.baidu.unbiz.fluentvalidator.interceptor.FluentValidateInterceptor.invoke(FluentValidateInterceptor.java:211)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at com.mvtech.graph.ui.GraphCanvasUI$$EnhancerBySpringCGLIB$$e773947f.upload(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.github.xiaoymin.knife4j.spring.filter.ProductionSecurityFilter.doFilter(ProductionSecurityFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.github.xiaoymin.knife4j.spring.filter.SecurityBasicAuthFilter.doFilter(SecurityBasicAuthFilter.java:90)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113)
    at com.botany.spore.core.page.PageRequestFilter.doFilterInternal(PageRequestFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:109)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

什么原因呢凡泣?因?yàn)槲业膍inio是集群模式的枉疼,所以我用nginx負(fù)載了,此處就報(bào)錯(cuò)了鞋拟,關(guān)于錯(cuò)誤的nginx配置和如何搭建環(huán)境都在我文章看開頭提的上一篇文章中骂维。

此處改成單節(jié)點(diǎn)的配置立馬就好了,由負(fù)載端口10000改成單節(jié)點(diǎn)端口9000贺纲,之后就都o(jì)k了航闺,無(wú)論上傳下載:

minio:
  endpoint: http://172.16.3.28:9000
  accessKey: admin
  secretKey: 12345678
  bucketName: aaa

如何解決nginx負(fù)載的問(wèn)題呢?
這個(gè)問(wèn)題和nginx反向代理作轉(zhuǎn)發(fā)的時(shí)候所攜帶的header有關(guān)系猴誊,minio在校驗(yàn)signature是否有效的時(shí)候,必須從http header里面獲取host,而我們這里沒(méi)有對(duì)header作必要的處理潦刃。所以我們需要增加以下的配置:

proxy_set_header Host $http_host;

完整的nginx配置如下:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    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  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

   upstream minio {
        server 172.16.3.28:9000 fail_timeout=10s max_fails=2 weight=1;
        server 172.16.3.29:9000 fail_timeout=10s max_fails=2 weight=1;
        server 172.16.3.30:9000 fail_timeout=10s max_fails=2 weight=1;
    }

   upstream minio-console {
        server 172.16.3.28:10001 fail_timeout=10s max_fails=2 weight=1;
        server 172.16.3.29:10001 fail_timeout=10s max_fails=2 weight=1;
        server 172.16.3.30:10001 fail_timeout=10s max_fails=2 weight=1;
    }

    server {
        listen       10000;
        root         /usr/share/nginx/html;
       client_max_body_size        100m; # 文件最大不能超過(guò)100MB
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        proxy_pass http://minio;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $remote_addr;
        proxy_set_header Host $http_host;
    }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
    
    server {
        listen       11000;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                proxy_pass http://minio-console;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $remote_addr;
                proxy_set_header Host $http_host;
        }
                
        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}

再次上傳測(cè)試,成功了:

image.png

到此為止就全部完成啦懈叹!需要作為starter的小伙伴不要忘記配置spring.factories.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乖杠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子澄成,更是在濱河造成了極大的恐慌胧洒,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墨状,死亡現(xiàn)場(chǎng)離奇詭異卫漫,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)肾砂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門列赎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人镐确,你說(shuō)我怎么就攤上這事粥谬「馗” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵漏策,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我臼氨,道長(zhǎng)掺喻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任储矩,我火速辦了婚禮感耙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘持隧。我一直安慰自己即硼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布屡拨。 她就那樣靜靜地躺著只酥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪呀狼。 梳的紋絲不亂的頭發(fā)上裂允,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音哥艇,去河邊找鬼绝编。 笑死,一個(gè)胖子當(dāng)著我的面吹牛貌踏,可吹牛的內(nèi)容都是我干的十饥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼祖乳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼逗堵!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起凡资,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤砸捏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后隙赁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垦藏,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年伞访,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掂骏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厚掷,死狀恐怖弟灼,靈堂內(nèi)的尸體忽然破棺而出级解,到底是詐尸還是另有隱情,我是刑警寧澤田绑,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布勤哗,位于F島的核電站,受9級(jí)特大地震影響掩驱,放射性物質(zhì)發(fā)生泄漏芒划。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一欧穴、第九天 我趴在偏房一處隱蔽的房頂上張望民逼。 院中可真熱鬧,春花似錦涮帘、人聲如沸拼苍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)疮鲫。三九已至,卻和暖如春同蜻,著一層夾襖步出監(jiān)牢的瞬間棚点,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工湾蔓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘫析,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓默责,卻偏偏與公主長(zhǎng)得像贬循,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子桃序,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容