轻量级的Spring Cloud Gateway实践,实现api和websocket转发

当国内大部分都是粘贴复制一些重型框架时,有没有人会想到,我们自己做一个小项目,几个小的Spring boot的项目时,我们是否还需要按部就班的用我们公司中用到的Nacos,这种冗余且调配复杂的组件呢?

不是本人说什么得罪同行的话。

很多程序员在开发和编码过程中,很少自己去真正的研究一个框架和组件,他们大部分的工作只是在自己接手的项目上缝缝补补罢了。

假如某一天,老板或者有个客户说,【我想要做一个项目,加钱好说,那么你是否能真正的独立完成一个项目框架吗?】

那么我们从API路由开始,尝试做一个轻量级的实践。

  1. Spring Cloud Gateway

今天我们来实现Spring Cloud Gateway,我们首先了解一下Spring Cloud Gateway是什么东东:

Spring Cloud Gateway 是 Spring Cloud 生态系统的一部分,提供了简单、有效的方式来路由到API,并为它们提供跨域处理、安全、监控/指标和弹性。

  • Route(路由): 网关的基本构件。它由一个ID、一个目的地URI、一个谓词(Predicate)集合和一个过滤器(Filter)集合定义。如果集合谓词为真,则路由被匹配。

  • Predicate(谓词): 这是一个 Java 8 Function Predicate。输入类型是 Spring Framework ServerWebExchange。这让你可以在HTTP请求中的任何内容上进行匹配,比如header或查询参数。

  • Filter(过滤器): 这些是 GatewayFilter 的实例,已经用特定工厂构建。在这里,你可以在发送下游请求之前或之后修改请求和响应。

添加图片注释,不超过 140 字(可选)

客户端向 Spring Cloud Gateway 发出请求。如果Gateway处理程序映射确定一个请求与路由相匹配,它将被发送到Gateway Web处理程序。这个处理程序通过一个特定于该请求的过滤器链来运行该请求。过滤器被虚线分割的原因是,过滤器可以在代理请求发送之前和之后运行逻辑。所有的 "pre" (前)过滤器逻辑都被执行。然后发出代理请求。在代理请求发出后,"post" (后)过滤器逻辑被运行。

2.实现

我们来新建简单的Maven一个工程,在pom.xml代码中引入Gateway。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

我们再简单的写一个main来启动工程看一看。

@Slf4j
@EnableDiscoveryClient
@SpringBootApplication
@PropertySource("classpath:config/application.properties")
public class GateWayServiceApplication {

    /**
     * <b>功能描述:</b>启动<br>
     * <b>修订记录:</b><br>
     */
    public static void main(String[] args) {
        SpringApplication.run(GateWayServiceApplication.class, args);
        log.info("网管服务启动成功");
    }
}

点击启动,结果是启动不起来的,为什么呢?

我们父级pom,都会引入spring-boot-starter-web组件,可是web组件内,基本都是使用tomcat来作为服务发布内置组件,这里我还做了更改,我希望我的整个项目使用undertow。

那么怎么来更改呢?

父级pom,排除Tomcat使用undertow,您也可以不使用unsertow,直接使用tomcat的话,不用exclusions也无需引入undertow。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

那么在Gateway内如何更改呢?

Gateway使用 Spring WebFlux 作为服务,那么我们需要去除undertow或者Tomcat,使用WebFlux.

更改示例如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

如果在父级项目还引入了Eureka,那么我们还需要排除Eureka内的web服务。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </exclusion>
    </exclusions>
</dependency>

重新启动项目,这下就可以完美启动了。

  1. 跨域请求

接下来,我们所有的配置所属都在配置中进行,在我们日常开发中,经常会被跨域请求绞挠的难受,网络充斥着大量的无用cors跨域配置。

那么我们看下如何在Gateway中如何正确的配置跨域。

spring.cloud.gateway.globalcors.cors-configurations.[/**].allow-credentials=true
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-origins[0]=http://localhost:8080
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-origins[1]=http://localhost:8081
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-origins[2]=http://localhost:63343
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-headers=*
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-methods[0]=OPTIONS
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-methods[1]=GET
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-methods[2]=POST
spring.cloud.gateway.globalcors.cors-configurations.[/**].max-age=3600

以上就是跨域配置,只需要在allowed-origins数组内添加需要跨域的链接,即可解决跨域问题。

  1. API路由配置转发

    #设置路由id
    spring.cloud.gateway.routes[0].id=manager-server
    #设置路由的uri
    spring.cloud.gateway.routes[0].uri=lb://manager-server
    #设置路由断言,代理servicerId为manager-server的/gb/路径
    spring.cloud.gateway.routes[0].predicates[0]=Path=/api/manager/**

使用routes数组来增加路由API的增减。

  1. WebSocket配置转发

    #设置路由id
    spring.cloud.gateway.routes[2].id=manager-server-socket
    #设置路由的uri
    spring.cloud.gateway.routes[2].uri=lb:ws://manager-server
    #设置路由断言,代理servicerId为manager-server的/exchange/路径
    spring.cloud.gateway.routes[2].predicates[0]=Path=/ws/**

这里我们要记住,socket路由转发是配合SockJS的,假如使用普通的websocket似乎有一些困难哦。

SockJS实现可以参考网络内容SockJS+StompJS实现websocket,它也是很好的实现哦。

如上,我们基本实现了API及websocket、跨域等基础问题的解决。

相关推荐
Chrikk1 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*1 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue1 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man1 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟1 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity2 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天2 小时前
java的threadlocal为何内存泄漏
java
caridle2 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^3 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋33 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx