今天,我们就在项目中整合SpringCloud Gateway来为项目增加API网关,同时,会将SpringCloud Gateway与Sentinel进行整合实现网关的限流能力。说干就干,小伙伴们跟上发车速度。,我们需要在项目中增加一个服务网关模块shop-gateway,在服务网关模块中实现网关的能力。此时,我们的项目中就会有用户微服务、商品微服务、订单微服务和服务网关。,在项目中新建shop-gateway模块,新增网关模块后项目的结构如下图所示。,(1)在服务网关shop-gateway模块的pom.xml文件中添加如下依赖。,(2)在服务网关shop-gateway模块的resources目录下新建application.yml文件,并在文件中添加如下配置信息。,我们重点来看下 spring.cloud.gateway 节点下的配置。,(3)在服务网关shop-gateway模块的io.binghe.shop包下新建GatewayStarter类,表示服务网关的启动类,源码如下所示。,(4)由于之前项目中整合了Nacos和Sentinel,所以,在启动项目前,要分别启动Nacos和Sentinel。,进入Sentinel Jar包所在的目录,输入如下命令启动Sentinel。,(5)分别启动用户微服务、商品微服务、订单微服务和服务网关。,(6)通过服务网关访问用户微服务,在浏览器中输入http://localhost:10001/server-user/user/get/1001,如下所示。,用户微服务返回的原始数据如下所示。,可以看到,通过服务网关能够正确访问到用户微服务。,(7)通过服务网关访问商品微服务,在浏览器中输入http://localhost:10001/server-product/product/get/1001,如下所示。,商品微服务返回的原始数据如下所示。,可以看到,通过服务网关能够正确访问到商品微服务。,(8)通过服务网关访问订单微服务,在浏览器中输入http://localhost:10001/server-order/order/test_sentinel,如下所示。,可以看到,通过服务网关能够正确访问到订单微服务。,在初步整合SpringCloud Gateway中,我们在服务网关模块的application.yml文件中硬编码配置了服务转发的地址,如下所示。,这里,我们将网关整合Nacos实现从Nacos注册中心获取转发的服务地址。,(1)在服务网关shop-gateway模块的pom.xml文件中继续添加如下依赖。,(2)在服务网关shop-gateway模块的启动类io.binghe.shop.GatewayStarter上添加@EnableDiscoveryClient注解,如下所示。,(3)将application.yml备份一份,命名为application-simple.yml,并修改application.yml配置文件,修改后的文件如下所示。,上述配置中增加了Nacos相关的配置,如下所示。,新增了让SpringCloud Gateway可以发现Nacos中的服务配置,如下所示。,另外,将硬编码的服务转发地址修改成从Nacos中按照名称获取微服务地址,并按照负载均衡策略分发。,其中,lb指的是从Nacos中按照微服务的名称获取微服务地址,并按照负载均衡的策略分发。使用lb从Nacos中获取微服务时,遵循如下的格式。,微服务的名称就是各个微服务在application.yml文件中配置的服务名称。,(4)分别启动用户微服务、商品微服务、订单微服务和服务网关。,(5)通过服务网关访问用户微服务,在浏览器中输入http://localhost:10001/server-user/user/get/1001,如下所示。,用户微服务返回的原始数据如下所示。,可以看到,通过服务网关能够正确访问到用户微服务。,(6)通过服务网关访问商品微服务,在浏览器中输入http://localhost:10001/server-product/product/get/1001,如下所示。,商品微服务返回的原始数据如下所示。,可以看到,通过服务网关能够正确访问到商品微服务。,(7)通过服务网关访问订单微服务,在浏览器中输入http://localhost:10001/server-order/order/test_sentinel,如下所示。,可以看到,通过服务网关能够正确访问到订单微服务。,SpringCloud Gateway整合Nacos后,可以不用手动指定其他微服务的名称来从Nacos中获取微服务的地址。接下来,我们就来实现SpringCloud Gateway网关整合Nacos的最简配置。,(1)将application.yml备份一份,命名为application-nacos.yml,并修改application.yml配置文件,修改后的文件如下所示。,可以看到,在application.yml文件中,去掉了spring.cloud.gateway.routes 节点及其下面的所有配置。,(2)分别启动用户微服务、商品微服务、订单微服务和服务网关。,(3)通过服务网关访问用户微服务,在浏览器中输入http://localhost:10001/server-user/user/get/1001,如下所示。,用户微服务返回的原始数据如下所示。,可以看到,通过服务网关能够正确访问到用户微服务。,(4)通过服务网关访问商品微服务,在浏览器中输入http://localhost:10001/server-product/product/get/1001,如下所示。,商品微服务返回的原始数据如下所示。,可以看到,通过服务网关能够正确访问到商品微服务。,(5)通过服务网关访问订单微服务,在浏览器中输入http://localhost:10001/server-order/order/test_sentinel,如下所示。,可以看到,通过服务网关能够正确访问到订单微服务。,注意:SpringCloud Gateway整合Nacos最简配置时,通过网关访问微服务的格式如下所示。,Sentinel从1.6.0版本开始,提供了SpringCloud Gateway的适配模块,并且可以提供两种资源维度的限流,一种是route维度;另一种是自定义API分组维度。,(1)在服务网关shop-gateway模块的pom.xml文件中添加如下依赖。,(2)在服务网关shop-gateway模块中新建io.binghe.shop.config包,并在包下新建GatewayConfig类。基于Sentinel 的Gateway限流是通过其提供的Filter来完成的,使用时只需注入对应的SentinelGatewayFilter实例以及 SentinelGatewayBlockExceptionHandler 实例即可。,GatewayConfig类的源代码如下所示。,GatewayConfig类的源代码看上去比较多,但是都是一些非常简单的方法,冰河在这里就不再赘述了。,这里有个需要特别注意的地方:,Sentinel1.8.4整合SpringCloud Gateway使用的API类型为Route ID类型时,也就是基于route维度时,由于Sentinel为SpringCloud Gateway网关生成的API名称规则如下:,生成的规则为:${spring.cloud.gateway.discovery.locator.route-id-prefix}后面直接加上目标微服务的名称,如下所示。,{spring.cloud.gateway.discovery.locator.route-id-prefix}目标微服务的名称。其中,${spring.cloud.gateway.discovery.locator.route-id-prefix}是在yml文件中配置的访问前缀。,为了让通过服务网关访问目标微服务链接后,请求链路中生成的API名称与流控规则中生成的API名称一致,以达到启动项目即可实现访问链接的限流效果,而无需登录Setinel管理界面手动配置限流规则,可以将生成GatewayFlowRule对象的resource参数设置为${spring.cloud.gateway.discovery.locator.route-id-prefix}目标微服务的名称,当然,如果不按照上述配置,也可以在项目启动后,通过服务网关访问目标微服务链接后,在Sentinel管理界面的请求链路中找到对应的API名称所代表的请求链路,然后手动配置限流规则。,(3)将服务网关shop-gateway模块的application.yml文件备份一份名称为application-nacos-simple.yml的文件,并将application.yml文件的内容修改成如下所示。,其中:,(4)在IDEA中配置启动服务网关shop-gateway模块的参数-Dcsp.sentinel.app.type=1,如下所示。,如果是在命令行启动网关服务的Jar包,则可以使用如下命令。,或者在启动类io.binghe.shop.GatewayStarter的main()方法中添加一行System.setProperty("csp.sentinel.app.type", "1");代码,如下所示。,(5)分别启动用户微服务、商品微服务、订单微服务和服务网关,启动后会在Sentinel管理界面左侧菜单栏中看到server-gateway菜单,如下所示。,在server-gateway菜单下的流控规则子菜单中可以看到网关的流控规则已经注册到Sentinel,如下所示。,(6)通过服务网关访问用户微服务,在浏览器中输入http://localhost:10001/server-user/user/get/1001,不断刷新页面,如下所示。,用户微服务返回的原始数据如下所示。,可以看到,通过服务网关不断刷新用户微服务时,触发了服务限流,并返回了自定义的限流结果数据。,(7)通过服务网关访问商品微服务,在浏览器中输入http://localhost:10001/server-product/product/get/1001,不断刷新页面,如下所示。,商品微服务返回的原始数据如下所示。,可以看到,通过服务网关不断刷新商品微服务时,触发了服务限流,并返回了自定义的限流结果数据。,(8)通过服务网关访问订单微服务,在浏览器中输入http://localhost:10001/server-order/order/test_sentinel,不断刷新页面,如下所示。,可以看到,通过服务网关不断刷新订单微服务时,触发了服务限流,并返回了自定义的限流结果数据。,前面,我们实现了route维度的限流,接下来,我们再基于Sentinel与SpringCloud gateway实现自定义API分组维度的限流。,(1)在服务网关shop-gateway模块的io.binghe.shop.config.GatewayConfig配置类中新增initCustomizedApis()方法,初始化API管理的信息,源码如下所示。,上述代码中,配置了两个API分组,每个API分组的规则如下。,(2)在服务网关shop-gateway模块的io.binghe.shop.config.GatewayConfig配置类中init()方法中调用initCustomizedApis()方法,为了避免route维度的限流对自定义API分组维度的限流产生影响,这里,同时在init()方法中注释掉调用initGatewayRules()方法,修改后的init()方法的代码如下所示。,(3)在用户微服务shop-user的io.binghe.shop.user.controller.UserController类中新增四个测试接口,源码如下所示。,(4)分别启动用户微服务、商品微服务、订单微服务和服务网关,启动后会在Sentinel管理界面左侧菜单栏中看到server-gateway菜单,如下所示。,此时,由于我们注释了调用以route维度限流的方法,所以,在流控规则里的限流规则为空,如下所示。,在API管理里面会发现我们定义的API分组已经自动注册到Sentinel中了,如下所示。,(5)在Sentinel管理界面的流控规则中,新增网关流控规则,如下所示。,点击新增网关流控规则后,会弹出新增网关流控规则配置框,按照如下方式为user_api1分组配置限流规则。,点击新增按钮后,按照同样的方式为user_api2分组配置限流规则。,配置完毕后,在流控规则中的限流规则如下所示。,(6)预期的测试结果如下。,注意:只有最后一个不会被限流。,(7)在浏览器上频繁访问http://localhost:10001/server-user/user/api1/demo1,如下所示。,返回的原始数据如下所示。,说明触发了服务限流,并返回了自定义的限流结果数据。,(8)在浏览器上频繁访问http://localhost:10001/server-user/user/api1/demo2,如下所示。,返回的原始数据如下所示。,说明触发了服务限流,并返回了自定义的限流结果数据。,(9)在浏览器上频繁访问http://localhost:10001/server-user/user/api2/demo1,如下所示。,返回的原始数据如下所示。,说明触发了服务限流,并返回了自定义的限流结果数据。,(10)在浏览器上频繁访问http://localhost:10001/server-user/user/api2/demo2,如下所示。,可以看到,访问http://localhost:10001/server-user/user/api2/demo2时,无论访问的频率多频繁,都不会触发Sentinel限流。,至此,我们就成功在项目中整合了SpringCloud Gateway网关,并通过Sentinel整合SpringCloud Gateway实现了网关的限流操作。
© 版权声明
文章版权归作者所有,未经允许请勿转载。