网关我选 Spring Cloud Gateway
网关可提供请求路由与组合、协议转换、安全认证、服务鉴权、流量控制与日志监控等服务。可选的网关有不少,比如 Nginx、高性能网关 OpenResty、Linkerd 以及 Spring Cloud Gateway。
如果是真的追求高性能,那肯定是选择 Nginx 或者 OpenResty 无疑了, 但是对性能要求不是很高的话,并且又在用 Spring Cloud 系列,那当然就要选择 Spring Cloud Gateway 了。
网关的基础就是路由功能,通俗解释就是地址转发,将一个请求地址转发到实际的服务地址。比如请求的是 http://xxx.com/api 的路由地址,实际上会被转发到 http://xxx.com:8888 上来,这就是个最简单的路由方式。
我们可以理解为 Spring Cloud Gateway 就是针对进来的请求做各种判断和处理,比如说判断请求的合法性、权限验证,请求地址改写,请求参数、头信息、cookie 信息的分析和改写,请求速率控制,日志留存等。而这些都可以方便的通过 Predicate 和 GatewayFilter 来组合实现。
创建 Spring Cloud Gateway 项目
Spring Cloud 版本是 Greenwich.SR2,Spring Boot 版本 2.1.6.RELEASE,JDK 1.8。
接下来正式创建一个 Gateway 项目。
首先做两个微服务,当做路由转发的目标服务
两个微服务是以 consul 作为服务注册中心的,可以看这篇文章服务注册发现、配置中心集一体的 Spring Cloud Consul
1、创建 consul-order 服务,具体可以去 github 上看代码(https://github.com/huzhicheng/spring-cloud-study/tree/master/consul/consul-order),很简单的一个服务。创建的 RESTful Controller 如下:
@RestController
@RequestMapping(value = "order")
public class OrderController {
@Value("${spring.application.name}")
private String applicationName;
@GetMapping(value = "get")
public CustomerOrder getOrder(){
CustomerOrder customerOrder = new CustomerOrder();
customerOrder.setOrderId("9999");
customerOrder.setProductName("MacBook Pro");
customerOrder.setClient(applicationName);
return customerOrder;
}
}
总之,最后直接访问这个接口的地址为 http://localhost:5006/order/get
2、创建 consul-user 服务,具体代码可以到 github 上查看(https://github.com/huzhicheng/spring-cloud-study/tree/master/consul/consul-user)。创建的 RESTful Controller 内容如下:
@RestController
@RequestMapping(value = "user")
public class UserController {
@GetMapping(value = "get")
public User getUserInfo(){
User user = new User();
user.setName("古时的风筝");
user.setAge(8);
user.setLocation("北京");
return user;
}
}
和上面的微服务有点区别的就是设置了 context-path
server:
port: 5005
servlet:
context-path: /user-service
之所以这样不同的设置,是因为下面要验证一个 filter。总之,最后上述接口的访问地址为:http://localhost:5005/user-service/user/get
创建一个项目,并引入 maven 包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置简单的路由转发
路由配置有两种方式。一种是配置文件,另外一种是代码方式配置,WebFlux 的反应式编程方式。所以我们 pom 文件中要引入 WebFlux 的包。这是 Spring 5 的新特性。
1、先看第一种配置文件方式配置:
server:
port: 10000
spring:
application:
name: gateway
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: false # 是否将服务id转换为小写
routes:
- id: userServiceRouter
uri: lb://consul-user
predicates:
- Path=/user-service/**
- id: orderServiceRouter
uri: lb://consul-order
predicates:
- Path=/order-service/**
filters:
- StripPrefix=1
consul:
host: localhost #注册gateway网关到consul
port: 8500
discovery:
service-name: service-gateway
其中包括 Spring Boot 项目的基本配置,name、port ,还有关于 consul 的配置,要将网关服务注册到注册中心。
上面配置中创建了两条路由规则,路由规则名称通过 id 设置,分别是 userServiceRouter 和 orderServiceRouter,通过 predicates.Path 设置待转发的 url,通过 uri 设置转发后的目标地址。上面配置将以 /user-service/
开头的地址转发到 lb://consul-user
,固定格式 lb + 服务id,在有注册中心的情况下要这样写,如过没有注册中心,可以直接写目标 url。
下面的路由规则中多了一个 StripPrefix 的 filter ,这个是 Gateway 的内置 filter,作用就是去掉 Path 中的指定部分,StripPrefix=1,就是以 / 分隔,去掉第一部分,比如 /a/b/c 这个地址,在 StripPrefix=1 的作用下,就会转发到 /b/c/,当 StripPrefix=2 的时候,就会转发到 /c/。
配置好上述接口,然后启动网关服务。访问规则就会有如下对应关系:
http://localhost:10000/user-service/user/get->http://localhost:5005/user-service/user/get
http://localhost:10000/order-service/order/get->http://localhost:5006/order/get
当然这只是针对每一个目标服务只有一个实例的情况,如果有多个实例,就会按照负载策略落到对应的实例中。
2、代码方式的路由配置
@Bean
public RouteLocator kiteRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("userRouter", r -> r.path("/user-service/**")
.filters(f ->
f.addResponseHeader("X-CustomerHeader", "kite"))
.uri("lb://consul-user")
)
.route("orderRouter", r -> r.path("/order-service/**")
.filters(f -> f.stripPrefix(1)).uri("lb://consul-order")
)
.build();
}
上面的这段代码和前面的配置文件的内容是同样的作用。只要实现一个返回类型为 RouteLocator
,参数为 RouteLocatorBuilder
类型的 Bean。
你看后面那一连串的 r.path().filters().uri() 了吗,用它们就可以简单的配置出路由规则,而且可读性也比较强。另外,Gateway 还套用了 Predicate 的规则来构建更加灵活、复杂的路由规则。Predicate 是 Java 8 增加的逻辑计算库,有 negate()、and()、or()、isEqual()几个方法。具体的代码在 PredicateSpec 和 UriSpec 这两个类里,一目了然。
PredicateSpec 里有这么多方法,都可以结合 and、or 组合起来使用。
接下来就说到 filter,Gateway 内置了很多的 filter,可以在 GatewayFilterSpec 类下找到方法封装,每一个 filter 都由一个 factory 的 apply 实现,都在 org.springframework.cloud.gateway.filter.factory
包下,有必要的话可以直接看源码。 比如上面用到的 StripPrefix。还有 addResponseHeader,它的作用是在 Response 对象的 header 中添加请求头。
启动网关服务
启动网关,并访问两个接口测试,接口分别为 http://localhost:10000/user-service/user/get和http://localhost:10000/order-service/order/get,正常返回数据,则说明网关服务配置正常。
巧用 StripPrefix filter
微服务多了之后,路由的转发规则也就多了,比方说订单相关请求要转发到订单微服务集群,用户相关请求要转发到用户微服务集群,最终开放给终端的接口也要能表明是哪个微服务的,除了接口文档里说明之外,接口本身最好也能明确标识。
一种方式是在微服务的配置文件中配置上server.servlet.context-path
。
还有一种方式就是在路由规则的 path 中配置,然后加上 StripPrefix 配置,选择性的去掉请求 url 中的某些部分。比如我们请求 Gateway的地址为 order-service/order/get,则经过 StripPrefix(1) 之后,会把请求地址变为 order/get,然后根据路由规则定向到具体的微服务地址或者特定的 url。
本篇就介绍 Spring Cloud Gateway 的基本用法,后续还会有关于集成安全认证、鉴权、限流、日志等相关内容,敬请关注。
不要吝惜你的「推荐」呦
欢迎关注,不定期更新本系列和其他文章
古时的风筝
,进入公众号可以加入交流群
网关我选 Spring Cloud Gateway的更多相关文章
- Spring Cloud Gateway服务网关
原文:https://www.cnblogs.com/ityouknow/p/10141740.html Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gatewa ...
- 网关服务Spring Cloud Gateway(一)
Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gateway ,相比之前我们使用的 Zuul(1.x) 它有哪些优势呢?Zuul(1.x) 基于 Servlet,使 ...
- 微服务网关 Spring Cloud Gateway
1. 为什么是Spring Cloud Gateway 一句话,Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是 ...
- Spring Cloud gateway 网关四 动态路由
微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...
- spring cloud:服务网关 Spring Cloud GateWay 入门
Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gateway ,相比之前我们使用的 Zuul(1.x) 它有哪些优势呢?Zuul(1.x) 基于 Servlet,使 ...
- Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!
大家好,我是不才陈某~ 这是<Spring Cloud 进阶>第八篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得 ...
- Spring Cloud Gateway VS Zuul 比较,怎么选择?
Spring Cloud Gateway 是 Spring Cloud Finchley 版推出来的新组件,用来代替服务网关:Zuul. 那 Spring Cloud Gateway 和 Zuul 都 ...
- SpringCloud无废话入门05:Spring Cloud Gateway路由、filter、熔断
1.什么是路由网关 截至目前为止的例子中,我们创建了一个service,叫做:HelloService,然后我们把它部署到了两台服务器(即提供了两个provider),然后我们又使用ribbon将其做 ...
- Spring Cloud gateway 五 Sentinel整合
微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...
随机推荐
- cogs 2652. 秘术「天文密葬法」(0/1分数规划 长链剖分 二分答案 dp
http://cogs.pro:8080/cogs/problem/problem.php?pid=vSXNiVegV 题意:给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σai ...
- gulp的介绍和手动安装
gulp, 前端自动化工具, 文件操作, 项目上线之前,将碎片文件合并,将ES6转成ES5,文件压缩,快速搭建服务器... gulp基于node环境 gulp就是node的一个非内置的小模块 gulp ...
- XSS漏洞之加载远程js文件
这次在对一个系统渗透测试过程中,发现一个XSS漏洞,可弹窗,并且没有httponly 但是在尝试加载远程js文件的时候发现,script标签被过滤掉了,准确的说应该是服务器后端在识别到输入内容有< ...
- 013 turtle程序语法元素分析
目录 一.概述 二.库引用与import 2.1 库引用 2.2 使用from和import保留字共同完成库引用 2.3 两种库引用方法比较 2.4 使用import和as保留字共同完成库引用 三.t ...
- 每天学会一点点(枚举enum)
枚举的特点: enum和class.interface的地位一样 使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类.枚举类可以实现一个或多个接口. 枚举类的所有 ...
- FreeSql (三十二)Aop
FreeSql AOP 已有的功能介绍,未来为会根据用户需求不断增强. 审计 CRUD 马云说过,996是修福报.对于多数程序员来说,加班是好事...起码不是闲人,不会下岗. 当如果因为某个 sql ...
- 《Java 8 in Action》Chapter 10:用Optional取代null
1965年,英国一位名为Tony Hoare的计算机科学家在设计ALGOL W语言时提出了null引用的想法.ALGOL W是第一批在堆上分配记录的类型语言之一.Hoare选择null引用这种方式,& ...
- Python文件访问编码格式问题UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position xx: 解决方案
1.Python读取文件 # .打开文件 file = open("ReadMe") # .读取文件类容 text = file.read() print(text) # .关闭文 ...
- Kali Linux 安装open-vm-tools
Kali Linux是基于Debian的Linux发行版,集成了精心挑选的渗透测试和安全审计的工具,供渗透测试和安全设计人员使用.(以及一些各种颜色的hacker ^-^) 首先需要安装好虚拟机(V ...
- jmeter运行第三方java项目
自己写了个简化系统操作的小工具,因为不想给别人用的时候占用本地资源于是写的是纯java项目,后面放到jmeter中通过beanshell sampler调用. java源码不贴了,把写好的项目导出成可 ...