文章目录
相信一些老程序员都经过没有网关的日子,不使用网关时,会有很多问题:
1、前后端分离,页面会对接很多域(微服务),客户端处理的复杂性很高;
2、存在安全隐患,随着微服务暴露接口的增加,服务器的受攻击面积也会增加;
3、重复鉴权;服务鉴权功能分布在每个微服务中处理,客户端对于每个服务的提供者都需要重复鉴权;
4、客户端需要针对不同的请求协议做适配:因为在后端的微服务架构中,可能不同的服务采用的协议不同,比如:HTTP、RPC等;客户端调用多个服务时,需要对不同的协议进行适配;
5、跨域问题;
6、客户端难以重构,因为微服务是动态拆分的,域名会改变;
针对没有网关时的缺点,微服务网关的诞生恰恰是解决这些问题的;
提供统一的
访问入口,类似于门面,所有的请求都会先经过网关这一层,降低了服务器的受攻击面积;不管微服务怎么拆分,域名都不会变;也降低了客户端重构的难度。提供统一的
跨域问题解决方案;提供统一的
日志记录操作,进行用户打点,做用户画像,进行统一的监控;提供
统一的协议:如果后端微服务使用的协议不同,或存在一些对前端不友好的协议,可以在网关中转换为浏览器友好的、统一的协议。
认证授权;黑白名单机制,做路由转发。
限流,保护微服务;
整合微服务:API网关层可以把后端的多个服务进行整合,提供统一的业务接口,形成若干套业务系统。
请求转发:可以根据不同的请求路径pattern,进行请求的转发,并且可以基于网关实现内网 和 外网的隔离。外网采用HTTP提供服务,内网之间使用RPC通信(RPC通信更快)。
网关大体上分为两类:独立网关和业务网关;
独立网关:像nginx、Kong、Trsefik属于独立网关,不关注业务代码;
业务网关:像Zuul、Gateway属于业务网关,他们在意业务代码的实现语言;
服务网关是所有微服务的唯一入口,在做技术选型时,网关组件应该具备的特性:
1、高可用:保证
7 * 24 小时可用,提供提供稳定可靠的服务;2、高性能;所有的请求都会经过服务网关,它要承受的压力是很大的,所以它必须具备良好的性能,以
应对高并发请求。3、高安全性:要能
防止外部的恶意访问,确保内网各个微服务的安全。4、高可扩展性:服务网关是一个非业务的模块,除了要提供流量管控、路由转发、日志监控、认证鉴权等能力;同时要对以后
非业务功能的扩展提供良好的兼容性。
现在的一些网关技术:traefix、Nginx、OpenResty、Kong、Zuul、Spring Cloud Gateway等。

官网地址:https://www.traefik.tech/。
Traefik 是⼀款开源的边缘路由器,可让我们轻松地发布服务;traefik 与众不同的点在于它能够⾃动发现适合服务的配置;并发现哪个服务应该服务于哪个请求;其⽆需维护和同步配置⽂件:所有操作都会⾃动实时完成(⽆重启,不⽤中断服务);我们只需花时间于系统开发和部署新功能,⽽不需要配置和维护其⼯作状态。
另外:Traefik ⽀持多种集群技术,如 Kubernetes,Kubernetes, Docker, Docker Swarm, AWS, Mesos, Marathon,⽀持列表 ; 并且可以同时处理多个 providers。(它甚⾄适⽤于在裸机上运⾏的传统软件。)所以它主要用于云原生中。

官网地址:http://nginx.org/en/
Nginx是⼀款轻量级的Web服务器、反向代理服务器,由于它的内存占⽤少,启动极快,⾼并发能⼒强,在互联⽹项⽬中⼴泛应⽤。一般Nginx的上层还有一个负载均衡器,如LVS,对Nginx做负载均衡。
特点:
1、Nginx以事件驱动的⽅式编写,所以有⾮常好的性能;
2、在性能上,Nginx占⽤很少的系统资源,能⽀持更多的并发连接,达到更⾼的访问效率;
3、在功能上,Nginx是优秀的代理服务器和负载均衡服务器;
4、在安装配置上,Nginx安装简单、配置灵活;
5、Nginx支持热部署,启动速度特别快,可以在不间断服务的情况下对软件版本或配置进行升级; nginx -s reload。
在微服务的体系之下,Nginx被越来越多的项目所采用,作为网关来使用,配合Lua做限流、熔断等控制。
此外,Nginx可以用来做正向代理、反向代理;
正向代理:
1、正向代理
“代理”的是客户端,客户端知道⽬标,⽽⽬标不知道客户端是通过VPN访问的;2、由于防⽕墙的原因,我们并不能直接访问⾕歌,那么我们可以借助VPN来实现。
反向代理:
1、反向代理
“代理”的是服务器端,这⼀个过程对于客户端⽽⾔是透明的;
2、当我们在外⽹访问google的时候,google会进⾏⼀个转发,代理到他们内⽹去,这就是所谓的反向代理;

官网地址:https://openresty.org/cn/;
OpenResty 是⼀个基于 Nginx 与 Lua 的⾼性能 Web 平台,其内部集成了⼤量的 Lua 库、第三⽅模块。⽤于⽅便地搭建能够处理超⾼并发、扩展性极⾼的动态 Web 应⽤、Web 服务和动态⽹关;快速构造出⾜以胜任 10K 乃⾄ 1000K 以上单机并发连接的⾼性能 Web 应⽤系统。
OpenResty 的⽬标是让我们的Web服务直接跑在 Nginx 服务内部,充分利⽤ Nginx 的⾮阻塞 I/O 模型;不仅仅对HTTP 客户端请求,甚⾄于对远程后端(诸如 MySQL、PostgreSQL、Memcached、Redis等)都能进⾏⼀致的⾼性能响应。
本质上就是将Lua脚本嵌入到Nginx中,在每个nginx的进程中都嵌入一个LuaJIT虚拟机来执行Lua脚本;
- 在接收客户端请求时,通过在不同的阶段挂载不同的Lua脚本,实现拦截请求进行前置/后置处理;
- OpenResty实现网关功能的核心就是在
11个步骤中挂载不同的Lua脚本实现功能的扩展。
特点:

