Spring Cloud Gateway 代理 Solon项目

1 相关背景介绍

1.1 Spring Cloud Gateway介绍

Spring Cloud Gateway 是一个基于 Spring Framework 和 Spring Boot 的 API 网关服务,它利用了 Spring WebFlux 来提供响应式非阻塞式Web请求处理能力。它的核心功能是路由,即根据请求的特定规则将请求转发到后端服务,同时提供了一系列跨领域关注点的处理,如安全认证、监控、限流等。

Spring Cloud Gateway 还提供了多种内置的 GatewayFilter 工厂,如 AddRequestHeaderAddRequestParameterCircuitBreakerRequestRateLimiter 等,用于修改请求和响应、实现断路器功能、限流等。此外,还可以自定义 GatewayFilter 来满足特定的需求 5。

1.2 Solon介绍

Java “纯血国产”应用开发框架。从零开始构建,有自主的标准规范与开放生态。

有以下特点。

  1. 轻量性:Solon 的内核非常小,仅有 0.1MB,最小接口开发单位为 0.2MB 10。
  2. 高性能:在 HTTP helloworld 测试中,Solon 能够达到 12 万的 QPS,表现出色 10。
  3. 多种开发模式:支持 RPC、REST API、MVC、Job、Micro service、WebSocket 和 Socket 等多种开发模式 10。
  4. 代码操控自由度:Solon 强调代码的自由操控,以满足特定的业务需求 10。
  5. 生态插件:拥有 150 多个生态插件,可以满足各种场景开发 12。
  6. 国产框架适配:Solon 支持国产框架适配,为应用软件国产化提供支持 12。
  7. 启动速度:相较于 Spring Boot 和 Spring Cloud,Solon 的启动速度快 5 到 10 倍 13。
  8. QPS 和内存占用:QPS 高 2 到 3 倍,运行时内存节省 1/3 到 1/2 13。
  9. 支持 JDK 版本:Solon 支持 JDK 8 至 JDK 222,以及 GraalVM native image 13。
  10. 编程语言支持:Solon 不仅限于 Java,还支持 Kotlin 等多种编程语言 14。

 2 项目代码

2.1 gateway项目代码

首先引入依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

编写配置文件

spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: "solon project" # id 不要重复即可
          uri: http://localhost:8123  # 代理地址
          predicates:
            - Path=/solon/**   # 断言 满足则使用当前路由规则
          filters:
            - RewritePath=/solon/?(?<segment>.*), /$\{segment} # 路径重写过滤   http://localhost/solon/ -> http://localhost:8123/
        - id: "qq" # id
          uri: https://www.qq.com # 代理地址
          predicates:
            - Query=url,qq # 请求参数?url=qq时匹配  请求参数过滤器
server:
  port: 80

正常启动项目即可

 2.2 Solon 项目代码

引入依赖

 <parent>
        <groupId>org.noear</groupId>
        <artifactId>solon-parent</artifactId>
        <version>2.8.5</version>
        <relativePath/>
    </parent>


    <packaging>jar</packaging>

    <description>Demo project for Solon</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>solon-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>solon.logging.logback</artifactId>
        </dependency>
        <!-- 开启 http_2 使用-->
        <!--        <dependency>-->
        <!--            <groupId>org.noear</groupId>-->
        <!--            <artifactId>solon.boot.undertow</artifactId>-->
        <!--        </dependency>-->
        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>solon-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>

        <plugins>
            <plugin>
                <groupId>org.noear</groupId>
                <artifactId>solon-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>tencent</id>
            <url>https://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

编写主启动

import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
//import org.noear.solon.boot.http.HttpServerConfigure;

@SolonMain
public class App {
    public static void main(String[] args) {
//        Solon.start(App.class, args,app->{
//            app.onEvent(HttpServerConfigure.class, e -> {
//                e.enableHttp2(true); //开启 http_2
//            });
//        });
        Solon.start(App.class,args);
    }
}

编写控制层

import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Param;

@Controller
public class HelloSolonController {
    @Mapping
    public String solon() {
        return "Hello Solon!";
    }

    @Get
    @Mapping("/hello")
    public String hello(@Param(defaultValue = "world") String name) {
        return String.format("Hello %s!", name);
    }

}

启动Solon 项目 可以感觉到启动速度很快

访问 地址 http://localhost:8123

 2.3 gateway代理

访问 http://localhost/solon

这里是我们写的路由匹配规则生效了,代理到solon的服务了

也可以验证我们写的另一个路由匹配规则

http://localhost?url=qq

 说明gateway是按我们的规则去实现的

3 排错过程

3.1 前置条件

在通过spring gateway 代理的时候错误把依赖引入错误

 路由配置基本一样

spring:
  application:
    name: gateway
  cloud:
    gateway:
      mvc:
        routes:
          - id: "solon project" # id 不要重复即可
            uri: http://localhost:8123  # 代理地址
            predicates:
              - Path=/solon/**   # 断言 满足则使用当前路由规则
            filters:
              - RewritePath=/solon/?(?<segment>.*), /$\{segment} # 路径重写过滤   http://localhost/solon/ -> http://localhost:8123/
          - id: "qq" # id
            uri: https://www.qq.com # 代理地址
            predicates:
              - Query=url,qq # 请求参数?url=qq时匹配  请求参数过滤器

启动项目

这时可以正常代理qq网页

但是代理solon项目时发生了错误

 3.2 debug调试

通过idea的异常断点创建对应的异常断点监视快速定位到错误代码行

 再次请求找到出错行号​进入 request.newAbstractRequest(); 方法中找到出错的方法

这里发现他的type被解析成 HTTP_2 了所以返回null

这里引入支持http2依赖

        <!-- 开启 http_2 使用-->
                <dependency>
                    <groupId>org.noear</groupId>
                    <artifactId>solon.boot.undertow</artifactId>
                </dependency>

启动类添加配置

import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
import org.noear.solon.boot.http.HttpServerConfigure;

@SolonMain
public class App {
    public static void main(String[] args) {
        Solon.start(App.class, args,app->{
            app.onEvent(HttpServerConfigure.class, e -> {
                e.enableHttp2(true); //开启 http_2
            });
        });
//        Solon.start(App.class,args);
    }
}

这样再次请求就可以了,不过后来我发现不配置也可以!!!知道引入依赖就好了,所以可能解析的时候出错了,再次查看源码和断点

这里就是解析type的方法看着好像没有什么问题不过不知道为什么和protocol不一样

不过我用访问了spring boot项目是可以正常访问的 

gateway代码icon-default.png?t=N7T8http:// https://gitee.com/zhong-liuyang/spring-gateway-proxy-solon-demo.git https://gitee.com/zhong-liuyang/spring-gateway-proxy-solon-demo.git

solon代码icon-default.png?t=N7T8https://gitee.com/zhong-liuyang/solon-quickstart.git

 总结spring cloud gateway代理solon还是可行的,就是spring cloud gateway mvc代理时出现了错误。不过网关通常还是使用spring cloud gateway 毕竟底层是netty+webflux响应式编程。

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZLY_2004

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值