前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微服务路由网关之Spring Cloud Gateway入门使用教程

微服务路由网关之Spring Cloud Gateway入门使用教程

作者头像
lyb-geek
发布2022-03-10 13:46:26
8750
发布2022-03-10 13:46:26
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路

Spring Cloud Gateway是类似Nginx的网关路由代理,有替代原来Spring cloud zuul之意:

Spring 5 推出了自己的Spring Cloud Gateway,支持Java 8、Reactor API,可在Spring Boot 2 使用,看到了响应式组件Reactor,可以理解这个网关方案目标之一是能够采用Reactive 来实现高效率的网关。

想要建立一个Spring Cloud Gateway 的话,在Spring Tool Suite 上可以选择「Gateway」这个Starter,为了能注册到服务发现服务器,也为了能开放gateway/routes 端点,以便观察路由信息,就顺便加入Eureka与Actuator 的Starter,比如在build.gradle 中可以包含:

代码语言:javascript
复制
implementation('org.springframework.boot:spring-boot-starter-actuator')  
implementation('org.springframework.cloud:spring-cloud-starter-gateway')
implementation('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')

Spring Cloud Gateway 可以在注册服务器上注册的服务ID,自动建立路由信息,为此,可以如下设定bootstrap.properties:

代码语言:javascript
复制
server.port=5555

spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lowerCaseServiceId=true

eureka.instance.preferIpAddress=true
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

management.endpoints.web.exposure.include: gateway

spring.cloud.gateway.discovery.locator.enabled启用了自动根据服务ID建立路由,路由的路径对应会使用大写ID,若想要使用小写ID,可将

spring.cloud.gateway.discovery.locator.lowerCaseServiceId设为true;在设置中也开放了gateway端点。必要时,可以使用RouteLocator实现自定义路由的方式。 接下来启动相关服务,启动Spring Cloud Gateway,默认会跑在Netty上,如果测试请求http://localhost:5555/actuator/gateway/routes的话,就可以看到以下:

代码语言:javascript
复制
[
    {
        "route_id": "CompositeDiscoveryClient_ACCTSVI",
        "route_definition": {
            "id": "CompositeDiscoveryClient_ACCTSVI",
            "predicates": [
                {
                    "name": "Path",
                    "args": {
                        "pattern": "/acctsvi/**"
                    }
                }
            ],
            "filters": [
                {
                    "name": "RewritePath",
                    "args": {
                        "regexp": "/acctsvi/(?<remaining>.*)",
                        "replacement": "/${remaining}"
                    }
                }
            ],
            "uri": "lb://ACCTSVI",
            "order": 0
        },
        "order": 0
    },
    ...
]

每个路由设定会有个route_id作为识别,在路由定义的predicates中,可以看到设置了Path,这是Spring Cloud Gateway内建的断言器工厂Bean名称,pattern这个设置表示对于http://localhost:5555/acctsvi/xxxx的请求会转给uri设定的值:lb://ACCTSVI,也就是说路由转给了服务ID为ACCTSVI的服务。 filters中设置了RewritePath,这是个过滤器工厂Bean名称,依照regexp的规则,会捕捉请求中的/acctsvi/之后的部份,套用至服务的URI上,也就是http://localhost:5555/acctsvi/xxxx的请求,将会路由转发至http://acctsvi-uri/xxxx。 predicates与filters是Spring Cloud Gateway的重要特性,predicates断言哪些路径符合路由定义,filters设置具体哪些路径适用什么样的具体过滤器,除了设置之外,必要时,都可以代码自己定义。 Spring Cloud Gateway也内建了一些断言器工厂与过滤器工厂,这些工厂类别,是可以通过属性档来定义的,必要时,也可以自定义工厂类别。 就以上的设置来说,请求http://localhost:5555/acctsvi/accountByName?username=caterpillar就可以得到以下回应:

代码语言:javascript
复制
{

    
"name"
:
 
"caterpillar"
,

    
"email"
:
 
"caterpillar@openhome.cc"
,

    
"password"
:
 
"$2a$10$CEkPOmd.Uid2FpIOHA6Cme1G.mvhWfelv2hPu7cxZ/vq2drnXaVo."
,

    
"_links"
:
 
{

        
"self"
:
 
{

            
"href"
:
 
"http://Justin-2017:8084/accountByNameEmail?username=caterpillar"

        
}

    
}

}

