什么是网关
随着互联网的快速发展,当前以步入移动互联、物联网时代。用户访问系统入口也变得多种方式,由原来单一的PC客户端,变化到PC客户端、各种浏览器、手机移动端及智能终端等。同时系统之间大部分都不是单独运行,经常会涉及与其他系统对接、共享数据的需求。所以系统需要升级框架满足日新月异需求变化,支持业务发展,并将框架升级为微服务架构。“API网关”核心组件是架构用于满足此些需求。
很多互联网平台已基于网关的设计思路,构建自身平台的API网关,国内主要有京东、携程、唯品会等,国外主要有Netflix、Amazon等。
网关框架框架
1、基于nginx平台实现的网关有:KONG、API Umbrella
2、自研发的网关有:apigateway、Zuul
API网关设计
API网关是微服务架构(Microservices Architecture)标准化服务的模式。API网关定位为应用系统服务接口的网关,区别于网络技术的网关,但是原理则是一样。API网关统一服务入口,可方便实现对平台众多服务接口进行管控,对访问服务的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,甚至基于API调用的计量或者计费等等。
网关的应用场景
1、 黑白名单:实现通过IP地址控制禁止访问网关功能,此功能是应用层面控制实现,再往前也可以通过网络传输方面进行控制访问。
2、 日志:实现访问日志的记录,可用于分析访问、处理性能指标,同时将分析结果支持其他模块功能应用。
3、 协议适配:实现通信协议校验、适配转换的功能。
4、 身份认证:负责网关访问身份认证验证,此模块与“访问认证中心”通信,实际认证业务逻辑交移“访问认证中心”处理。
5、 计流限流:实现微服务访问流量计算,基于流量计算分析进行限流,可以定义多种限流规则。
路由:路由是API网关很核心的模块功能,此模块实现根据请求,锁定目标微服务并将请求进行转发。此模块需要与“服务发布管理中心”通信。“服务发布管理中心”实现微服务发布注册管理功能,与其通信获得目标微服务信息。
API网关部署
API网关是一个公共基础组件,无状态,可支持多套分布式部署。如下图所示:
lvs + Keepalived 属于四层负载均衡,针对于 ip + port 这一层。
lvs 作用:管理Nginx 集群。
Nginx 属于七层负载均衡,针对于 Http 协议这一层。
Zuul框架与Nginx 的区别
1、Zuul框架使用java语言写的,Nginx使用C语言写的。
2、Nginx是服务器端反向代理服务器,Zuul是为微服务中的反向代理服务器。
3、Nginx针对与服务器层面,Zuul 针对与客户端层面的。
基于Nginx 搭建API网关
使用网关可以解决跨越问题,实现原理:保证域名相同,使用Nginx区分不同的项目路径进行转发跳转。
Nginx配置反向代理:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name www.test.com;
location /api-a {
proxy_pass http://www.test.com:8000/;
index index.html index.htm;
}
location /api-b {
proxy_pass http://www.test.com:8001/;
index index.html index.htm;
}
}
}
基于Zuul搭建网关
zuul 网关 配置文件
### 将服务注册到 eureka 注册中心 i
eureka.client.serviceUrl.defaultZone=http://localhost:8100/eureka/
### zuul 服务端口号
server.port=8080
### zuul 服务别名
spring.application.name=service-zuul
### 路由配置
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=springboot_zuul_a
### 路由拦截地址
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=springboot_zuul_b
Eureka 注册中心配置文件
## eureka 端口号
server.port=8100
### 注册中心 eureka 别名
eureka.instance.hostname=eureka-server
### eureka 注册中心地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
### 是否注册到自己本身 eureka 集群时使用(true)
eureka.client.register-with-eureka=false
### 是否检索服务信息 集群时使用(true)
eureka.client.fetch-registry=false
spirngboot_zuul_a 配置文件
### a 项目端口号
server.port=8081
### a 项目服务别名
spring.application.name=springboot_zuul_a
### 服务注册到 eureka 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8100/eureka
spirngboot_zuul_b 配置文件
### b 项目端口号
server.port=8082
### b 项目服务别名
spring.application.name=springboot_zuul_b
### 服务注册到 eureka 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8100/eureka
zuul 启动类上面需要添加二个注解:
@EnableZuulProxy //开启 zuul 服务
@EnableEurekaClient // 注册到 eureka 注册中心
过滤器拦截参数
// 使用网关拦截Token参数public class TokenFilter extends ZuulFilter { public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); Object accessToken = request.getParameter("accessToken"); if (accessToken == null) { // 返回错误信息 ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); ctx.setResponseBody("accessToken is null"); return null; } return null; } public boolean shouldFilter() { return true;// 是否执行该过滤器,此处为true,说明需要过滤 } @Override public int filterOrder() { return 0;// 优先级为0,数字越大,优先级越低 } @Override public String filterType() { return "pre"; // 前置过滤器 } }
原文地址:https://www.cnblogs.com/ming-blogs/p/11087413.html