php和mysql做租车网站,域名注册人查询,网址怎么输入,需要手机端网站建设的企业1.认识网关
网关#xff08;Gateway#xff09;和路由#xff08;Router#xff09;是两个相关但不同的概念。
一、网关#xff08;Gateway#xff09;
定义 网关是一个网络节点#xff0c;它充当了不同网络之间的连接点。可以将其看作是一个网络的 “大门”#xf…1.认识网关
网关Gateway和路由Router是两个相关但不同的概念。
一、网关Gateway
定义 网关是一个网络节点它充当了不同网络之间的连接点。可以将其看作是一个网络的 “大门”用于在不同的网络如本地网络和外部互联网、两个不同的局域网等之间传递数据。例如在一个企业内部网络连接到互联网时防火墙设备通常就充当网关。它接收来自内部网络的请求将这些请求转发到互联网并将互联网返回的数据再转发回内部网络。功能 协议转换不同的网络可能使用不同的网络协议。网关能够在这些不同协议之间进行转换。比如内部网络可能使用 IPX/SPX 协议而外部网络使用 TCP/IP 协议网关可以把基于 IPX/SPX 协议的数据包转换为 TCP/IP 协议的数据包反之亦然。数据转发网关会根据数据包的目的地址决定数据的流向。当它收到一个数据包时会查看数据包的目标网络地址然后将其转发到相应的网络。安全过滤网关可以作为安全控制点对进出网络的数据进行过滤。它可以阻止某些非法的或具有潜在威胁的网络流量进入或离开网络。例如网关可以配置访问控制列表ACL只允许特定 IP 地址或端口号的流量通过。
二、路由Router
定义 路由器是一种网络设备用于在多个网络可以是相同类型的网络也可以是不同类型的网络之间转发数据包。它通过维护路由表来决定数据包的转发路径。例如在一个大型企业网络中有多个部门的局域网路由器可以将不同部门局域网之间的数据进行转发并且还可以将这些局域网连接到互联网。功能 路径选择路由器的核心功能是根据路由表选择最佳的路径来转发数据包。路由表包含了网络地址、子网掩码、下一跳地址等信息。当路由器收到一个数据包时它会查看数据包的目的地址然后在路由表中查找最佳的转发路径。例如一个数据包要从本地网络发送到另一个远程网络路由器会根据网络拓扑和链路状态等因素选择一条最优的路径如最短路径或者带宽最高的路径等将数据包转发出去。网络互联路由器能够将不同的网络连接在一起。它可以连接局域网LAN和广域网WAN或者连接多个不同的局域网。比如一个小型办公室网络通过路由器连接到互联网服务提供商ISP的网络从而实现办公室内部的计算机与互联网的连接。隔离广播域路由器可以隔离广播域。在一个局域网中广播消息会被发送到局域网中的所有设备。但是当通过路由器连接不同的网络时广播消息不会被路由器转发到其他网络除非进行特殊配置。这有助于减少网络中的广播流量提高网络的性能。
现在微服务网关就起到同样的作用。前端请求不能直接访问微服务而是要请求网关 网关可以做安全控制也就是登录身份校验校验通过才放行 通过认证后网关再根据请求判断应该访问哪个微服务将请求转发过去
在SpringCloud当中提供了两种网关实现方案 Netflix Zuul早期实现目前已经淘汰 SpringCloudGateway基于Spring的WebFlux技术完全支持响应式编程吞吐能力更强
课堂中我们以SpringCloudGateway为例来讲解官方网站
Docshttps://b11et3un53m.feishu.cn/wiki/UMgpwmmQKisWBIkaABbcwAPonVf#S1FjdzW92oKZCJxLgs3cKmW9nUK
2.快速入门
接下来我们先看下如何利用网关实现请求路由。由于网关本身也是一个独立的微服务因此也需要创建一个模块开发功能。大概步骤如下 创建网关微服务 引入SpringCloudGateway、NacosDiscovery依赖 编写启动类 配置网关路由
2.1.创建项目
首先我们要在hmall下创建一个新的module命名为hm-gateway作为网关微服务 2.2.引入依赖
在hm-gateway模块的pom.xml文件中引入依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdhmall/artifactIdgroupIdcom.heima/groupIdversion1.0.0/version/parentmodelVersion4.0.0/modelVersionartifactIdhm-gateway/artifactIdpropertiesmaven.compiler.source11/maven.compiler.sourcemaven.compiler.target11/maven.compiler.target/propertiesdependencies!--common--dependencygroupIdcom.heima/groupIdartifactIdhm-common/artifactIdversion1.0.0/version/dependency!--网关--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId/dependency!--nacos discovery--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!--负载均衡--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-loadbalancer/artifactId/dependency/dependenciesbuildfinalName${project.artifactId}/finalNamepluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build
/project
2.3.启动类
在hm-gateway模块的com.hmall.gateway包下新建一个启动类
2.4.配置路由
接下来在hm-gateway模块的resources目录新建一个application.yaml文件内容如下
server:port: 8080
spring:application:name: gatewaycloud:nacos:server-addr: 192.168.150.101:8848gateway:routes:- id: item # 路由规则id自定义唯一uri: lb://item-service # 路由的目标服务lb代表负载均衡会从注册中心拉取服务列表predicates: # 路由断言判断当前请求是否符合当前规则符合则路由到目标服务- Path/items/**,/search/** # 这里是以请求路径作为判断规则- id: carturi: lb://cart-servicepredicates:- Path/carts/**- id: useruri: lb://user-servicepredicates:- Path/users/**,/addresses/**- id: tradeuri: lb://trade-servicepredicates:- Path/orders/**- id: payuri: lb://pay-servicepredicates:- Path/pay-orders/**3.路由过滤
路由规则的定义语法如下
spring:cloud:gateway:routes:- id: itemuri: lb://item-servicepredicates:- Path/items/**,/search/**
其中routes对应的类型如下 是一个集合也就是说可以定义很多路由规则。集合中的RouteDefinition就是具体的路由规则定义其中常见的属性如下 四个属性含义如下 id路由的唯一标示 predicates路由断言其实就是匹配条件 filters路由过滤条件后面讲 uri路由目标地址lb://代表负载均衡从注册中心获取目标微服务的实例列表并且负载均衡选择一个访问。 这里我们重点关注predicates也就是路由断言。SpringCloudGateway中支持的断言类型有很多 名称 说明 示例 After 是某个时间点后的请求 - After2037-01-20T17:42:47.789-07:00[America/Denver] Before 是某个时间点之前的请求 - Before2031-04-13T15:14:47.43308:00[Asia/Shanghai] Between 是某两个时间点之前的请求 - Between2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver] Cookie 请求必须包含某些cookie - Cookiechocolate, ch.p Header 请求必须包含某些header - HeaderX-Request-Id, \d Host 请求必须是访问某个host域名 - Host**.somehost.org,**.anotherhost.org Method 请求方式必须是指定方式 - MethodGET,POST Path 请求路径必须符合指定规则 - Path/red/{segment},/blue/** Query 请求参数必须包含指定参数 - Queryname, Jack或者- Queryname RemoteAddr 请求者的ip必须是指定范围 - RemoteAddr192.168.1.1/24 weight 权重处理
4.网关登录校验
单体架构时我们只需要完成一次用户登录、身份校验就可以在所有业务中获取到用户信息。而微服务拆分后每个微服务都独立部署不再共享数据。也就意味着每个微服务都需要做登录校验这显然不可取。
4.1.鉴权思路分析
我们的登录是基于JWT来实现的校验JWT的算法复杂而且需要用到秘钥。如果每个微服务都去做登录校验这就存在着两大问题 每个微服务都需要知道JWT的秘钥不安全 每个微服务重复编写登录校验代码、权限校验代码麻烦 既然网关是所有微服务的入口一切请求都需要先经过网关。我们完全可以把登录校验的工作放到网关去做这样之前说的问题就解决了 只需要在网关和用户服务保存秘钥 只需要在网关开发登录校验功能
此时登录校验的流程如图 暂时无法在飞书文档外展示此内容
不过这里存在几个问题 网关路由是配置的请求转发是Gateway内部代码我们如何在转发之前做登录校验 网关校验JWT之后如何将用户信息传递给微服务 微服务之间也会相互调用这种调用不经过网关又该如何传递用户信息
4.2.网关过滤器
登录校验必须在请求转发到微服务之前做否则就失去了意义。而网关的请求转发是Gateway内部代码实现的要想在请求转发之前做登录校验就必须了解Gateway内部工作的基本原理。 如图所示 客户端请求进入网关后由HandlerMapping对请求做判断找到与当前请求匹配的路由规则Route然后将请求交给WebHandler去处理。 WebHandler则会加载当前路由下需要执行的过滤器链Filter chain然后按照顺序逐一执行过滤器后面称为Filter。 图中Filter被虚线分为左右两部分是因为Filter内部的逻辑分为pre和post两部分分别会在请求路由到微服务之前和之后被执行。 只有所有Filter的pre逻辑都依次顺序执行通过后请求才会被路由到微服务。 微服务返回结果后再倒序执行Filter的post逻辑。 最终把响应结果返回。
如图中所示最终请求转发是有一个名为NettyRoutingFilter的过滤器来执行的而且这个过滤器是整个过滤器链中顺序最靠后的一个。如果我们能够定义一个过滤器在其中实现登录校验逻辑并且将过滤器执行顺序定义到NettyRoutingFilter之前这就符合我们的需求了
那么该如何实现一个网关过滤器呢
网关过滤器链中的过滤器有两种 GatewayFilter路由过滤器作用范围比较灵活可以是任意指定的路由Route. GlobalFilter全局过滤器作用范围是所有路由不可配置。
注意过滤器链之外还有一种过滤器HttpHeadersFilter用来处理传递到下游微服务的请求头。例如org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter可以传递代理请求原本的host头到下游微服务。
其实GatewayFilter和GlobalFilter这两种过滤器的方法签名完全一致
/*** 处理请求并将其传递给下一个过滤器* param exchange 当前请求的上下文其中包含request、response等各种数据* param chain 过滤器链基于它向下传递请求* return 根据返回值标记当前请求是否被完成或拦截chain.filter(exchange)就放行了。*/
MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain);
FilteringWebHandler在处理请求时会将GlobalFilter装饰为GatewayFilter然后放到同一个过滤器链中排序以后依次执行。
Gateway中内置了很多的GatewayFilter详情可以参考官方文档
Docshttps://b11et3un53m.feishu.cn/wiki/UMgpwmmQKisWBIkaABbcwAPonVf#CbiqdfAlNoTXFCxAJeDcyiwenuc
Gateway内置的GatewayFilter过滤器使用起来非常简单无需编码只要在yaml文件中简单配置即可。而且其作用范围也很灵活配置在哪个Route下就作用于哪个Route.
例如有一个过滤器叫做AddRequestHeaderGatewayFilterFacotry顾明思议就是添加请求头的过滤器可以给请求添加一个请求头并传递到下游微服务。
使用的使用只需要在application.yaml中这样配置
spring:cloud:gateway:routes:- id: test_routeuri: lb://test-servicepredicates:-Path/test/**filters:- AddRequestHeaderkey, value # 逗号之前是请求头的key逗号之后是value
如果想要让过滤器作用于所有的路由则可以这样配置
spring:cloud:gateway:default-filters: # default-filters下的过滤器可以作用于所有路由- AddRequestHeaderkey, valueroutes:- id: test_routeuri: lb://test-servicepredicates:-Path/test/**
5.自定义过滤器
无论是GatewayFilter还是GlobalFilter都支持自定义只不过编码方式、使用方式略有差别。
5.1自定义GlobalFilter
自定义GlobalFilter则简单很多直接实现GlobalFilter即可而且也无法设置动态参数
Component
public class PrintAnyGlobalFilter implements GlobalFilter, Ordered {Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 编写过滤器逻辑System.out.println(未登录无法访问);// 放行// return chain.filter(exchange);// 拦截ServerHttpResponse response exchange.getResponse();response.setRawStatusCode(401);return response.setComplete();}Overridepublic int getOrder() {// 过滤器执行顺序值越小优先级越高return 0;}
}