MinIO,Zuul

本文介绍了如何在Spring Cloud项目中集成MinIO作为文件服务,以及如何使用Zuul作为API网关。MinIO的启动和配置、文件上传的实现、访问策略设置等细节都有详细讲解。接着,文章阐述了Zuul网关的配置和使用,包括路由、认证与鉴权的实现,以及简单的限流配置。整个过程展示了微服务架构中文件管理和API安全管理的基本流程。
摘要由CSDN通过智能技术生成

MInIO

MinIO是一个轻量级的适用于存储文件的存储服务,可以轻易的和NodeJS、Redis或MySQL结合

项目中文件服务流程

在这里插入图片描述

由其他服务处理请求后,对于上传文件的请求交给独立的文件服务来执行,对应的文件存储到文件服务器上,而非tomcat容器

minio的启动

通过命令minio.exe server 路径 -address ip+port,来启动服务器,然后通过指定的端口访问
在这里插入图片描述

文件服务实现

  1. 导入依赖
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>7.0.2</version>
        </dependency>
  1. 配置minio链接参数
minio:
  end-point: http://localhost:9000
  access-key: minioadmin
  secret-key: minioadmin
package com.demo.file;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/***
 * @author shaofan
 * @Description
 * @Date 2021-8-12
 * @Time 20:24
 */
@Component
@ConfigurationProperties("minio")
public class MinioProp {

    private String endPoint;
    private String accessKey;
    private String secretKey;

    public String getEndPoint() {
        return endPoint;
    }

    public void setEndPoint(String endPoint) {
        this.endPoint = endPoint;
    }

    public String getAccessKey() {
        return accessKey;
    }

    public void setAccessKey(String accessKey) {
        this.accessKey = accessKey;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    @Override
    public String toString() {
        return "MinioProp{" +
                "endPoint='" + endPoint + '\'' +
                ", accessKey='" + accessKey + '\'' +
                ", secretKey='" + secretKey + '\'' +
                '}';
    }
}

  1. 文件上传
@Controller
@RequestMapping("file")
@ResponseBody
public class FileController {

    @Autowired
    private MinioClient minioClient;

    @PostMapping("upload")
    public ResponseVO upload(MultipartFile file){
        String objectName = null;
        try {

            boolean isExist = minioClient.bucketExists("images");
            if(isExist) {
                System.out.println("Bucket already exists.");
            } else {
                minioClient.makeBucket("images");
                minioClient.setBucketPolicy("picture","{\n" +
                        "    \"Version\": \"2012-10-17\",\n" +
                        "    \"Statement\": [\n" +
                        "        {\n" +
                        "            \"Effect\": \"Allow\",\n" +
                        "          \t\"Principal\":\"*\",\n" +
                        "            \"Action\": [\n" +
                        "                \"s3:GetBucketLocation\",\n" +
                        "                \"s3:GetObject\"\n" +
                        "            ],\n" +
                        "            \"Resource\": [\n" +
                        "                \"arn:aws:s3:::*\"\n" +
                        "            ]\n" +
                        "        }\n" +
                        "    ]\n" +
                        "}" );
            }

            objectName = UUID.randomUUID().toString().replace("-","");
            minioClient.putObject("images", objectName, file.getInputStream(), new PutObjectOptions(file.getInputStream().available(),-1));
        } catch(MinioException e) {
            System.out.println("Error occurred: " + e);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return new ResponseVO(200,objectName);
    }
}

putObject方法参数

桶名
文件名
上传的文件流
上传的选项,第一个参数为上传文件流大小,第二个参数为用于上传的part大小,-1表示与前一个参数相同

访问策略

minio默认是私有访问,无法预览信息,设置访问策略principal字段为*即可使全部用户都可访问
访问策略的json字符串是iam访问策略,不太了解,在minio的图形化界面可以找到几个常用的访问策略

注意
这里为了测试方便存储桶直接写死了,实际开发中存储桶也要像其他参数一样放到yml中,文件后缀的获取也直接写死为jpg

Zuul

概述

Zuul是spring cloud中的微服务api网关,所有请求都会先通过zuul在到达后端的Netflix应用程序,zuul通常用来做四件事情:路由鉴权限流日志

使用网关后,应用向外部暴露一个端口,即网关的端口,剩余服务的端口在局域网中访问,不暴露在外部,外部请求都只能通过网关
没有使用网关时,每一个服务都要考虑到跨域问题,使用网关后就只用在网关考虑跨域问题即可
在这里插入图片描述

环境搭建

