Gateway--服务网关

目录

 配置集群

1.准备三个nacos服务器---为了操作方便统一部署到同一台电脑

1.1 创建数据库

 ​编辑

​编辑1.2 指定使用mysql作为数据存储

1.3 配置集群文件

1.4 停止nacos并复制三份

1.5  启动三个nacos

 1.6 搭建nginx代理上面三个nacos

 1.7 微服务注册到nacos集群上

2 网关简介

3 Gateway简介

4 Gateway快速入门

4.1 创建一个gateway的工程并加入依赖

4.2 创建启动类

4.3 修改配置文件

4.4 启动项目, 并通过网关去访问微服务

5.1 让gateway网关从注册中心拉取服务型

5.2 gateway自动路由

 5.3  介绍Gateway断言

5.4  过滤器

5.4 全局过滤器

6 nacos配置管理


 配置集群

在实际开发过程中,如果使用Nacos的话,为了确保高可用,我们一般都会对其进行集群的部署。Nacos规定集群中Nacos节点的数量需要大于等于3个;同时,单机模式下Nacos的数据认保存在其内嵌数据库中deby,不方便观察数据存储的基本情况。而且如果集群中启动多个认配置下的Nacos节点,数据存储是存在一致性问题的。为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只支持MysqL的存储;此外,我们还需要借助Nginx实现负载均衡。这一过程的部署架构图如下所示:


1.准备三个nacos服务器---为了操作方便统一部署到同一台电脑


1.1 创建数据库

 


1.2 指定使用MysqL作为数据存储

1.3 配置集群文件

 

 

1.4 停止nacos并复制三份

 

 并修改每一份的端口号


1.5  启动三个nacos

 

 

 1.6 搭建Nginx代理上面三个nacos

 

 1.7 微服务注册到nacos集群上

2 网关简介

大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端(pc androud ios 平板)要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。 axios.get(ip:port/url)   axios.get(ip:port/url)

 

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

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

(跨域: 浏览器的ajax从一个地址访问另一个地址:

   协议://ip:port  如果三则有一个不同,则会出现跨域问题。

    http://192.168.10.11:8080 ----->https://192.168.10.11:8080

    http://127.0.0.1:8080--->http://localhost:8080  跨域

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

 

3 Gateway简介

Spring Cloud Gateway是Spring公司基于Spring 5.0,Spring Boot 2.0 和 Project Reactor 等术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。

优点:

    性能强劲:是第一代网关Zuul的1.6倍
    功能强大:内置了很多实用的功能,例如转发、监控、限流
    设计优雅,容易扩展.

缺点:  

    其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高
    不能将其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包执行 web.Jar
    需要Spring Boot 2.0及以上的版本,才支持

gateway内置了服务器 netty服务器。


4 Gateway快速入门

 

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

4.1 创建一个gateway的工程并加入依赖

   

 <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>qy151-dyt-parent</artifactId>
            <groupId>com.dyt</groupId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
     
        <artifactId>qy151-dyt-gateway</artifactId>
     
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
    </project>

4.2 创建启动类

   

 package com.dyt;
     
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
     
    /**
     * @author dyt
     */
    @SpringBootApplication
    public class GatewayApp {
        public static  void main(String[] args){
            SpringApplication.run(GatewayApp.class,args);
        }
    }

4.3 修改配置文件

    server:
      port: 7001
     
     
    spring:
      application:
        name: dyt-gateway
     
      cloud:
        nacos:
          discovery:
            register-enabled: false
            server-addr: localhost:81

    #
    #    gateway:
    #      discovery:
    #        locator:
    #          enabled: true
     
        gateway:
          routes:
            - id: xzj-order
              uri: lb://order
              predicates:
                - Path=/order/**
            - id: xzj-product
              uri: lb://product
              predicates:
                - Path=/product/**
              filters:
                - SetStatus=300

 

4.4 启动项目, 并通过网关去访问微服务


5 让gateway网关从注册中心拉取服务型


5.1 让gateway网关从注册中心拉取服务型

(1)引入依赖

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

(2)配置文件中指定注册中心的地址

 发现: 有一个微服务需要配置一个路由,如果这时增加一个新的微服
务,则需要在配置文件增加一个新的路由配置。
能不能自动路由转发微服务呢!====能


5.2 gateway自动路由

修改配置文件:

 

 访问时:
http://网关的ip:网关的port/微服务名称/资源路径

 

 

 5.3  介绍Gateway断言

SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配体如下:

    基于Datetime类型的断言工厂

此类型的断言根据时间做判断,主要有三个:

AfterRoutePredicateFactory: 接收一个日期参数,判断请求日期是否晚于指定日期

BeforeRoutePredicateFactory: 接收一个日期参数,判断请求日期是否早于指定日期

BetweenRoutePredicateFactory: 接收两个日期参数,判断请求日期是否在指定时间段内

 

5.4  过滤器

 

5.4 全局过滤器

 

作用: 认证校验 黑白名单 敏感词

(1) 如何定义全局过滤器。

 package com.dyt.filter;
     
    import com.alibaba.fastjson.JSON;
    import com.dyt.entity.Anon;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.core.io.buffer.DataBuffer;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.server.reactive.ServerHttpRequest;
    import org.springframework.http.server.reactive.ServerHttpResponse;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
     
    import java.nio.charset.StandardCharsets;
    import java.util.HashMap;
    import java.util.Map;
     
    /**
     * @author dyt
     */
    @Component
    public class LoginFilter implements GlobalFilter, Ordered {
        @Autowired
        private Anon anon;
     
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            ServerHttpRequest request = exchange.getRequest();
            ServerHttpResponse response = exchange.getResponse();
            String path = request.getPath().toString();
            System.out.println(request);
            System.out.println(path);
            System.out.println(anon.getUrl());
            if(anon.getUrl().contains(path)){
                return chain.filter(exchange);
            }
            String token = request.getHeaders().getFirst("token");
            if (StringUtils.hasText(token)&&"admin".equals(token)){
                return chain.filter(exchange);
            }
            //3.返回一个json数据。
            //3.1设置状态码
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
     
            //3.2封装返回数据
            Map<String, Object> map = new HashMap<>();
            map.put("msg", "未登录");
            map.put("code", 4000);
     
            //3.3作JSON转换
            byte[] bytes = JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8);
     
            //3.4调用bufferFactory方法,生成DataBuffer对象
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
     
            //4.调用Mono中的just方法,返回要写给前端的JSON数据
            return response.writeWith(Mono.just(buffer));
        }
     
        //优先级 返回的值越小优先级越高
        @Override
        public int getorder() {
            return 0;
        }
    }

   

 package com.dyt.entity;
     
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
     
    import java.util.List;
     
    /**
     * @author dyt
     */
    @Component
    @ConfigurationProperties(prefix = "anon")
    public class Anon {
    private List<String> url;
     
        public List<String> getUrl() {
            return url;
        }
     
        public void setUrl(List<String> url) {
            this.url = url;
        }
    }


