1 GateWay简介
1.1 Zuul退出历史舞台
第一代网关是zuul,zuul核心人员走了两个,zuul2的核心开发人员分歧较大,研发过久,spring公司等不及,自己研发的Gateway网关。
1.2 GateWay是什么
官网文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/
在微服务架构中网关的位置可以参考下图,也就是说网关是微服务最外面的入口,挡在第一线。
1.3 Gateway的特点
1.4 Zuul与Gateway的对比
1.5 Gateway的非阻塞异步模型
而springcloud Gateway使用了spring5的新特性:webflux和reactive stack
2 Hello Gateway
2.1 Gateway的工作流程
先讲解三个核心概念。
Route(路由):路由是构建网关的基本模块,它由ID,目标URL,一系列的断言和过滤器组成,如断言为true则匹配路由。
Predicate(断言):断言是JDK8的新特性,可以参考java.util.function.Predicate。断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。
Filter(过滤):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或之后对请求进行修改。
Gateway的工作流程可以参考下图。
web请求,通过一些匹配条件,定位到真正的服务节点,并在这个转发过程的前后,进行精细化的控制。Predicate就是我们匹配的条件,而Filter,可以理解为一个无所不能的拦截器,再加上目标URI,就可以实现一个具体的路由了
官网对于GateWay也进行了相应的总结。
2.2 搭建网关
(1)建模块
cloud-gateway-gateway9527
(2)写pom
注意:gateway 是网关,不是web项目,不能带spring-boot-starter-web,否则后面启动服务会出错哟。
<dependencies> <!--gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- 引用自己定义的api通用包,可以使用Payment支付Entity --> <dependency> <groupId>com.wangzhou.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <!--eureka client(通过微服务名实现动态路由)--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--热部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
(3)写yml
server: port: 9527 spring: application: name: cloud-gateway eureka: instance: hostname: cloud-gateway-service client: fetch-registry: true register-with-eureka: true service-url: #单机版 defaultZone: http://localhost:7001/eureka #集群版 # defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
(4)主启动
@SpringBootApplication @EnableEurekaClient //9527自己也是微服务,要向注册中心注册哟 public class GatewayMain9527 { public static void main(String[] args) { SpringApplication.run(GatewayMain9527.class, args); } }
(5)网关配置
回顾下我们之前的8001支付微服务,对外暴露了下面两个接口:/payment/get/{id}
,/payment/lb
,如果我们不想将这两个接口直接暴露给外接,而希望网关9527在外面挡一层,可以修改下9527的yml文件。
server: port: 9527 spring: application: name: cloud-gateway cloud: gateway: routes: - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名 #匹配后提供服务的路由地址 uri: http://localhost:8001 predicates: - Path=/payment/get/** # 断言,路径相匹配的进行路由 - id: payment_route2 uri: http://localhost:8001 predicates: - Path=/payment/lb/** #断言,路径相匹配的进行路由 eureka: instance: hostname: cloud-gateway-service client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://eureka7001.com:7001/eureka/
2.3测试
依次启动7001,8001,9527三个微服务
访问:http://localhost:9527/payment/get/1
再来。使用原端口
也可以访问,我们渐渐淡化了真实地址,通过网关端口访问
如果想安全点,服务器设置防火墙把8001墙了,只开放网关端口就好啦呀
回顾下网关的对应关系。
访问下lb:http://localhost:9527/payment/lb
发现没有,访问9527端口实际上找到的还是8001.