Gateway-网关-分布式服务部署

前言

什么是API⽹关

API⽹关(简称⽹关)也是⼀个服务, 通常是后端服务的唯⼀⼊⼝. 它的定义类似设计模式中的Facade模式(⻔⾯模式, 也称外观模式). 它就类似整个微服务架构的⻔⾯, 所有的外部客⼾端访问, 都需要经过它来进⾏调度和过滤.

常⻅⽹关实现

Spring Cloud Gateway,Nginx

快速入门


因为要动态路由找到我们的服务,所以要用nacos,所以要引入nacos依赖

因为还有负载均衡,所以也要引入负载均衡的jar包

然后是写启动类

然后是写配置文件

现在我们通过网关服务来调用order-service

这样就调用成功了

没有配置的路径是访问不成功的

配置多个接口用逗号隔开就可以了

这样就成功了

这样的话,如果8080,9090端口没有开放的话,也是可以访问里面的东西了

Gateway-Predicate学习

predicates就是路由条件

这个就是path满足条件就会去调用url,调用对应的服务

predicate其实就是一个接口

这样子predicate就写好了,接下来就是使用了

引入这个测试依赖

这样就可以run了

我们还可以用匿名内部类的方式来创建predicate

这样也是可以的

因为提示了灰色--》可以优化

这里有提示

这样还是可以的

然后就是predicate还有其他的方法

negate就是对test的值取反而已

然后还有and,or这些



这个就是predicate的使用。and

Route Predicate Factories

路由断言工厂,就是路由的条件判断-》比如path
官网

这个的意思就是请求的时间必须在这个之后

这个意思就是请求必须在这个日期之前

请求必须在这两个日期之间

这个意思就是请求里面必须带一个cookie

名字为chocolate,value为ch.p,可能是一个值,也可能是一个正则表达式

意思就是请求要有这个header

key是X-Request-Id,值是\d+(数字类型),值是正则表达式

这个表示请求的方式为get或者post

这个是请求查询的字符串,第一个表示请求里面必须有gree这个参数

第二个表示请求参数必须有red,值为gree.,可以为正则表达式

多个参数用逗号分开

表示请求的ip

我们现在演示一下时间

存在多个路由条件的时候,关系是and


这样就不能访问了

日期格式怎么写呢

这样就可以直到当前日期了

GatewayFilter Factories(⽹关过滤器⼯⼚)

Predicate决定了请求由哪⼀个路由处理,如果在请求处理前后需要加⼀些逻辑,这就是Filter(过滤器)的作⽤范围了.

Filter分为两种类型:Pre类型和Post类型.

Pre类型过滤器:路由处理之前执⾏(请求 转发到后端服务之前执⾏),在Pre类型过滤器中可以做鉴权,限流等.

Post类型过滤器:请求执⾏完成后,将结果返回给客⼾端之前执⾏.

Spring Cloud Gateway从作⽤范围上,把Filter可分为GatewayFilter和GlobalFilter.

GatewayFilter: 应⽤到单个路由或者⼀个分组的路由上.

GlobalFilter: 应⽤到所有的路由上,也就是对所有的请求⽣效.

GatewayFilter 同Predicate 类似,都是在配置⽂件application.yml 中配置,每个过滤器的逻辑都是固定的.⽐如AddRequestParameterGatewayFilterFactory 只需要在配置⽂件中写AddRequestParameter ,就可以为所有的请求添加⼀个参数,我们先通过⼀个例⼦来演⽰GatewayFilter如何使⽤.

添加filters,

  • AddRequestParameter=userName,bite
  • 这个就表示给当前路由的所有请求添加请求参数key=userName,value=bite


官网


AddRequestHeader 为当前请求添加Header

RequestRateLimiter

为当前⽹关的所有请求执⾏限流过滤,如果被限流,默认会响应HTTP 429-Too ManyRequests默认提供了RedisRateLimiter的限流实现,采⽤令牌桶算法实现限流功能.此处不做具体介绍

RemoveResponseHeader

从响应结果删除某个Header

Retry

针对不同的响应进⾏重试.当后端服务不可⽤时,⽹关会根据配置参数来发起重试请求.

cpp 复制代码
filters:
    - name: Retry
      args:
        retries: 3
        statuses: BAD_REQUEST

就是针对不同的状态码进行重试

retries:重试次数,默认为3

status:HTTP请求返回的状态码,针对指定状态码进⾏重试.对应org.springframework.http.HttpStatus

RequestSize

设置允许接收最⼤请求包的⼤⼩.如果请求包⼤⼩超过设置的值,则返回413PayloadToo Large.请求包⼤⼩,单位为字节,默认值为5M

默认过滤器

添加⼀个filter并将其应⽤于所有路由,这个属性需要⼀个filter的列表4

要对全部的路由生效,就要使用默认的过滤器了

bash 复制代码
spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin

属性配置内容就是上面的内容

这个就是针对BAD_REQUEST重试三次,就是错误路径

针对所有的路径

