• gateway网关


    这里先简单介绍下getway网关的大体实现。细节不去详述。这一篇也是最后一篇关于微服务的基础介绍。后面的文章中会介绍具体微服务和中间件的设计、编码和实现

    1. 项目中加入热部署

    由于我们在开发阶段频繁的修改代码,所以在项目中加入热部署以免频繁的启动

    我们在启动的项目中加入maven依赖如下:

                org.springframework.boot

                spring-boot-devtools

                true

                true

         

    并且在nacos的配置中加入spring.devtools.restart.enabled=true。启动项目并且在启动成功之后修改代码发现打出了再次启动的日志。说明加入热部署成功

    1. 加入log日志

    我们使用Lombok的@Slf4j注解放入我们的控制器类中并且我们在select方法中加入log.info的日志。请求该接口发现日志正常打印。关于设置日志的位置请查阅相关资料。如下图:

     

    1. getway基础环境

    新建一个maven的基于pom的空工程命名为cloud-getway

    在主工程添加统一的版本管理如下:

            1.8

            Hoxton.SR8

        

     

        

    org.springframework.cloud

    spring-cloud-dependencies

    ${spring-cloud.version}

    pom

    import

    1. 子模块cloud-getway-provider的依赖

                org.springframework.cloud

                spring-cloud-starter-gateway

            

            

                org.springframework.cloud

                spring-cloud-starter-netflix-hystrix

            

            

                org.springframework.boot

                spring-boot-starter-webflux

            

            

                org.springframework.boot

                spring-boot-starter-data-redis-reactive

            

    1. 添加路由功能

    为了简单起见我们之间在项目的资源文件下新建application.yml文件并添加内容如下:

    server:

      port: 8082

    spring:

      application:

        name: gateway

      cloud:

        gateway:

          routes:

            - id: path_route

              uri: http://localhost:9090

              order: 0

              predicates:

                - Path=/foo/**

              filters:

                - StripPrefix=1

    Uri 是我们需要路由的地址,也是我们之前搭建的demo的请求地址。

    编写WrapperResponseFilter 类实现路由功能

    @Component

    public class WrapperResponseFilter implements GlobalFilter, Ordered {

        @Override

        public int getOrder() {

            // -1 is response write filter, must be called before that

            return -2;

        }

        @Override

        public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

            ServerHttpResponse originalResponse = exchange.getResponse();

            DataBufferFactory bufferFactory = originalResponse.bufferFactory();

            ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {

                @Override

                public Mono writeWith(Publisher body) {

                    if (body instanceof Flux) {

                        Flux fluxBody = (Flux) body;

                        return super.writeWith(fluxBody.map(dataBuffer -> {

                            // probably should reuse buffers

                            byte[] content = new byte[dataBuffer.readableByteCount()];

                            dataBuffer.read(content);

                            // 释放掉内存

                            DataBufferUtils.release(dataBuffer);

                            String rs = new String(content, Charset.forName("UTF-8"));

                            byte[] newRs = "sssss".getBytes(Charset.forName("UTF-8"));

                            originalResponse.getHeaders().setContentLength(newRs.length);//如果不重新设置长度则收不到消息。

                            return bufferFactory.wrap(newRs);

                        }));

                    }

                    // if body is not a flux. never got there.

                    return super.writeWith(body);

                }

            };

            return chain.filter(exchange.mutate().response(decoratedResponse).build());

        }

    }

    我们发起请求http://localhost:8082/foo/demo/hello

    foo是我们路由的根路径  demo/hello是我们业务系统的路径发起请求结果如下图:

     

    说明我们的请求经过了路由的处理类。控制台如下:

     

    说明我们业务系统的代码也得到了执行。

    1. 认证

    编写AuthFilter如下:

    @Component

    public class AuthFilter implements GlobalFilter{

        @Override

        public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

            String token = exchange.getRequest().getHeaders().getFirst("token");

            if ("token".equals(token)) {

                        return chain.filter(exchange);

            }

            ServerHttpResponse response = exchange.getResponse();

    //        Response data = new Response();

    //        data.setCode("401");

    //        data.setMessage("非法请求");

            byte[] datas = "fffffff".getBytes(StandardCharsets.UTF_8);

            DataBuffer buffer = response.bufferFactory().wrap(datas);

            response.setStatusCode(HttpStatus.UNAUTHORIZED);

            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");

            return response.writeWith(Mono.just(buffer));

        }

    }

    使用postmain发起请求并填写token如下图所示

     

    我们给token填写不同的值观察控制台 发现已经对token进行控制了

    1. 熔断

    我们在yml文件中加入配置如下:

                - name: Hystrix

                  args:

                    name: fallbackcmd

                    fallbackUri: forward:/fallback

    编写类FallbackController如下:

    @RestController

    public class FallbackController {

        @GetMapping("/fallback")

        public String fallback() {

            return "test";

        }

    }

    在postman中发起请求http://localhost:8082/fallback如下图所示:

     

    说明我们的熔断经过了熔断的类

    我们在熔断的类中加入接口响应时间超时做熔断的操作。此次不在详述

    1. 限流

    限流可以根据ip 用户Id.可以通过拦截器自行实现限流的逻辑此处不在详述

    1. 动态路由

    我们在路由的时候 添加增删改查的功能即可实现。请自行实现

  • 相关阅读:
    生成函数、多项式题单
    同是负值像素,为何在matplotlib和opencv上显示不一样?
    Xavier(8):Xavier使用速腾聚创激光雷达运行a-loam算法部分报错与解决方案
    『现学现忘』Docker基础 — 33、Docker数据卷容器的说明与共享数据原理
    Leetcode:正则表达式匹配
    三次握手和四次挥手小结
    Flutter+SpringBoot实现ChatGPT流实输出
    java计算机毕业设计H5醉美南湾湖网站设计MyBatis+系统+LW文档+源码+调试部署
    大数据Flink(一百零一):SQL 表值函数(Table Function)
    智能运维监控告警6大优势
  • 原文地址:https://blog.csdn.net/yusongcao7/article/details/126358209