Kong是⼀款基于OpenResty(Nginx + Lua模块)编写的⾼可⽤、易扩展、开源的API Gateway。Kong基于NGINX和Apache Cassandra / PostgreSQL构建,提供提供易于使⽤的RESTful API来操作和配置API管理系统;它可以⽔平扩展多个Kong服务器,通过前置的负载均衡配置把请求均匀地分发到各个Server,来应对⼤批量的⽹络请求。
Kong的三大组件
Kong采⽤插件机制进⾏功能定制,插件集(可以是0或N个)在API请求响应循环的⽣命周期中被执⾏。插件使⽤Lua编写,⽬前已有⼏个基础功能:HTTP基本认证、密钥认证、CORS(Cross-Origin Resource Sharing,跨域资源共享)、TCP、UDP、⽂件⽇志、API请求限流、请求转发以及Nginx监控。
Nginx、OpenRestry、Kong这三个项⽬紧密相连:
Nginx是模块化设计的反向代理软件,C语⾔开发;
OpenResty是以Nginx为核⼼的Web开发平台,可以解析执⾏Lua脚本;
Kong是⼀个OpenResty应⽤,⼀个api gateway。
OpenResty与Lua的关系类似于Jvm与Java,不过OpenResty是基于nginx的,主要⽤于Web、API类应⽤。
Kong 和 Traefik 不依赖于后端服务的语⾔,是⽐较独⽴的⽹关服务,经常被⽤于云原⽣服务。
- 从开源社区活跃度、成熟度来看:Kong和Traefik都⽐较好;
- 从性能⻆度来看:Kong的性能要领先一些;
- 从状态存储来看:Traefik通过Kubernetes存储状态,Kong需要使⽤Postgres 或 Cassandra来存储状态;
所以如果应用是基于K8S来发布部署的,最好还是使⽤Traefik,会更⽅便⼀些。
而:Zuul 和 Spring Cloud Gateway 结合 Spring Cloud ⽣态 使⽤效果⽐较好,并且这两者和业务结合⽐较紧密。
Zuul作为微服务系统的⽹关组件,是从设备和⽹站到Netflix流应⽤程序后端的所有请求的前⻔,其旨在实现动态路由,监控,弹性和安全性。
Zuul的核心是由一些列的过滤器Filter组成,它定义了四种标准类型的过滤器,对应于请求的整个生命周期:

zuul有两个版本:zuul1和zuul2,⽬前spring cloud只集成了zuul1。zuul2是Netflix在2018年5⽉推出,它最⼤的特点就是⽀持异步调⽤ (而zuul1仅⽀持同步) ,不过可惜springcloud并没有计划集成zuul2,⽽且还推出springcloud gateway来替代zuul1。这也标志着zuul已经渐渐被Spring Cloud 抛弃,不建议使用了。
从编程模型上来看:Zuul1 同步阻塞编程模型简单,⻔槛低,开发运维⽅便,容易调试定位问题;Zuul2 异步非阻塞模型复杂,⻔槛⾼,调试不⽅便。
从埋点来看:Zuul1 监控埋点容易,⽐如和调⽤链监控⼯具 CAT 集成;而 Zuul2监控埋点困难,比如用就CAT 不好埋点;
从成熟度来看:Zuul1开源了很久,稳定成熟,坑基本被踩平;而Zuul2 2018年才开源,实际落地案例不多,可能有 bug 需要踩坑。
从请求量来看:Netflix 是要应对每⽇千亿级流量,如果公司连亿级都达不到,也没必要用Zuul2;
**Zuul的改进:**Zuul1可以使⽤ Servlet 3.0 规范⽀持的 AsyncServlet 进⾏优化,进而实现前端异步,⽀持更多的连接数,达到和 Zuul2 ⼀样的效果了;并且还不用引入太多异步复杂性
官网地址:https://spring.io/projects/spring-cloud-gateway#learn
SpringCloudGateway是由WebFlux+Netty+Reactor实现的响应式的API⽹关。
Spring Cloud Gateway旨在为微服务架构提供⼀种简单且有效的API路由管理⽅式,并基于Filter的⽅式提供⽹关的基本功能,例如说安全认证、监控、限流等等;
Spring Cloud Gateway定位于取代Netflix Zuul,成为SpringCloud⽣态系统的新⼀代⽹关;相⽐Zuul来说,SpringCloudGateway提供更优秀的性能,更强⼤的有功能。
Spring Cloud Gateway的几个核心概念:
网关通常作为微服务的门面统一请求的入口,以方便鉴权、协议匹配、整合微服务等操作;可用的网关技术包括两大类:
不关注业务代码的独立网关:像nginx、OpenResty、Kong、Traefik;
在意业务代码的实现语言的业务网关:像Zuul、Spring Cloud Gateway;
一般SpringCloud生态选择使用Spring Cloud Gateway;云原生中处于方便使用Traefik;对于很多不上微服务的项目,常使用nginx做多个实例的统一入口;对于一些需要在nginx中做定制功能的,往往选择Nginx + Lua脚本的方式,即OpenResty、Kong。
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