关于公司引入网关组件的提议

3,196 阅读12分钟

关于公司引入网关组件的提议

Hello,大家好,很久没有写博客了,上年纪了,确实老了,有时突然想写点什么又感觉没什么干货,就又放弃了,这次的话本来是准备在公司内网论坛来写这边博客(提议书),后来的话想了想,也算是自己对网关这一块的一个沉淀,索性就放在了外网,好了,废话不多说,先说一下背景,去年我司做了一次比较大的改造,把单体项目拆开成了各个子系统,兼着Dubbo的使用,勉强的算是微服务架构了,其实说微服务架构,确实很牵强。作者第一次做微服务架构还是15年,不知不觉4年过了。现在再提微服务,就是炒冷饭了。微服务本身确实技术含量不高。今天的话主要不是来讲微服务,还是和大家分享一下,我目前想在公司推行的组件-网关!网关的作用我就不叽叽歪歪了,大家自行google,其实作为架构师的而讲,盲目的追风,一味的追求技术名词是大忌。学技术不是学名词,而是学架构哲学。好了,不叽歪,直接上文章结构:

  1. 公司现有架构
  2. 现有架构存在的问题
  3. 网关作用
  4. 现有网关的几大派
  5. Kong

1 . 公司现有架构

简单说下公司业务背景,我司是深圳一家一线互联网公司(原谅我这可耻的"一线"一词),专做电子元器件采购网上商城,是一家To B 端的电商网站,根据业务的特性,前台网站拆分成了首页,详情页,列表页,搜索页等多个子系统,也就是大家说的微服务。然后简单说下流量的入口架构。由于这里可能涉及到公司隐私问题,所以部分组件用某组件代替:

介绍: 其实很简单,流量通过DNS解析后,会再流入一些安全组件和SLB组件,然后走向三个Nginx,Nginx把流量导向Tomcat层,后面的持久化层我就不画了,因为不是本文的重点。公司分为很多子项目,像上文说的,订单系统,购物车系统,每个系统的架构都如此,当然了,有些Nginx是共用的。也就是说,可能有A,B,C,D,E5个系统,AB系统的流量走向共用的三个Nginx,其他的都是单独的Nginx集群,核心业务一般是单独的三个集群,不是很重要的业务就可以共用Nginx.这也是大部分公司的常规做法。

一切看上去似乎很完美.......

2. 现有架构存在的问题

相信大部分小伙伴看到上面的架构后,有种似曾相似的感觉,因为业界来讲,做的微服务架构,大部分都是这样的。把项目拆开,系统间的通讯走个RPC,用一套服务管理平台,然后就是微服务了。其实我个人来讲,真心不觉得这是微服务来着,我最早在北京某家公司就是差不多这么一套架构,RPC通讯用的大家都比较熟悉的Dubbo,后来又一家公司用的Spring Cloud大礼包,个人来讲,对微服务还是有一点理解。但这里不纠结微服务的问题,还是回归到架构本身问题上。我这里先大致说一些这套流量入口存在的一些问题 :

2.1 配置分散,节点间无法通讯,运维难以维护。

大家都知道,Nginx节点与节点之间是没有通讯的,都是无状态的。也就是说,假如有Nginx三个节点,A,B,C,分别路由到编号1,2,3的三个Tomcat上,现在想临时加一个编号为4的Tomcat,那运维估计有打人的冲动。因为要分别到三个节点上去改配置,然后"nginx -s reload",大家想一想,每个项目都是这种架构,nginx的数量也是一个非常大的问题,部署问题,改配置问题。

再比如一些公共的插件,比如nginx的限流module,或者一些鉴权module,如JWT,OAUTH2等,这些如果有变更,分别更改多台机器上的配置,这无疑是场灾难。。。

2.2 nginx原生不支持dlb

