第一步:导入依赖
创建maven工程就不多说了,创建一个父工程后......,还是说一下父工程的pom吧
1.parent解决springboot相关依赖,包含了一些springboot的基本依赖,可以向下传递给子工程,也就是子工程相当于继承了父工程里的依赖包可以直接使用,不用再次导入一些基本的通用的依赖,具体细节看注释或可以百度一下。
2.dependencyManagement里面的是管理spring-cloud-dependencies、spring-cloud-alibaba-dependencies体系下依赖的版本,可以解决由于各种依赖版本引起的不兼容问题导致无法启动项目,所以子工程的依赖包就不用再写版本号了,由父工程统一管理可以避掉很多坑。
3.repositories为国内依赖镜像仓库,可以方便下载依赖。
<!-- 有了这个parent就不需要给子集pom配置版本号了,因为它包括了
1.定义了java编译版本为1.8
2.使用utf-8格式编码
3.继承spring-boot-dependencies进行统一版本依赖管理
4.执行打包 war jar操作配置(可以省略打包plugin的配置)
5.自动化资源过滤 如application.properties和application.yml的资源过滤 包括profile 多环境配置的
6.自动化插件配置
7.不需要配置maven打包plugin插件配置-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<!--引入springcloud的版本-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring</id>
<url>https://maven.aliyun.com/repository/spring</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
gateway子工程创建不多说,下面pom贴出来,这里nacos客户端要提前装好,因为通过网关调用微服务要通过注册中心先注册好,才能找到对应的转发请求路径。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
第二步:配置yml
1.网关自身端口 9999
2.nacos访问路径及端口 localhost:8848
- gateway的默认配置为开启,就是最下面enabled: true这个配置你就算删除它,网关也是默认开启的,所以可以不配, locator:后面的enabled就如同注释所说的那样。
server:
port: 9999
spring:
application:
name: simple-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true#开启表示根据微服务名称映射,就是微服务名称拼接到url中可以直接访问,但是不推荐这么使用 容易暴露微服务
enabled: true#默认开启网关true,关闭网关false
第三步:启动网关及相关微服务
启动网关之前你需要提供一个以上的微服务给网关调用才能体现它的价值,这个微服务也是要注册到nacos的,我简单定义一个order-center这样一个微服务,搭建过程和gateway类似。
controller接口
@RequestMapping(value = "/order")
@RestController
public class OrderController {
@RequestMapping(value = "/find")
public String find(){
return "下单号:3265467984";
}
}
yml
server:
port: 8889
spring:
application:
name: order-center
cloud:
nacos:
discovery:
server-addr: localhost:8848
启动类
@EnableDiscoveryClient
@SpringBootApplication
public class MyOrderApplication {
public static void main(String[] args) {
SpringApplication.run(MyOrderApplication.class,args);
}
}
ok!把他们全部启动起来,访问nacos,http://localhost:8848/nacos/

第四步:postman测试
localhost:9999/order-center/order/find

当然网页也可以发起这个get请求

总结:至此这个网关就可以正常使用了,但是没看出他有什么大的用处。
问:我可以直接访问order-center微服务接口啊,何必走网关呢?
直接请求微服务localhost:8889/order/find也是ok的

是的,如果此时你有很多个ip端口的微服务时,你在前端调用这些接口时就要配置相应这么多的ip端口,尽管你可以去动态配置管理它,况且一般都硬编码写死在前端代码中,一但ip端口发生变动时,管理起来也是相当混乱的,所以由gateway统一对前端暴露ip端口就不用担心了,只需要配置一个统一ip端口路径访问gateway就可以。
问:就算你使用了gateway网关,我还是能直接访问order-center微服务接口啊?
既然使用了网关,就必须强制走网关,为了安全,接口不会对外暴露所以你不知道真正的接口路径是啥,也就无从发起访问,如果你猜出访问路径,在服务部署到生产环境时也会通过防火墙屏蔽掉一切外部访问,当然还有一系列的权限校验拦截,只对外暴露gateway端口。
问:当前这个搭建好的网关有什么缺陷?
它将微服务名称order-center在访问url路径中暴露了出去,这样别人就知道你的微服务名称了,一般不会这么使用。
第五步:gateway拓展routes路由predicates、filter
gateway的yml追加一些配置,这里增加了一个服务product-center的配置。
1.id:取个名称要唯一,一般可以用微服务名称。
2.uri:要路由访问到哪个微服务,这里gateway底层会通过order-center去nacos中找到对应ip端口,lb表示采用负载均衡策略调用。
3.predicates:断言,会根据你的配置来判断是否满足断言条件,满足就放行帮你转发,不满足就给你挡回去不允许你访问,Path表示当前访问的url中能匹配上/order/**,如果url是localhost:9999/order/find就能匹配的上,如果url是localhost:9999/orders/find就匹配不上,自己试验,自己体会,总之就是满足条件的通过,不满足的请回。更多拓展使用访问官方:
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/index.html#configuring-route-predicate-factories-and-gateway-filter-factories
spring:
cloud:
gateway:
routes:
- id: order-center #id名称要唯一
uri: lb://order-center
predicates:
- Path=/order/**
- id: product-center #id名称要唯一
uri: lb://product-center
#谓词工厂
predicates:
- Path=/product/** #先匹配断言 然后追加或省略前缀
filters顾名思义就是过滤器,追加一些配置。
spring:
cloud:
gateway:
routes:
- id: order-center #id名称要唯一
uri: lb://order-center
predicates:
- Path=/order/**
- id: product-center #id名称要唯一
uri: lb://product-center
#谓词工厂
predicates:
- Path=/product/** #先匹配断言 然后追加或省略前缀
filters:
- AddRequestHeader=X-Request-Name,nico
- AddRequestParameter=name,nico123456
- StripPrefix=1 #跳过一个前缀 上下顺序有影响
- PrefixPath=/order#追加一个前缀 上下顺序有影响
- AddResponseHeader=X-Response-Name,nico
1.测试时要一个个调试filters下配置的这些作用,可以注释掉一部分避免相互影响。
2.它可以给通过网关gateway的请求追加请求头参数、请求参数、跳过一个前缀、追加一个前缀、追加响应头参数等,以localhost:9999/order/find为例,追加请求头参数就是给这个请求加了个参数X-Request-Name=nico到请求头里,后台服务controller中可以从中取出,自己试一下。
public String addHeader(@RequestHeader("X-Request-Name") String name){
return "gateway追加的请求头:"+name;
}
追加请求参数同理
public String addRequestParam(@RequestParam(value = "name",defaultValue = "nico") String param) {
return "gateway追加的请求参数"+param;
}
跳过一个前缀结果为 localhost:9999/find,当然这个路径是不会请求成功的。
追加一个前缀结果为 localhost:9999/order/order/find,当然这个路径是不会请求成功的。
但是上面两个组合起来用结果为localhost:9999/order/find,可以访问成功,反正灵活应用。
追加响应头参数X-Response-Name=nico,返回的响应头会包含这个参数。
最后:不管是predicates,还是filter,gateway都提供了对应的抽象工厂类我们可以继承它实现自己的自定义工厂类。
网友评论