记录Nginx搭建网关服务

1、业务背景分析
前一段时间,须要开发一套业务系统,此系统须要对外统一提供api服务,但这些服务在内部是由多个业务子系统分别提供。
通过分析,此业务系统须要具备如下这么几个特性


一、不一样的api服务由不一样的子系统负责
二、每个服务之间是相互独立的
三、每个服务都须要支持横向扩展和负载均衡
四、每个服务都须要高可用


这么一分析,咱们发现这里须要一个api网关,这个api网关须要具备如下几个特色:
一、api服务器自注册,须要知足如下两个特色(固然也能够由运维在api网关管理平台上进行管理,此部分不影响本文的技术探讨,这里不进行详细的描述)
   1)新增一个服务时,api服务器能够将相应的服务自注册到api网关上
   2)某服务新增一个服务器或删除一个服务器时,api服务器能够在进行自注销或自注册
二、api网关须要支持对同一个服务子系统的多个服务器进行负载均衡
三、api网关须要支持对同一个服务子系统的多个服务器中的故障服务器进行检测和切换,也就是高可用
四、api网关系统自己须要支持横向扩展


2、方案的选择
对于任何团队来说,方案不必定是本身开发的就是最好的(牛A和牛C之间的技术团队除外),须要综合考虑各类因素,这个API网关也不例外,中间经历了一点曲折,过程以下:


一、系统是部署在云上面的(具体的云这里就不透露了),本来想着看这个云服务端是否有提供此功能服务,不过遗憾的是此云未提供此服务(好像亚马逊云有提供,没有用过不知道怎么样)
二、使用开源的方案,在开源方案上找到了一个叫kong的方案,此方案是基于nginx的反向代理开发的一套方案,通过调研,此套方案不支持负载均衡和高可用方案(固然不是很深刻的调研),此方案自己是基于nginx的lua扩展模块进行开发的,对于api网关的配置是使用cassandra数据库进行存储,对于团队的技术背景来讲,这个不是那么合适。(ps:团队自己还不是很强大,业务工做量比较多,整个团队对lua和cassandra没什么积累,在这个场合下除非此方案能直接用,而且有较多的资料,不然只能舍弃掉)php

三、自主开发一套,通过对各服务子系统的接口分析,发现直接使用nginx的反向代理和负载均衡来实现也不是那么复杂,因此这个方案这么诞生了nginx

 

3、使用nginx做为api网关的调研
对于nginx的反向代理和负载均衡的资料网上已经有不少,这里就不废话了,直接看调研过程
这里假设nginx的配置文件目录为/etc/nginx/
一、配置的考虑
  考虑到nginx的配置文件大小有要求,因此在这里不把配置直接写入到nginx.conf,而是在nginx.conf里面去include其余目录,好比
  在/etc/nginx/目录下新建api_servers.d目录和api_rules.d目录,分别用来存放api服务器的相关配置和api服务代理规则的相关配置,在http配置项中增长一行配置include /etc/nginx/api_servers.d/*.conf;
  在提供网关服务的server中增长一行include /etc/nginx/api_rules.d/*.conf;


二、配置负载均衡和反向代理
   在/etc/nginx/api_servers.d/目录下新增一个文件api_test_servers.conf,内容以下
   upstream api_testa_server {
       server 192.168.1.101:80 weight=1 max_fails=3 fail_timeout=20;
       server 192.168.1.102:80 weight=1 max_fails=3 fail_timeout=20;
       server 192.168.1.103:80 weight=2 max_fails=3 fail_timeout=20;
   }


   upstream api_testb_server {
       server 192.168.1.104:80 weight=1 max_fails=3 fail_timeout=20;
       server 192.168.1.105:80 weight=1 max_fails=3 fail_timeout=20;
   }


   在/etc/nginx/api_rules.d/目录下新增一个文件api_test_rule.conf(这里以简单的url匹配来举例)
   location ~(^\/ws\/apitesta)(.*) {
       proxy_set_header Host $host:$server_port;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_buffering off;#缓存在其余文章中会讨论,在这里暂只讨论基本的功能,因此直接使用off
       proxy_pass http://api_testa_server;
   }
   
   location ~(^\/ws\/apitestb)(.*) {
       proxy_set_header Host $host:$server_port;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_buffering off;
       proxy_pass http://api_testb_server;
   }
  nginx服务reload使配置生效


三、测试过程
 nginx服务器的地址是192.168.1.100,服务的端口为80端口,测试过程以下
1)、 执行wget http://192.168.1.100/ws/apitesta/phpinfo和wget http://192.168.1.100/ws/apitestb/phpinfo
分别重复执行此命令20次,查看192.168.1.101-105这5台web服务器的web访问日志,发现101-103的/ws/apitesta/phpinfo访问量分别为五、五、10,104和105的web访问日志里面对/ws/apitestb/phpinfo的访问量都是10次
2)、 关闭192.168.1.102和192.168.1.104,重复上述测试过程,发现两个url都可正常访问


4、网关的搭建
从上述的调研结果来看,使用nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用,那么咱们须要解决的就是自注册的问题和网关自己的扩展性。
对于自注册和自注销这个问题,对于咱们的业务系统来讲,业务的上线与下线自己不是一个特别频繁的事情,因此直接在api网关上搭建一个简单的web服务便可,咱们称之为api网关系统,api网关系统基本功能以下:
一、注册或注销时须要从新生成nginx的反向代理和负载均衡配置文件(也就是上述的api_rules.d和api_servers.d目录下的文件),而且网关服务器须要对nginx执行reload操做
二、须要对api服务的相关信息作持久化存储
除了上述两个基本功能还须要网关自己支持横向扩展,这个仔细分析一下无非就是须要如下两个问题
一、在任一个网关服务器上注册或注销一个api服务或一个api服务的一个服务器时都须要通知到全部的网关服务器,全部的网关服务器都须要从新生成配置而且reload各自的nginx服务,显然的咱们想到了消息队列里面的topic消息(消息队列的高可用等特性在这里不进行特别延伸),全部的api网关服务器共用同一个消息队列便可知足此要求
二、全部的网关服务器须要共同同一个网关配置信息,这个无非是共用一个数据库(数据库的高可用等特性在这里不进行特别延伸)


api服务器自注册至生效主要流程以下:web

全部的网关服务器共用一个消息队列,共用同一个存储数据库,各网关服务器上的网关信号处理进程向消息队列订阅相关的消息,当api服务器向网关服务器集群中的某一台服务器进行注册时,全部的网关服务器都会收到reload消息,会从同一个数据库中读取同一个配置,而后从新生成nginx反向代理和负载均衡的相关配置文件,接着reload各自的nginx服务,固然这里面的网关信号处理进程启动时也会从新生成相关的配置。数据库

至此一个基于nginx的API网关完成了,此文转载了大牛的日志,仅此本身记录学习api

相关文章
相关标签/搜索