100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 微服务开发(三) Spring Cloud 网关gateway

微服务开发(三) Spring Cloud 网关gateway

时间:2022-12-30 20:36:58

相关推荐

微服务开发(三) Spring Cloud 网关gateway

目录

一.概要

二.spring cloud架构图

三. 项目结构

三.gateway的配置

四.解决问题

五.总结

一.概要

本篇文章可以单独阅读,如果要保持连贯性也可以先看看前面两篇文章.

微服务开发(一) Spring Cloud 到底是什么?

微服务开发(二) :Spring Cloud:OpenFeign 服务调用与网关

这篇文章主要介绍spring cloud中网关gateway的作用以及配置.

二.spring cloud架构图

在上一篇文章中,已经介绍过spring cloud的架构图了,上面这个图将更详细的描述spring cloud架构.从这个图中,我们要了解以下几个内容:

1) 在spring cloud中,项目组织结构是已模块的形式编写的;

2) 网关gateway也属于服务.

3) 因为各服务之间需要相互调用,都需要用到实体对象,所以将实体对象抽离出来放在common模块中,从上图可以看出common模块并不属于服务.

4) 服务(网关,微服务)都需要主动向服务管理中心进行注册;

5) 网关作为访问服务的入口,由网关来分配具体访问那个服务;

6) 每个微服务中controller是对外公开的部分,也就是说网关实际上是要求controller实现请求响应的功能.

7) 微服务之间也需要进行调用,注意看上图中红色的箭头; 微服务之间的调用是通过open feign实现的,open feigh访问的是服务的controller,并且也需要通过网关的转发,具体看上一篇文章.

8) 一个完整的服务包含有dao,service,controller,并且大多数情况也需要访问数据库.

三. 项目结构

上图展示了项目结构,其中:

1) common:是公共模块,里面暂时存放了实体对象,其它几个模块可以引用这个模块;

2) eurake-server:是服务管理中心,

3) gateway:是网关服务,目前只对配置文件进行了编写;

4) goods,user:是项目中提供具体服务的模块,留意goods模块下的facade包,这个包将通过open feign访问user服务的controller.

三.gateway的配置

gateway网关配置可以通过代码的方式,也可以通过application.yml文件配置的方式,通常application.yml的方式更加的灵活,所以本篇文章使用application.yml配置的方式.

首先我们来回顾下上一篇文章网关的关键配置.

# Spring应用(微服务)名称spring:application:name: gatewaycloud:gateway:# 开始配置路径routes:# 路径匹配- id: user# 转发URIuri: http://localhost:2001/# 断言配置predicates:- Path=/user/**# 路径匹配- id: goods# 转发URIuri: http://localhost:3001/# 断言配置predicates:- Path=/goods/**

在上面这段代码中配置了两个路由(id,uri,predicates就构成了最简单的路由.)

其中id为user的路由表示当浏览器访问:http://localhost:6001/user/test时(6001是网关的端口),网关会自动转发给:http://localhost:2001/user/test.

其中的id:user是唯一编号,没有实际含义,predicates是断言,表示当路径如何 /user/**的规则时,那么就响应 http://localhost:2001/的路径(响应的完整路径是:http://localhost:2001/user/**),其中user是服务名称,**可以匹配后面的所有内容.

但是上面的路由匹配存在以下几个问题:

1. 在之前我们通过配置做了负载均衡,user存在两个端口号(2001,2002),如果这里只发送给2001端口,那么之前的负载均衡就毫无作用.

2. user,goods关键字过于普通,如果在地址栏中出现与之相同的内容将会存在错误转发的情况;

3. 如果使用get方式访问时,地址栏可以带参数,能否通过路由限制参数.

接下来我们就逐一解决这三个问题.

四.解决问题

1. 通过gateway做负载均衡

服务内部我们可以通过 lb://<服务的名称> 访问服务的controller暴露出来的方法,例如:lb://user/test 可以访问user服务中controller定义的test方法.但是我们并不能通过地址栏直接这样访问,你可以认为这个是内部范围uri.其中<服务的名称>是在服务中心注册的名字.通过这样的方式,服务中心将自动完成负载均衡,并且不需要写端口号.

所以我们可以将上面的routes改成下面的形式:

routes:# 路径匹配- id: user# 转发URIuri: lb://user# 断言配置predicates:- Path=/user/**# 路径匹配- id: goods# 转发URIuri: lb://goods# 断言配置predicates:- Path=/goods/**

这里的lb://user和lb://goods将会访问在服务管理中心注册了的user符合和goods服务,并完成进行负载均衡.同时避免了写端口号.

使用上面的方式需要注意服务的命名规则,在java命名规则的基础上,不能使用"_"(下划线),因为这个不符合服务命名规则.

2. gateway过滤器

gateway提供了二十多种过滤器还可以自定义过滤器,但是我们一般情况下不需要这么复杂.接下来我们用StripPrefix过滤器解决上面的第二个问题,先看路由配置:

routes:# 路径匹配- id: user# 转发URIuri: lb://user# 断言配置predicates:- Path=/user-api/user/**- Query=id,^[0-9]*$# 过滤器配置filters:- StripPrefix=1# 路径匹配- id: goods# 转发URIuri: lb://goods# 断言配置predicates:- Path=/goods-api/goods/**# 过滤器配置filters:- StripPrefix=1

在上面这个案例中,使用的是/user-api/user/**的断言匹配lb:/user的路径,最近在服务中心将生成 lb://user/user-api/user/**的路径,但是显然这个路径是访问不到服务的,会出现404,所以在路由配置中,还有下面这段, filters: -StripPrefix=1 这是一个过滤器,在路由匹配之后,转发之前进行过滤,这段代码的含义就是去掉前面一段(/user-api/).所以实际访问的路径是 lb://user/user/**. 在这段代码中第一个user表示的是服务器中user服务,第二个user是因为这个服务的controller我们添加了@RequestMapping("user"),所以第二个user是指向这个controller的.

3. 匹配参数

在上面代码中,由一段- Query=id,^[0-9]*$ 表示需要在地址栏比配一个参数,并且参数必须为数字.

五.总结

经过上面的了解,其实我们在一开始定制服务的时候,就应该要由整体的认识,例如:

1. 服务的名称后面可以统一添加后缀,这样可以避免和其它命名相冲突,例如user-api,goods-api;

2. gateway使用配置文件进行配置;

3. 分析整体的业务需求,按照业务来划分服务.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。