这个上面其实也提到了,Nginx是没有动态负载均衡的功能的,改完配置需要重启nginx,这对流量密度非常高的公司,是无法接受的。(当然这一点也有很多很好的方案来支持Nginx的动态lb,大家可以自行google,像与Consul结合等...)

2.3 无法动态切流量权重(金丝雀发布,AB发布等)

其实也很好理解。比如现在Nginx后挂了3个Tomcat节点,其中一点节点想做AB升级,升级到新版本,要临时把流量切掉,Nginx是无法支持动态的更改流量权重的。需要改配置文件后重启。

2.4 没有暴露API供监控系统和运维人员使用

一个好的组件需要对外暴露出很多内部的指标,但对于Nginx来说,是不能暴露出当前有多少个upstream,当前哪些上游服务(如Tomcat)有问题,当前的具体配置等等....相当于是黑盒使用。这是很让人头疼的一件事。更别提暴露API动态更改配置,更改路由信息了...

2.5 没有服务发现功能

暂时不讲。

2.6 动态可扩展性

讲实话,Nginx的可扩展性还是有的,module的形式,但不支持动态的插拔,也让人很头疼。比如写了一个限流的插件,想动态的调整限流力度。无法做到。

看到上面这些,大家可能会说了,节点多的问题,多几个运维就OK了,这些动态调配的功能,我不需要,我每次写好脚本重启即可。说实话,确实是这样,这也是为什么大部分中小型公司不需要网关的原因,因为不是刚需。大部分的公司可能把所有项目的流量全部接入到几个Nginx上,通过Nginx来转发到业务Tomcat上,这种架构,对于中小型公司来讲,毫无问题!但如果想做一个接入层管理平台,或者网关平台。仅仅使用Nginx,是远远不够的。下面再给大家画一副图,看看理想中的网关平台是怎样的: (下图省掉一些无关组件,不代表实际架构如此,抓住重点即可)

大家可以看到,把所有商城的接入层Nginx全部抽取成一套网关集群。所有流量都从这里走。那么问题来了,这个网关平台和Nginx集群到底有什么不同呢?看下图:

其实说白了,我是想定制化一套平台,解决上面的诸多问题。现在一一对应上来解答:

2.1【 配置分散,节点间无法通讯,运维难以维护。】

这个就不用说了,因为我们抽取出了一组GateWay集群,又有管理平台,所以只要在平台上配置,无需登陆到各个节点去进行配置。以后我们的运维同学就可以到GateWay管理平台上配置类似于这样的数据:

项目 下游节点 权重 心跳检测URL 节点状态 操作
订单系统 192.168.157.123:8888 50 / 存活 -
订单系统 192.168.157.124:8888 100 /test 死亡 -
订单系统 192.168.157.125:8888 100 /test1 存活 -

当想为订单系统添加一个节点的时候,只需要在管理平台上新加一下,当想人工摘掉一个节点的时候,也是一样的在UI平台操作。总之,把运维培养成傻子,什么都不用干,只需要在平台上配置即可。

2.2【 nginx原生不支持dlb】

这个就更不用说了,我们的GateWay平台肯定是要支持动态的lb功能的,也就是说,在平台上配置好,立即生效,无需重启组件!

2.3 【 无法动态切流量权重(金丝雀发布,AB发布等)】

同理,如果想做一些流量的切换,只需要对权重进行操作即可。也是动态生效的。

2.4 【没有暴露API供监控系统和运维人员使用】

我们的网关管理平台就是根据网关集群暴露的API来操作网关的。当然具备相关的监控API和操作API了。

2.5 【没有服务发现功能】

我们的网关集群必须具备这个功能,请求可以直接下发的微服务调用,无需走到Tomcat

2.6 【动态可扩展性】

这个其实也是一样的道理,我们的网关平台要支持动态配置插件,并且实时生效,并且动态的配置插件内容。

好了,大致想做出的效果也看到了,其实网关的作用远不止这些。后面会和大家细讲。大家思路一定要转换过来。就是说,我们要一个全局AOP的点,管理着所有API,让后面的服务专做自己该做的业务 。 其次就是,操作的便捷性,也就是我们常说的,把运维培养成傻子。。

