前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微服务网关SpringCloud Gateway的基本入门和注意点

微服务网关SpringCloud Gateway的基本入门和注意点

作者头像
lyb-geek
发布2019-05-07 14:53:51
4.8K0
发布2019-05-07 14:53:51
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路

一、gateway和zuul

Spring Cloud Finchley版本的gateway比zuul 1.x系列的性能和功能整体要好,且使用 Gateway 做跨域相比应用本身或是 Nginx 的好处是规则可以配置的更加灵活.

这两者相同的地方就是都是作为网关,处理前段的请求,可以进行路由到对应的服务或者url,也可以针对权限做过滤处理,也可以对其他服务响应的结果做处理

二、使用gateway的路由功能

1、 搭载springcloud gateway

准备一个spring cloud工程,包括eureka-server注册中心,service-client服务提供者,端口8090

service-client提供一个接口:

代码语言:javascript
复制
@RestController@Slf4jpublic class ProducerController {
  @RequestMapping("/hi")  public String hi(@RequestParam String name) {    log.info("[client服务] [hi方法]收到请求");    return "hi " + name + ",i am from service-client";  }}

再建一个spring cloud工程,service-gateway网关,端口8088

pom的依赖:

代码语言:javascript
复制
<parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>2.0.4.RELEASE</version>    <relativePath/> </parent>
 <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>1.8</java.version></properties>
<dependencies>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-gateway</artifactId>    </dependency>
    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>    </dependency></dependencies>

application启动类:

代码语言:javascript
复制
package com.zgd.springcloud.gateway;
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/** * service-gateway 客户端 * @author zgd */@EnableEurekaClient@SpringBootApplicationpublic class App {
    public static void main(String[] args) {        SpringApplication.run(App.class, args);    }
}

这样基本的框架就搭好了,先启动eureka-server注册中心,再启动service-client和service-gateway

直接调用 localhost:8090/hi?name=zgd,可以收到

代码语言:javascript
复制
hi zgd,i am from service-client

2、简单使用gateway

Spring Cloud gateway内置了很多校验条件谓语(predicate)来实现路由功能

有两种方式配置,一种是配置文件application的方式,一种是代码配置

application配置:

a、路由到其他地址

代码语言:javascript
复制
spring:  cloud:    gateway:      #可以根据请求参数,cookie,host,请求时间,请求头等进行校验判断路由, 下面根据先后顺序转发      routes:        - id: host_route          uri: http://httpbin.org:80/get          predicates:            - Path=/zzzgd/** # 请求地址携带zzzgd的,则转发

在spring.cloud.gateway.routes中,我们可以根据不同的谓语配置不同的路由,根据配置的先后顺序来跳转,越在前面优先级越高.

其中id,区分不同的路由规则,不可重复,uri,指需要跳转的地址,Predicates就是上面说的谓语了,可以配置多个,使用正则匹配. 这里我们配置的是如果请求地址携带zzzgd则会跳转到我们配置的uri

配置好gateway,重新启动,然后我们调用localhost:8088(网关的地址和端口)/zzzgd/abc,这个地址是没有任何匹配的接口的,按理来说会返回404,但是配置了网关就返回了这些信息,这个是我们配置的uri所返回的:

