微服网关
为了解决客户端访问不同的服务,需要调用不同的服务地址。因此需要微服务网关定制统一的地址,使所有请求都经过网关进行访问,从而简化开发
常见的api网关实现方式
kong
基于Nginx+Lua开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可以开箱即用。
问题:只支持Http协议;二次开发,自由扩展困难;提供管理API,缺乏更易用的管控、配置方式
Zuul
Netflflix开源,功能丰富,使用JAVA开发,易于二次开发;需要运行在web容器中,如Tomcat。
问题:缺乏管控,无法动态配置;依赖组件较多;处理Http请求依赖的是Web容器,性能不如 Nginx
Traefifik
Go语言开发;轻量易用;提供大多数的功能:服务路由,负载均衡等等;提供WebUI
问题:二进制文件部署,二次开发难度大;UI更多的是监控,缺乏配置、管理能力;
Spring Cloud GatewaySpringCloud提供的网关服务
Nginx+lua实现
使用Nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用
问题:自注册的问题和网关本身的扩展性
Zuul使用
搭建zuul网关服务
- 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.marcosbarbero.cloud</groupId>
<artifactId>spring-cloud-zuul-ratelimit</artifactId>
<version>1.3.4.RELEASE</version>
</dependency>
- 启动类
添加:@EnableZuulProxy
- 配置文件
server:
port: 7003
spring:
application:
name: my-wf-gateway-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
prefer-ip-address: true #显示浏览器中的状态栏显示ip
zuul:
routes:
myuser-consumer: # 这里是路由id,随意写
path: /userserver/** # 这里是映射路径
serviceId: user-consumer #配置转发的微服务名称
# ratelimit:
# enabled: true #开启限流
# policies:
# myuser-consumer:
# limit: 10 #60s 内请求超过 3 次,服务端就抛出异常,60s 后可以恢复正常请求
# refresh-interval: 60
# type: origin #针对 IP 进行限流,不影响其他 IP
ratelimit:
enabled: true #开启限流
default-policy:
limit: 3 #60s 内请求超过 3 次,服务端就抛出异常,60s 后可以恢复正常请求
refresh-interval: 60
type: origin #针对 IP 进行限流,不影响其他 IP
zuul过滤器
- PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
- ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfifilx Ribbon请求微服务。
- POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP
Header、收集统计信息和指标、将响应从微服务发送给客户端等。- ERROR:在其他阶段发生错误时执行该过滤器。
@Component
public class PowerFilter extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return