Gateway--服务网关

网关简介

大家都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用 这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。

这样的架构,会存在着诸多的问题:

  • 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
  • 认证复杂,每个服务都需要独立认证。
  • 存在跨域请求,在一定场景下处理相对复杂。

上面的这些问题可以借助API网关来解决。

所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等等。 添加上API网关之后,系统的架构图变成了如下所示:

Gateway快速入门

要求: 通过浏览器访问api网关,然后通过网关将请求转发到商品微服务

第1步:创建一个api-gateway 的模块,导入相关依赖

xml 复制代码
<dependencies>
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-gateway</artifactId>
     </dependency>
     <!--nacos客户端-->
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
     </dependency>
     <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
     </dependency>

     <!--限流-->
     <dependency>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
     </dependency>
 </dependencies>

第2步: 创建主类

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class);
    }
}

第3步: 添加配置文件

yaml 复制代码
server:
  port: 7000
spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # 将gateway注册到nacos
    gateway:
      discovery:
        locator:
          enabled: true # 让gateway从nacos中获取服务信息

第4步:启动项目,并通过网关去访问微服务

localhost:7000/service-product/product/1

解释:

  • localhost:7000 网关服务地址
  • service-product 微服务name
  • product/1 接口地址

这时候,就发现只要按照网关地址/微服务/接口的格式去访问,就可以得到成功响应。

自定义全局过滤器(鉴权)

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

//自定义全局过滤器(作用: 统一鉴权)需要实现GlobalFilter和Ordered接口
@Slf4j
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    //完成判断逻辑
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if (!StringUtils.equals(token, "admin")) {
            log.info("鉴权失败");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        //调用chain.filter继续向下游执行
        return chain.filter(exchange);
    }

    //顺序,数值越小,优先级越高
    @Override
    public int getOrder() {
        return 0;
    }
}

不加token认证不通过,返回401

加token=admin认证通过

相关推荐
lkasi14 分钟前
python文字转wav音频
开发语言·python
白茶等风1213824 分钟前
C#_封装详解
开发语言·c#
程序员阿鹏33 分钟前
ArrayList 与 LinkedList 的区别?
java·开发语言·后端·eclipse·intellij-idea
18你磊哥35 分钟前
java重点学习-JVM类加载器+垃圾回收
java·jvm
聂 可 以37 分钟前
在SpringBoot项目中利用Redission实现布隆过滤器(布隆过滤器的应用场景、布隆过滤器误判的情况、与位图相关的操作)
java·spring boot·redis
长安初雪1 小时前
Java客户端SpringDataRedis(RedisTemplate使用)
java·redis
繁依Fanyi1 小时前
使用 Spring Boot + Redis + Vue 实现动态路由加载页面
开发语言·vue.js·pytorch·spring boot·redis·python·算法
aloha_7891 小时前
B站宋红康JAVA基础视频教程(chapter14数据结构与集合源码)
java·数据结构·spring boot·算法·spring cloud·mybatis
星尘安全1 小时前
一种新的电子邮件攻击方式:AiTM
开发语言·网络安全·php·网络钓鱼·aitm
尘浮生1 小时前
Java项目实战II基于Java+Spring Boot+MySQL的洗衣店订单管理系统(开发文档+源码+数据库)
java·开发语言·数据库·spring boot·mysql·maven·intellij-idea