当前位置:网站首页>微服务-gateway【服务网关入门】
微服务-gateway【服务网关入门】
2022-08-02 18:16:00 【爱摸鱼的小凯】
文章目录
概述
Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和 Project Reactor等技术。
Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能, 例如:熔断、限流、重试等。
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,基于 Spring 5.0+Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
Spring Cloud Gateway的目标提供统一的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
通俗来说,SpringCloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。
作用
- 反向代理
- 鉴权
- 流量控制
- 熔断
- 日志监控
如下所示,这边便是gateway的工作区域
gateway的三大核心概念
路由
路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
断言
参考的是Java8的java.util.function.Predicate
开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
过滤
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
小结
- web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。
- predicate就是我们的匹配条件;
- 而filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了
gateway路由基础使用示例
操作步骤
新建模块cloud-gateway-gateway9527
配置pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mscloud</artifactId>
<groupId>com.zsy.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.zsy.springcloud</groupId>
<artifactId>cloud-gateway-gateway9527</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.zsy.springcloud</groupId>
<artifactId>cloud-api-commins</artifactId>
<version>${project.version}</version>
</dependency>
<!--一般基础配置类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
yml编写gateway配置
如下图所示,我们将服务注册的服务注册中心去,并且配置到达我们所需服务的路由,这样我们就可以通过gateway来完成路由转发功能了
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** # 断言,路径相匹配的进行路由
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表内
service-url:
register-with-eureka: true
fetch-registry: true
eureka注册中心的地址
defaultZone: http://127.0.0.1:7001/eureka
编写启动类
package com.zsy.springclou;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GateWayMain9527.class, args);
}
}
之后启动服务输入地址http://localhost:9527/payment/get/1 即可完成基于gateway访问8001端口的支付服务
注意开启所有payment模块以及eureka服务注册中心,然后再开启gateway
硬编码的方式实现路由
如下图所示,在boot项目中增加这样一个配置类,将gateway地址转发到对应uri上即可。
package com.zsy.springclou.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customRouterLocator(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder router = builder.routes();
router.route("new_router", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
return router.build();
}
}
测试也很简单,输入http://localhost:9527/guonei即可跳转到百度的国内新闻
gateway实现动态路由
配置步骤也很简单,只需要将eureka上做负载的的服务名配置到uri上即可开启所有payment模块以及eureka服务注册中心,然后再开启gateway
这时候通过地址http://localhost:9527/payment/lb
即可访问payment模块,又有是负载所以访问是随机的
gateway断言使用示例
如下所示,笔者想让这个请求在指定时间后且cookie为指定内容生效只需按照如下处理即可
具体也可以参照spring的官网示例
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories使用开启所有payment模块以及eureka服务注册中心,然后再开启gateway
上述配置完成后可用curl命令进行测试
curl http://localhost:9527/payment/lb --cookie "uname=zsy"
gateway过滤使用示例
package com.zsy.springclou.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class MyGateFielter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("执行了全局过滤器");
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if (uname == null) {
log.error("uname为空,请求将会被拦截");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
log.info("uname不为空,放行了,当前uname:" + uname);
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
测试
使用开启所有payment模块以及eureka服务注册中心,然后再开启gateway
测试命令
curl http://localhost:9527/payment/lb?uname=zsy
边栏推荐
- MySQL命令(命令行方式,而非图形界面方式)
- 通信大学生走向岗位,哪些技能最实用?
- pydev debugger: warning: trying to add breakpoint to file that does not exist: /tmp/xxx
- 编译型语言与解释型语言的区别
- What skills are the most practical for college students in communications?
- WIFi 开关控制实现-ESP8266 物联网 android studio arduino QT多线程服务器
- codeforces:E. Add Modulo 10【状态压缩 + 找规律】
- 【软考软件评测师】基于经验的测试技术
- Redis总结_实战篇
- POE交换机全方位解读(下)
猜你喜欢
TSF微服务治理实战系列(一)——治理蓝图
Taking advantage of cloud-network integration, e-Surfing Cloud has paved the way for digital transformation for government and enterprises
MySQL详细安装与配置
AI智能剪辑,仅需2秒一键提取精彩片段
共享平台如何提高财务的分账记账效率?
HDF驱动框架的API(3)
55.【sort函数的升序降序】
数据治理:数据集成和应用模式的演进
Why young people are snapping up domestic iPhone, because it is much cheaper and more populist
mongodb的游标
随机推荐
TSF微服务治理实战系列(一)——治理蓝图
arcgis 分子式标注
透过案例看清API接口的作用——演示1688商品详情接口
Code Inspection for DevOps
2022最新彩虹表
Why young people are snapping up domestic iPhone, because it is much cheaper and more populist
Win11dll文件缺失怎么修复?Win11系统dll文件丢失的解决方法
注释
【软考软件评测师】基于经验的测试技术
开源一夏 | Web开发(七):登录实现及功能测试
如何应对机器身份带来的安全风险
如何减轻企业账户被劫持的攻击?
golang刷leetcode动态规划(10)编辑距离
如何构建准实时数仓?
请教一个数据库连接池的问题,目前已知是事务未设置超时,又有一块代码事务没有提交,一直把连接给耗尽了,
Interviewer: can you talk about optimistic locking and pessimistic locks
Endanger the safety of common Internet attacks have?
ROS基本编程概述
pydev debugger: warning: trying to add breakpoint to file that does not exist: /tmp/xxx
LiveGBS国标GB/T28181流媒体平台支持主子码流切换主码流stream/streamprofile