代码语言:javascript
复制
{  "args": {    "name": "zgd"  },   "headers": {    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",     "Accept-Encoding": "gzip, deflate, br",     "Accept-Language": "zh-CN,zh;q=0.9",     "Connection": "close",     "Cookie": "SL_G_WPT_TO=zh; SL_GWPT_Show_Hide_tmp=undefined; SL_wptGlobTipTmp=undefined",     "Forwarded": "proto=http;host=\"localhost:8088\";for=\"0:0:0:0:0:0:0:1:55782\"",     "Host": "httpbin.org",     "Upgrade-Insecure-Requests": "1",     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",     "X-Forwarded-Host": "localhost:8088"  },   "origin": "0:0:0:0:0:0:0:1, 119.147.213.42",   "url": "http://localhost:8088/get?name=zgd"}

上面的是根据地址来路由,还有下面多种路由配置:

根据域名来转发路由:

代码语言:javascript
复制
routes:    - id: host_route      uri: http://httpbin.org:80/get      predicates:        - Host=**.csdn.** # 请求域名携带csdn的,则转发    - id: query_route      uri: http://httpbin.org:80/get      predicates:        - Query=username, zzz* # 请求参数含有username,且值满足zzz开头的,则转发(对值的匹配可以省略)    - id: header_route      uri: http://httpbin.org:80/get      predicates:        - Header=request, \d+ # 如果请求头含有request,且为数字,则转发    - id: cookie_route      uri: http://httpbin.org:80/get      predicates:        - Cookie=name, zzzgd # 如果携带cookie,参数名为name,值为zzzgd,则转发    - id: path_route      uri: http://httpbin.org:80/get      predicates:        - Path=/zzzgd/** # 请求地址携带zzzgd的,则转发    # 路由到其他服务,url需要用[lb://]+[serviceId]    - id: service_client      uri: lb://service-client      predicates:        - Path=/to_client/** # 如果请求地址满足/to_client/**,则转发到 service-client 服务      filters:        - StripPrefix=1 # 去除请求地址中的to_client    - id: after_route      uri: http://httpbin.org:80/get      predicates:        - After=2019-01-01T17:42:47.789-07:00[America/Denver] # 如果请求时间大于该时间,则转发

b. 路由到其他服务

我们知道,zuul是可以根据服务在eureka的serviceId,来将请求路由到不同的服务上,这也是网关最大的作用之一,gateway也可以

gateway可以通过开启以下配置来打开根据服务的serviceId来匹配路由,默认是大写:

代码语言:javascript
复制
# 配置gateway路由spring:  cloud:    gateway:      discovery:        locator:          # 是否可以通过其他服务的serviceId来转发到具体的服务实例。默认为false          # 为true,自动创建路由,路由访问方式:http://Gateway_HOST:Gateway_PORT/大写的serviceId/**,其中微服务应用名默认大写访问          enabled: true

开启配置,重启gateway,访问 localhost:8088/SERVICE-CLIENT/hi?name=zgd, 正常返回了service-client的结果.

如果需要小写serviceId,则配置

spring.cloud.gateway.locator.lowerCaseServiceId:true

注意事项

1、不管小写大写,不能使用下划线,否则会报:

代码语言:javascript
复制
org.springframework.cloud.gateway.support.NotFoundException: Unable to find instance for localhost

所以服务的spring.application.name 必须用中划线而不是下划线

2、如果开启了lowerCaseServiceId,则只能用小写,不能识别大写,如果不开启,只能识别大写

除了上面这种自动设置路由服务,也可以手动设置,在routes中配置

代码语言:javascript
复制
# 路由到其他服务,url需要用[lb://]+[serviceId]- id: service_client  uri: lb://service-client  predicates:    - Path=/to_client/** # 如果请求地址满足/to_client/**,则转发到 service-client 服务  filters:    - StripPrefix=1 # 去除请求地址中的to_client

这里的uri不是一个具体的地址了,而是lb://开头,加上serviceId然后比如上面这个配置,我们 再调用 localhost:8088/to_client/hi?name=zgd

可以看到也正常收到了service-client的返回.说明我们调用到了这个服务.

这里需要注意的一点,如果不加上filters.- StripPrefix=1,那么则无法请求到hi这个接口.因为对于service-client,相当于收到的请求路径是localhost:8090/toclient/hi?name=zgd,这个toclient只是为了网关的路由加上去的,不需要业务服务也收到这段地址,所以需要去掉

还有其他的predicate,可以参考官方文档

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.0.RC3/single/spring-cloud-gateway.html#gateway-request-predicates-factories

过滤

filters也是gateway的一个重要功能,过滤.可以参考官方文档

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.0.RC3/single/spring-cloud-gateway.html#gatewayfilterfactories

举个例子,我们将application配置如下:

代码语言:javascript
复制
spring:  cloud:    gateway:        routes:            - id: query_route                uri: http://httpbin.org:80/get                predicates:                - Query=username, zzz* # 请求参数含有username,且值满足zzz开头的,则转发(对值的匹配可以省略)                filters:                - AddRequestHeader=X-Request-Foo, Bar                - AddRequestParameter=age, 18

请求 localhost:8088/?username=zzzzzzz

它返回了它所受到的请求,这里可以看到,已经添加了一个age=18的请求参数,且右边响应头也多了X-Request-Foo=Bar

代码配置

为了方便在java开发,gateway也提供了代码的方式配置,比如我们注释掉上面的application配置,然后建一个配置类

代码语言:javascript
复制
/** * @Author: zgd * @Date: 2019/1/8 19:09 * @Description: */@Configurationpublic class GateWayConfig {
  @Bean  public RouteLocator routeLocator(RouteLocatorBuilder builder) {    return builder.routes()            .route(r -> r.path("/fluent/**").and().query("name")                    .uri("http://httpbin.org:80/get"))            .build();
  }
}

启动,访问

http://localhost:8088/fluent/1/?name=bb 成功

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

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

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

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

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