在微服务架构中,各个服务分散部署,每个服务可能会有不同的环境、网络等。而外部客户端可能需要调用多个服务,例如一个电商APP,可能需要调用用户、商品、交易等多个服务才能完成一个业务流程,如果让客户端直接与微服务通信,势必引发许多问题:
- 增加客户端请求服务的复杂性,不同的服务地址不同,管理困难
- 安全问题,不同的服务需要单独进行安全认证,复杂且不可持久
- 重构困难,当业务不断发展,服务可能会发生重新划分,直接导致客户端不可用
- 其他…
由于客户端直接与微服务通信存在诸多问题,需要引入一个中间层来解决客户端与微服务的直接耦合,即网关。
网关介于客户端与微服务之间,所有外部客户端的请求首先到达网关,由网关处理后在发送到微服务,如下图所示:
网关的作用,就是聚合各个微服务,客户端只跟网关通信,不再直接调用微服务,从而简化客户端的开发。
##Zuul
Zuul时Netflix开发的微服务网关框架,它可以很好的与Spring Cloud进行整合,与Eureka、Ribbon、Feign、Hystrix等组件配合使用。Zuul的核心是一系列的Filter,通过组合这些Filter可以完成一系列功能:
- 身份认证与安全
- 监控
- 动态路由
- 负载均衡
- 压力测试支持
- 其他…
Zuul默认使用Apache的Http Client作为Http客户端,也可以通过配置修改为okhttp或RestClient。
实战
Gateway-Zuul
创建新工程gateway-zuul
设置依赖
<dependencies> |
添加配置
bootstrap.yml
spring:
application:
name: gateway-server
cloud:
config:
uri: http://localhost:8888 # 配置服务器地址
fail-fast: true # 快速失败
name: ${spring.application.name} #默认就是spring.application.name
profile: ${spring.profiles.active:default} # 默认就是spring.profiles.active
label: master #标签
retry:
max-attempts: 6 #最大重试次数
max-interval: 2000 #间隔时间application.yml
zuul:
ignored-services: provider-user #忽略服务代理,多个用逗号分隔。* 表示忽略所有
ignored-patterns: /**/admin/** #忽略包含 /admin/ 的路径
routes:
consumer-movie: /movie/**application-local.yml
server:
port: 6999
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
创建启动类
package com.huluohu.cloud.gateway; |
测试
- 启动Eureka Server(local profile)
- 启动Config Server(不需要区分profile)
- 启动provider-user-hystrix(local profile)
- 启动consumer-movie-hystrix(local profile)
- 启动gateway-zuul(local profile)
启动应用列表
在浏览器中输入
http://localhost:6999/movie/test/user/1
,即可通过网关访问到consumer-movie服务
扩展
- 自定义访问路径
zuul: |
微服务consumer-movie
会被映射到/movie/**
路径
- 忽略微服务
zuul: |
provider-user
微服务不会被zuul代理,可以使用逗号分隔多个服务
- 忽略所有微服务
zuul: |
忽略所有其他服务,仅代理consumer-movie
服务
- 自定义路由
zuul: |
效果与1
中的配置一样
- 指定微服务地址
zuul: |
会讲/movie/映射到 http://localhost:9002/**
上,但是Hystrix和Ribbon会失效
- 指定微服务地址增强
zuul: |
通过禁用eureka,然后指定服务列表,可以实现自定义服务地址,同时Hystrix和Robbin不失效
- 前缀设置
- 过滤前缀
zuul: |
如果strix-prefix=true, 路径为/movie/**
到达Zuul后会被转发到consumer-movie服务的 /**
路径
如果strix-prefix=true, 路径为/movie/**
到达Zuul后会被转发到consumer-movie服务的 /movie/**
路径
- 添加前缀
zuul: |
会对zuul的所有path前面增加一个前缀 /api 如 /consumer-movie/user/1
需要修改为 /api/consumer-movie/user/1