如果想要自定义路由,可以写个application.yml(若不想自动建立路由,可以将spring.cloud.gateway.discovery.locator.enabled与spring.cloud.gateway.discovery.locator.lowerCaseServiceId注解掉):

代码语言:javascript
复制
spring
:

    application
:

            name
:
 gateway

    cloud
:

        gateway
:

            routes
:
 

                
-
 predicates
:

                    
-
 
Path
=
/acct/
**

                  filters
:

                      
-
 
StripPrefix
=
1

                  uri
:
 lb
:
//acctsvi

                
-
 predicates
:

                    
-
 
Path
=
/msg/
**

                  filters
:

                      
-
 
StripPrefix
=
1

                  uri
:
 lb
:
//msgsvi     

                
-
 predicates
:

                    
-
 
Path
=
/email/
**

                  filters
:

                      
-
 
StripPrefix
=
1

                  uri
:
 lb
:
//email     

上述配置filters中的StripPrefix也是内建的过滤器工厂Bean名称,设定值为1表示将路由中的第一个层去除,其余保留用来转发请求,请求http://localhost:5555/actuator/gateway/routes的话,就可以看到以下:

代码语言:javascript
复制
[
    {
        "route_id": "545d278b-192b-4370-8156-161815957f91",
        "route_definition": {
            "id": "545d278b-192b-4370-8156-161815957f91",
            "predicates": [
                {
                    "name": "Path",
                    "args": {
                        "_genkey_0": "/acct/**"
                    }
                }
            ],
            "filters": [
                {
                    "name": "StripPrefix",
                    "args": {
                        "_genkey_0": "1"
                    }
                }
            ],
            "uri": "lb://acctsvi",
            "order": 0
        },
        "order": 0
    },
    ...
]

也就是对http://localhost:5555/acct/accountByName?username=caterpillar的请求,会转给http://acctsvi-url/accountByName?username=caterpillar。 如果想要设定api前置路径,就是修改一下StripPrefix=1为StripPrefix=2:

代码语言:javascript
复制
spring
:

    application
:

            name
:
 gateway

    cloud
:

        gateway
:

            
default
-
filters
:

                
-
 
StripPrefix
=
2

            routes
:
 

                
-
 predicates
:

                    
-
 
Path
=
/api/
acct
/**

                  uri: lb://acctsvi

                - predicates:

                    - Path=/api/msg/**

                  uri: lb://msgsvi     

                - predicates:

                    - Path=/api/email/**

                  uri: lb://email       

对于每个路由都要套用的过滤器,可以使用default-filters来设置,就以上设定来说,可以请求http://localhost:5555/api/acct/accountByName?username=caterpillar来取得使用者信息。 一开始自动根据服务ID建立路由时,可以看到RewritePath,它也是内建的过滤器工厂,可以运用规则表示式来进行路径重写,因此,也可以这么设置api前置:

代码语言:javascript
复制
spring:
    application:
            name: gateway
    cloud:
        gateway:
            default-filters:
                - RewritePath=/api/.*?/(?<remaining>.*), /$\{remaining}
            routes: 
                - predicates:
                    - Path=/api/acct/**
                  uri: lb://acctsvi
                - predicates:
                    - Path=/api/msg/**
                  uri: lb://msgsvi     
                - predicates:
                    - Path=/api/email/**
                  uri: lb://email

就目前的设定来说,在客户端的部份,〈使用Zuul【链接:https://openhome.cc/Gossip/Spring/Zuul.html】〉中的gossip就可以了,毕竟交互的接口没有改变,但是因为使用spring.application.gateway作为应用代理了,还是要记得改一下@FeignClient中的服务ID为gateway。

可以在Gateway【链接如下】

https://github.com/JustinSDK/Spring5Tutorial/tree/master/labs/solutions/Cloud/Routing/CloudGateway/Gateway

中找到以上的源码

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档