SpringCloudGateway+Nacos+Knife4j

作者: 我犟不过你 | 来源:发表于2020-12-03 15:28 被阅读0次

最近nacos非常火,很多使用eureka的都替换成nacos,既可以做注册中心也可以做配置中心,除此之外还有更好用的功能,今天说一下nacos和gateway做动态路由。

动态路由网上一搜一大堆,真正好使的没几个,其实有更加直接的方式,nacos已经提供了。下面我们一步步看看动态路由怎么配置。

一、Nacos + Gateway动态网关

1.1 引入nacos依赖

在你的gateway项目,和其他微服务中引入nacos,分别是注册中心和配置中心。

<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${nacos.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${nacos.version}</version>
        </dependency>
 <nacos.version>2.2.1.RELEASE</nacos.version>

1.2 gateway配置文件

重点就在以下配置文件的带注释的这一行,这个可以主动将注册中心的服务拉取到网关作为路由,当新服务注册到naocs,会直接添加到网关路由中;从nacos下线的服务会从网关中去除。对比网上增加配置文件,以及代码的动态网关要方便很多。并且不需要在网关中配置路由信息。

spring:
  profiles:
    active: dev
  application:
    name: bssp-gateway-service
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        namespace: 3a44ef28-b35c-44bb-8cd2-873c14ebc911
        group: DEFAULT_GROUP
        file-extension: yml
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: 3a44ef28-b35c-44bb-8cd2-873c14ebc911
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由

1.3 服务调用

通过网关加服务名称调用服务接口:

http://localhost:8888/bssp-user-service/user/info/getById?id=1

结果:

{
    "code": 0,
    "data": {
        "limit": null,
        "page": null,
        "id": "1",
        "nickname": "weirx",
        "realName": "--",
        "username": "weirx",
        "password": "$2a$10$syz1K7t47gJZ79cIs7o0gOvS6hQO7AMlOlEWWKtxtrlJ/jLRRj4iy",
        "sex": 1,
        "phone": "13339411800",
        "certificatesType": 1,
        "certificatesNum": 230523199203134013,
        "address": null,
        "source": 1,
        "isDelete": 0,
        "createTime": "2020-07-23 14:06:56",
        "updateTime": null
    },
    "msg": "操作成功"
}

二、网关整合knife4j

2.1 引入依赖

在每个服务和网关中引入以下依赖

        <!--    knife4j     -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>2.0.3</version>
        </dependency>

2.2 配置文件

在每个服务中增加以下配置,gateway除外,用于在接口界面展示基本信息。

swagger:
  enabled: true
  title: 用户服务
  base-package: com.cloud.bssp.admin
  version: V1.0
  description: 后台admin服务
  license: Apache License, Version 2.0
  license-url: https://www.apache.org/licenses/LICENSE-2.0.html
  terms-of-service-url: http://localhost:8002/doc.html
  contact: xxxxxxxxxxxx@gmail.com
  authorization: #有auth2 并使用以前的swagger-ui
    key-name: Authorization

2.3 增加两个类

package com.cloud.bssp.gateway.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;

import java.util.Optional;

@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {

    /**
     * 权限配置,没有的不用关注
     */
    @Autowired(required = false)
    private SecurityConfiguration securityConfiguration;

    @Autowired(required = false)
    private UiConfiguration uiConfiguration;

    private final SwaggerResourcesProvider swaggerResources;

    @Autowired
    public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
        this.swaggerResources = swaggerResources;
    }


    @GetMapping("/configuration/security")
    public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("/configuration/ui")
    public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    /**
     * 获取接口信息
     * @date: 2020/12/3
     * @param
     * @return reactor.core.publisher.Mono<org.springframework.http.ResponseEntity>
     * @author weirx
     * @version 3.0
     */
    @GetMapping("")
    public Mono<ResponseEntity> swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}

package com.cloud.bssp.gateway.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component
public class SwaggerProvider implements SwaggerResourcesProvider {
    /**
     * 接口地址
     */
    public static final String API_URI = "/v2/api-docs";

    /**
     * 路由加载器
     */
    @Autowired
    private RouteLocator routeLocator;

    /**
     * 网关应用名称
     */
    @Value("${spring.application.name}")
    private String applicationName;

    @Override
    public List<SwaggerResource> get() {
        //接口资源列表
        List<SwaggerResource> resources = new ArrayList<>();
        //服务名称列表
        List<String> routeHosts = new ArrayList<>();
        // 获取所有可用的应用名称
        routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null)
                .filter(route -> !applicationName.equals(route.getUri().getHost()))
                .subscribe(route -> routeHosts.add(route.getUri().getHost()));
        // 去重,多负载服务只添加一次
        Set<String> existsServer = new HashSet<>();
        routeHosts.forEach(host -> {
            // 拼接url
            String url = "/" + host + API_URI;
            //不存在则添加
            if (!existsServer.contains(url)) {
                existsServer.add(url);
                SwaggerResource swaggerResource = new SwaggerResource();
                swaggerResource.setUrl(url);
                swaggerResource.setName(host);
                resources.add(swaggerResource);
            }
        });
        return resources;
    }

}

2.4 结果

访问以下地址:http://localhost:8888/doc.html

接口文档

相关文章

  • SpringCloudGateway+Nacos+Knife4j

    最近nacos非常火,很多使用eureka的都替换成nacos,既可以做注册中心也可以做配置中心,除此之外还有更好...

网友评论

    本文标题:SpringCloudGateway+Nacos+Knife4j

    本文链接:https://www.haomeiwen.com/subject/pbemwktx.html