这个就是返回的状态码为502的时候就重启

我们请求

发现直接打印了四次,说明请求响应了三次,第一次是正常的请求,失败了在请求三次

但是状态码并不影响我们界面的展示

GlobalFilter

GlobalFilter是Spring Cloud Gateway中的全局过滤器,它和GatewayFilter的作⽤是相同的. GlobalFilter 会应⽤到所有的路由请求上,全局过滤器通常⽤于实现与安全性,性能监控和⽇志记录等相关的全局功能.

Spring Cloud Gateway内置的全局过滤器也有很多,⽐如:

GatewayMetricsFilter: ⽹关指标,提供监控指标

ForwardRoutingFilter: ⽤于本地forword,请求不转发到下游服务器

LoadBalancerClientFilter: 针对下游服务,实现负载均衡.

官网

我们用的这个就是全局的路由器,就是GlobalFilter

GatewayMetricsFilter要先添加依赖

然后修改这个属性spring.cloud.gateway.metrics.enabled为true

默认监控的很少,我们配置一下,就监控很多了

然后开始启动

这个网关给我们提供了很多链接,都是json格式的

然后这些链接都是可以访问的

因为配置了这个所以显示很详细

因为配置了这个,所以显示很多链接·

⼀个项⽬中,既有GatewayFilter,⼜有GlobalFilter时,执⾏的先后顺序是什么呢?

请求路由后,⽹关会把当前项⽬中的GatewayFilter和GlobalFilter合并到⼀个过滤器链(集合)中,并进⾏排序,依次执⾏过滤器.

每⼀个过滤器都必须指定⼀个int类型的order值,默认值为0,表⽰该过滤的优先级.order值越⼩,优先级越⾼,执⾏顺序越靠前.

Filter通过实现Order接⼝或者添加@Order注解来指定order值.

SpringCloudGateway提供的Filter由Spring指定.⽤⼾也可以⾃定义Filter,由⽤⼾指定.

当过滤器的order值⼀样时,会按照defaultFilter>GatewayFilter>GlobalFilter的顺序执⾏

自定义Filter

Spring Cloud Gateway提供了过滤器的扩展功能,开发者可以根据实际业务来⾃定义过滤器,同样⾃定义过滤器也⽀持GatewayFilter和GlobalFilter两种

⾃定义GatewayFilter

⾃定义GatewayFilter,需要去实现对应的接⼝GatewayFilterFactory ,SpringBoot默认帮我们实现的抽象类是AbstractGatewayFilterFactory ,我们可以直接使⽤

因为过滤器还要有优先级,所以我们设定一个Ordered的优先级

我们定义一个接收参数的类型

然后来接收

然后是实现方法

Component还要有注解,打入spring

然后还要有构造方法,指定接收参数类型


这样我们的过滤器就实现了,然后就是开始配置了

原来:

现在:

注意我们的过滤器名称前面自定义,后面必须是GatewayFilterFactory

所以名字就是Custom

和这里是对应的,这个就是自定义过滤器的使用了

然后我们用网关来访问订单服务



⾃定义GlobalFilter

GlobalFilter的实现⽐较简单,它不需要额外的配置,只需要实现GlobalFilter接⼝,⾃动会过滤所有的Filter

因为这个是全局的过滤器

因为这个方法直接返回的就是Mono,所以直接就可以返回了

然后写pre和post

因为全局的过滤器直接作用于全局路由,所以不用配置的

所以我们知道了,同样的优先级的情况下,执行的优先是GatewayFilter

服务部署

没什么好配置的

直接打包

点这个,对集体打包,打出多个jar包

但是这个jar包很小,是因为没有打进来依赖,只打进来了代码

我们给gateway项目打进一个maven打包的插件


然后上传三个jar包order,product,gateway

因为product-api不是一个服务,所以不用上传

它是是作为依赖进去的

nohup java -jar gateway-1.0-SNAPSHOT.jar > logs/gateway.log &

nohup java -jar order-service-1.0-SNAPSHOT.jar > logs/order.log &

nohup java -jar product-service-1.0-SNAPSHOT.jar > logs/product.log &

我是两核两G的,启动多个服务的时候就会比较卡

分布式服务部署

部署介绍

分布式部署,就是部署到不同的机器上面




一个机器配置好的话,就可以配置网关,nacos,mysql

服务器1

MySQL,Nacos

服务器2

产品服务实例1,订单服务实例1

服务器3

产品服务实例2,订单服务实例2

服务器4

⽹关服务

Mysql安装

apt list | grep "mysql-server"

sudo apt install mysql-server

sudo systemctl status mysql检查状态

sudo mysql_secure_installation安装安全设置,一直Y,2,2是密码必须包含大小写和特殊字符

sudo mysql

alter user 'root'@'localhost' identified with mysql_native_password by "bit@yyds66"

然后数据初始化

MySQL默认情况下,只允许本地连接,即localhost,如果其他服务器需要连接到MySQL,需要MySQL对这个服务器授权

