由于公司最近引用网关API,jenkins热部署以及nginx代理转发的一整套服务体系,相较于以前系统分散,同样的功能需要多次维护,管理维护都十分麻烦,同时也造成了效率不高等问题,所以本文就这些技术问题加以总结,如有任何问题,欢迎指出!!
一:引入网关gateway的原因以及jenkins,nginx的作用
为何引入网关?
- 1首先,什么是网关?
API网关:能提供一个单独且统一的API入口用于访问内部一个或多个API,是一个独立于内部微服务的组件。
简单说就是:服务网关 = 路由转发 + 过滤器
1)路由转发:接收一切外界请求,转发到后端的微服务上去;
2)过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验、负载均衡,缓存,服务代理以及监控 日志等,这些都可以通过过滤器完成(其实路由转发也是通过过滤器实现的)。
- 2 为什么需要服务网关?
上述所说的横切功能(以权限校验为例)可以写在三个位置:
①每个服务自己实现一遍
②写到一个公共的服务中,然后其他所有服务都依赖这个服务
③写到服务网关的前置过滤器中,所有请求过来进行权限校验
方案①,缺点太明显,基本不用;
方案②,相较于第一点好很多,代码开发不会冗余,但是有两个缺点:
- 由于每个服务引入了这个公共服务,那么相当于在每个服务中都引入了相同的权限校验的代码,使得每个服务的jar包大小无故增加了一些,尤其是对于使用docker镜像进行部署的场景,jar越小越好;
- 由于每个服务都引入了这个公共服务,那么我们后续升级这个服务可能就比较困难。而且公共服务的功能越多,升级就越难,而且假设我们改变了公共服务中的权限校验的方式,想让所有的服务都去使用新的权限校验方式,我们就需要将之前所有的服务都重新引包,编译部署。
而服务网关恰好可以解决这样的问题:
- 将权限校验的逻辑交给网关的过滤器,后端服务不需要关注权限校验的代码,所以服务的jar包中也不会引入权限校验的逻辑,不会增加jar包大小;
- 如果想修改权限校验的逻辑,只需要修改网关中的权限校验过滤器即可,而不需要升级所有已存在的微服务。
- 3 微服务API网关的解决方案:
私有云开源解决方案如下:
- Kong kong是基于Nginx+Lua进行二次开发的方案, https://konghq.com/
- Netflix Zuul,zuul是spring cloud的一个推荐组件,https://github.com/Netflix/zuul
- orange,这个开源程序是国人开发的, http://orange.sumory.com/
公有云解决方案:
- Amazon API Gateway,https://aws.amazon.com/cn/api-gateway/
- 阿里云API网关,https://www.aliyun.com/product/apigateway/
- 腾讯云API网关, https://cloud.tencent.com/product/apigateway
自开发解决方案:
- 基于Nginx+Lua+ OpenResty的方案,可以看到Kong,orange都是基于这个方案
- 基于Netty、非阻塞IO模型。 通过网上搜索可以看到国内的宜人贷等一些公司是基于这种方案,是一种成熟的方案。
- 基于Node.js的方案。 这种方案是应用了Node.js天生的非阻塞的特性。
- 基于java Servlet的方案。 zuul基于的就是这种方案,这种方案的效率不高,这也是zuul总是被诟病的原因
公司采用的Netflix Zuul,即SpringCloud推荐的组件,它具备的优点与缺点就不一一罗列,感兴趣的朋友可以查资料!!
- 4 nginx与jenkins的优势
jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台。
作用: 持续、自动地构建/测试软件项目。
监控软件开放流程,快速问题定位及处理,提示开放效率。
nginx是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务。在前面文章有具体的关于nginx,jenkins的应用。
- 5 微服务网关架构图及具体应用过程
如下图为公司系统优化而引入微服务网关的整体构造图,其中在网关前使用nginx代理,其实是为了避免网关的单点问题。原因之一:在整个网络调用过程中,一定会有一个单点,可能是网关、nginx、dns服务器等。防止网关单点,可以在网关层前边再挂一台nginx,nginx的性能极高,基本不会挂,这样之后,网关服务就可以不断的添加机器。
原因之二:项目基本采用前后端分离形式,前端使用vue.js框架实现。所以需要nginx作为代理转发到相应的后台服务。
所以重点来了,如何将jenkins,nginx以及网关gateway,内部微服务这一整套串起来??
首先jenkins的安装及项目构建热部署过程参看前面文章,jenkins将后台服务以及前端静态资源通过命令存放在相应的目录下,此时nginx的配置文件就要发挥作用了
#user nobody;
worker_processes 4;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_max_body_size 80M;
client_body_buffer_size 128k;
fastcgi_intercept_errors on;
server {
listen 441 ssl;
ssl_certificate /home/nginx/conf/api_gateway_openssl.crt;
ssl_certificate_key /home/nginx/conf/api_gateway_openssl.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
listen 8002;
server_name 172.16.16.45;
access_log /data/deploy/sxt/logs/sxt-test.access.log ;
error_log /data/deploy/sxt/logs/sxt-test.error.log;
location /api {
proxy_pass http://localhost:8666/api;
client_max_body_size 1000m;
proxy_set_header Cookie $http_cookie;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
}
location /zuul/api {
proxy_pass http://localhost:8666/zuul/api;
client_max_body_size 1000m;
proxy_set_header Cookie $http_cookie;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
}
location / {
root /data/deploy/sxt/html;
client_max_body_size 1000m;
index index.html index.htm;
}
location = /50x.html {
root html;
}
location = /40x.html {
root html;
}
}
}
其中server块对应了一个服务块,listen监听端口,比如:浏览器输入ip:8002/ 则会自动匹配到location /块中,加载root目录下的index.html页面,页面上操作请求路径会匹配相应路由,比如:以/api开头的路径都会进入到location /api块中,并将路径替代为proxy_pass指代的路径,如图,会将.../api/..替换为请求http://localhost:8666/api/..对应的具体路径。此时转发的路径即为微服务网关路径,具体网关路由策略及运转参看API Zuul的相关文章。