3. 网关作用

网关作用其实就太多太多了,其实网关这个词是比较大的,很多搞技术的把网关分为接入层网关和服务网关,我觉得是非常正确的。每层网关的作用其实是不一样的。接入层的网关最核心的功能就是LB,然后就是建立的LB之上的一些延伸,比如说断路器,限流,请求聚合,协议转换等,而服务网关,毋庸置疑,其实是对微服务的一种代理,最核心的功能就是服务发现了。也就是常说的,面向服务调用,这样就把下游检测和微服务体系结合在一起了,这个后面和大家分享。

再有一些常见的功能比如说: 服务分组管控、灰度发布、熔断监控、容器化迁移、统一出入口管理,实现协议适配、协议转发、安全策略(WAF)、防刷、流量管控、日志监控,可以对流量进行灵活动态的管控,API网关也起到安全防护的功能,提供IP黑名单和URL黑名单 我这里就不一一列举了,其实说实话,我这边想在公司推行网关并不是因为其作用的多,而是想解决上面说的一些问题的,至于后面的功能,要慢慢接入,从无到有是非常重要的!

网关的稳定性建设十分重要。

网关的稳定性建设十分重要。

网关的稳定性建设十分重要。

4. 现有网关的几大派

最近做技术选型时,把几大网关做了下对比,这里稍微分享下,各大网关的选择,意见不一,选择自己适合的才是最重要的,我们选技术的时候,不在乎它的功能多不多,时尚不时尚,而是能不能解决现有的问题。

4.1 zuul 1.0 & zuul 2.0

zuul1 大家可能比较熟悉,随着Spring Cloud对zuul1的支持,大家都纷纷使用,我这里就不画图了,直接画重点:

  1. zuul1 目前都结合Spring Cloud大礼包使用,具有服务发现功能,由于整合了Eureka,所以节点的自动上下架支持的非常好!
  2. zuul1属于线程池模型,不能支持高吞吐量,当后端服务有问题了,需要做断路器 。
  3. 我司需求: 不需要具备服务发现功能,但节点的自动上下架必须有。如果用原生的zuul1确实可以达到节点路由,但需要自己做断路器。只有与Spring Cloud结合时,才有支持好的断路器使用。

zuul2 :

  1. NIO模型,性能高(没有官方数据,业界测试结果不理想)
  2. 接入APM监控系统困难
  3. 学习成本高

4.2 Spring Cloud GateWay

Spring Cloud GateWay :

  1. NIO模型,使用WebFlux,与Spring Cloud大礼包结合,自动服务发现。
  2. 业界测试结果不理想
  3. 组件较新

4.3 Nginx

Nginx派系的网关比较多,orange,kong还有一些基于openresty开发的就不一一列举了,Nginx派系的是我比较推荐的。

5. Kong

Kong的官方资料比较全,因为这份博客,主要还是对内的,所以这些知识准备口头讲。这里给大家丢一张功能图,基本上网关该有的功能都有了,没有的功能可以通过plugin动态扩展:

总结

好了,算了大致写完了,其实写的很草率,前面主要讲了想引入网关的原因,后面组件对比的话稍微写了下自己的一些看法,我这里给大家的建议是,大家如果使用的是Spring Cloud生态系,使用zuul1 和Spring Cloud GateWay是比较不错的。鉴于我司不是微服务架构体系,所以我这里还是选择了一个比较纯正的API网关Kong,Kong的官方资料非常详细,使用起来非常潇洒。是一个我非常喜欢的组件,大家感兴趣可以自行学习。

TODO :

  • 动态降级(需接入监控平台),人工降级。
  • 动态限流规则
  • etc ... 凡是能在网关里做的事,全部可以做成平台化配置的东西。当然了,一些高频功能做。低频的再考虑。