application.properties

    anon.url[0]=/sso/login
    anon.url[1]=/product/getMsg

 

application.yml

server:
  port: 7000
spring:
  application:
    name: springcloud-gateway
#  cloud:
#    gateway:
#      discovery:
#        locator:
#          enabled: true
#    nacos:
#      server-addr: localhost:81


  cloud:
    gateway:
      routes:
        - id: springcloud-order
          uri: lb://nacos-order
          predicates:
            - Path=/order/**
          filters:
            - SetStatus=300

        - id: springcloud-product
          uri: lb://nacos-product
          predicates:
            - Path=/product/**
#anon:
#  url:
#    - /sso/login
#    - /product/getMsg

    nacos:
      discovery:
        server-addr: localhost:81
        register-enabled: false

定义一个

    @GetMapping("/getMsg")
    public String getMsg(){
        return "getMsg*****";
    }

6 nacos配置管理

(1) 创建列表中添加配置文件

 nacos.order

    server.port=8091

    #日志

    mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

    spring.cloud.nacos.discovery.server-addr=localhost:81

    #spring.cloud.nacos.discovery.register-enabled=false

    spring.application.name=nacos-order

    #eureka.client.register-with-eureka=false

    #eureka.client.service-url.defaultZone=http://localhost:7001/eureka

    nacos-product.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.Randomrule

nacos.product

    #为了后期扩展方便商品微服务的端口设置为8080~8089之间

    server.port=8081

    #日志

    mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

    spring.application.name=nacos-product

    #eureka.client.service-url.defaultZone=http://localhost:7001/eureka

datasource.propertiess数据源

    # 数据源

    spring.datasource.druid.driver-class-name=com.MysqL.cj.jdbc.Driver

    spring.datasource.druid.url=jdbc:MysqL://localhost:3306/springcloud?serverTimezone=Asia/Shanghai

    spring.datasource.druid.username=root

    spring.datasource.druid.password=pAssW0rd

nacos.properties

    spring.cloud.nacos.discovery.server-addr=localhost:81

(2)加入依赖

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

(3) 建一个bootstrap.propreties配置文件

     
    spring.application.name=nacos-order
    spring.cloud.nacos.config.file-extension=properties
    spring.cloud.nacos.config.server-addr=localhost:81
     
     
     
    #配置数据源
    spring.cloud.nacos.config.extension-configs[0].data-id=datasource.properties
    spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
    spring.cloud.nacos.config.extension-configs[0].refresh=true
     
     
    spring.cloud.nacos.config.extension-configs[1].data-id=nacos.properties
    spring.cloud.nacos.config.extension-configs[1].group=DEFAUL_GROUP
    spring.cloud.nacos.config.extension-configs[1].refresh=true

(4) 测试

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...