  1. 引入依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

由于zuul已经被官方弃用,新版的spring boot是没办法使用的,会报错NoSuchMethod,经测试一下版本可以:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/>
    </parent>
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  1. 在入口类上添加注解@EnableZuulProxy,开启zuul网关
  2. 配置文件,讲zuul注册到注册中心
    模块建好后只通过zuul的主机和端口就可以访问到所有其他的服务的资源,zuul的默认路由是其他服务注册的服务名

路由

zuul:
  routes:
    order:
      path: /order/**
      serviceId: service-order
    user:
      path: /user/**
      serviceId: service-user
  ignored-services:
    - service-user
    - service-order

path表示路由的映射路径,**通配符表示所有资源,比如默认的映射路径就是/service-order/**
serviceId表示注册的服务名
ignored-services可以禁用默认的路由规则

认证与鉴权

实现Zuul的请求过滤操作,需要自定义类继承ZuulFilter类,并实现几个方法

@Component
public class AuthFilter extends ZuulFilter {

    /**
     * 过滤器的类型
     * @return
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;//前置过滤器
    }

    /**
     * 过滤器的优先级,越小则越先调用
     * @return
     */
    @Override
    public int filterOrder() {
        return -4;//默认配置中最小到-3,返回-4保证在所有过滤器之前调用
    }

    /**
     * 是否使用过滤器,可在这里对使用过滤器的请求进行判断
     * @return
     */
    @Override
    public boolean shouldFilter() {
        /*
         *  通过这样的方法可以获得HttpServletRequest,即可通过请求头信息来判断是否使用该过滤器,认证
         */
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        return true;
    }

    /**
     * 过滤器的逻辑方法,这里执行过滤器的逻辑
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        if(request.getHeader("token")==null||request.getHeader("token").equals("")){
            requestContext.setSendZuulResponse(false);//设置是否进行路由,传参为false为不进行路由
            requestContext.setResponseBody("no login");//返回的数据
            requestContext.setResponseStatusCode(HttpStatus.SC_FORBIDDEN);//状态码
        }
        return null;
    }
}
  1. filterType:该方法用于指定过滤器的类型,如前置过滤器(在请求通过之前执行),后置过滤器(在请求通过之后执行)等等
  2. filterOrder:该方法指定执行顺序,返回值越小表示越早执行
  3. FilterConstrants:该类指定了方法的约束条件,使用静态字符串约定好了如filterType,filterOrder的返回值对应的效果
  4. shouldFilter:该方法的返回值决定是否调用接下来的run方法,即是否使用该过滤器,可以通过请求头信息来对指定类型的请求进行过滤
  5. run:该方法用于实现过滤器的逻辑,返回值表示同时执行的额外操作,可以不用管
    这里只简单的实现了认证操作,鉴权和这里差不太多,将shiro+jwt那一套拿来在这里写就行了

限流

  1. 导入依赖
<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>2.0.6.RELEASE</version>
</dependency>
  1. 限流配置
  ratelimit:
    #开启限流
    enabled: true
    #存储方式,推荐使用redis,这里使用in_memory存在内存中方便测试
    repository: in_memory
    #策略
    policies:
      #限流的服务
      user:
        #每个周期内限定请求次数
        limit: 3
        #单位周期内允许访问的总时间
        quota: 30 #表示一个周期内即使请求次数没有达到3次,如果一次请求时间超过30秒也会被限流
        #周期时间
        refresh-interval: 60
        #限流方式:USER(根据用户),ORIGIN(请求源),URL(请求路径)
        type: ORIGIN

如果配置了路由,那么这里的服务名应当是设置的路由的名称

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值