意思就是机器2和机器3要访问机器1的mysql,mysql要授权才可以

grant 权限 on 数据库对象 to ⽤⼾

使⽤下⾯SQL,创建⽤⼾,并授权

sql 复制代码
-- 创建⽤⼾bite, 并设置密码, 此步可省略
CREATE USER 'bite'@'%' IDENTIFIED BY '[email protected]';
-- 对bite⽤⼾授权
 -- *.* 表⽰所有库的所有表, 也可以指定库和表
 -- %表⽰IP, %表⽰允许所有IP所有的机器访问, 也可以指定IP机器 
GRANT ALL ON *.* TO 'bite'@'%';
-- 让修改⽣效
FLUSH PRIVILEGES;

GRANT ALL是开放所有的权限,*.*表示对所有的库和表

  1. 修改bind-address
    修改⽂件路径:/etc/mysql/mysql.conf.d/mysqld.cnf
    把bind-address =127.0.0.1改为bind-address =0.0.0.0
    #bind-address = 127.0.0.1
    bind-address = 0.0.0.0

vi /etc/mysql/mysql.conf.d/mysqld.cnf

原:

现在:

  1. 重启MySQL服务器

sudo systemctl restart mysql

这样不同的机器就要开放不同的端口号---》服务器控制台来开放

  1. 开放3306端⼝号
  2. 测试授权结果
    使⽤CMD客⼾端,连接服务器MySQL,如果可以正确连接,则授权成功

把110.41.51.65改成⾃⼰服务器的IP -u改成设置的账号名 -p后是对应的密码

mysql -h110.41.51.65 -P3306 -ubite [email protected]

这样就访问到了,表示授权成功了

安装nacos

安装这个之前先安装jdk

sudo apt update更新软件包

apt install openjdk-17-jdk

java -version

然后我们放入nacos

cd /usr/local/src/

直接拖过来

unzip nacos-server-2.2.3.zip

然后修改端口号

cd naocs/

cd conf

vim application.properties

然后启动程序

cd bin

bash startup.sh -m standalone

这样第一台机器就完成了

网关&订单&商品部署

这几个都是java服务的部署

然后就是分别安装jdk

这个就是问我们安装成功之后,要不要重启这个机器的服务

不需要的话,按esc

yml下的配置都不需要变

prod下的yml就要变了

原:

127因为原来mysql与order在同一台机器,所以没有问题

所以order就要改mysql的url,name,密码

product

product的bootstrap的nacos地址没有变化

但是我们的naocs没有配置

product的controller使用了naocs的配置,所以nacos对应要配置

prod还是要改mysql

就这两个问题

就在这里配置

不配置的话,product就启动不成功

但是mysql没有配置都启动成功了

网关

第三个机器

现在部署网关服务

还是要安装jdk

拖动记得安装rz

apt install lrzsz

这样就表面访问成功了

通过网关来访问order

10030/order/1

看到日志,数据库链接拒绝


然后改一下数据库的链接信息

授权就是端口开放没有

然后重新打包

记得杀掉原来的进程

然后重启服务

这样好像成功了

但是我们这个网关的ip地址不对呢

其他服务的ip也不对

因为一个服务器有内网ip和外网ip,这个naocs注册的是内网的ip

所以gateway路由到nacos的时候,获取到的是内网的ip--》只能局域网内部访问

如果不在一个局域网里面,访问是会失败的,需要改成外网ip

我们通过spring.cloud.nacos.discovery.ip来设置外网ip

就是可以在启动服务的时候指定

nohup java -jar xx.jar --spring.cloud.nacos.discovery.ip=自己ip > logs/xx.log &

这样ip就变了,别人可以访问它了

然后就是同样的方式启动product,gateway

然后是可以访问的

订单2&商品2部署

现在机器1,3,4都已经完成了,我们现在开始完成机器2

机器2和机器1差不多

先安装jdk

然后把jar拖进来,上面都已经改好了的

这样就有两个order了

product也是一样的

总结

相关推荐
TE-茶叶蛋4 分钟前
2025-Gateway架构
架构·gateway
小样vvv4 小时前
【微服务管理】深入理解 Gateway 网关:原理与实现
微服务·gateway
sky.fly5 小时前
在思科模拟器show IP route 发现Gateway of last resort is not set没有设置最后的通道
网络协议·tcp/ip·gateway
angushine2 天前
Gateway统一修改响应内容
gateway
云攀登者-望正茂4 天前
通过AWS WAF Rate limit rule来保护API Gateway
网络·gateway·aws
小怪瘦795 天前
IDEA :物联网ThingsBoard-gateway配置,运行Python版本,连接thingsboard,接入 MQTT 设备
python·物联网·gateway·idea
字节源流7 天前
【Spring Cloud Netflix】GateWay服务网关
java·运维·gateway
A叶子叶15 天前
Kong网关部署研究
python·spring cloud·微服务·gateway·kong
甜可儿16 天前
Gateway实战入门(四)、断言-请求头以及请求权重分流等
java·spring cloud·gateway