i007.cc

i007.cc

优先队列-降维打击

OpenResty 究竟解决了什么痛点?

原文地址

 

比如 MySQL 卡,就算 OpenResty 极其快,对打开浏览器的用户来说,迟迟看不到从数据库获取的信息,页面一片空白,他们认为也是卡,跟没有用 OpenResty 不是一样吗?

所以它到底解决了什么痛点?

关注者

217

被浏览

72,725

12 个回答

OpenResty解决的是高并发的痛点。现在服务的后台大部分是java写的,但是用java写出稳定的高并发服务是很复杂的一件事,首先是服务器的选择,web服务器有几个选型,tomcat,apache,weblogic,还有商用webphere. 1、tomcat官方宣称的并发量是1000,厉害点的做点参数调优,也不过3000并发,如果要开发一个并发百万的服务,1000000/3000,需要1000台服务器,想想都不可能。 2、apache的并发比tomcat更不堪,200-300 3、weblogic的并发稍好,平均能达到3000左右,但是也没有达到好一个数量级

但是nginx就不一样了,处理几万的请求很轻松,内存占用也不高,之前我们只是把它用作负载均衡,没想过当做一个web服务器,OpenResty的出现解决了享受nginx高并发优势的拦路虎,因为nginx是使用异步 事件模型,跟传统的编程思想不一样,而lua是用c解释执行的脚本语言(执行效率很高),可以用传统的同步编程思想上,在nginx请求接进来后处理稍复杂的逻辑。

对于高并发的系统来说,都是基于内存的,或者说是基于缓存的,题主说的用mysql支撑高并发是不现实的,mysql的并发量在4000-8000,超过这个量mysql性能就会急剧下降。一次内存读取的时间是几十纳秒,一次缓存读取是几毫秒,大家可能对纳秒比较陌生,一纳秒等于1秒的1000000000分之一,一毫秒等于1秒的1000分之一,请求过来之后直接走内存读取,在需要和数据库交互的时候把数据写入内存,然后再批量入库,快速响应。

web流量也符合二八原则,百分之八十的流量集中在百分之二十的页面,比如电商的首页,产品详情页,使用openResty支撑产品详情页的高并发访问,在处理订购单,购物车等环节用其他的高并发框架处理,比如java的NIO网络框架netty。

java的netty也是处理高并发的利器,不过我做过测试,整体性能可以达到nginx的80%,所以,脏活累活都让nginx做吧,关键业务用netty。

当然,每个人对高并发的理解可能不太一样,有人说1000并发就是高并发了,有人说1万的并发才是高并发,有人说并发百万才是高并发,OpenResty是可以做到百万并发的(当然需要各种调优),现在大部分业务OpenResty都可以胜任,但是像腾讯10亿用户,1亿的并发,OpenResty就搞不定了。

不同的并发量要应对的东西不一样,比如1000并发,用tomcat,springmvc框架加缓存就可以应对,1万的并发在关键节点使用内存处理也很容易,百万并发就需要linux内核调优,socket缓冲区,文件句柄数,内存池,RPS/RFS SMP等优化也可以达到。千万并发就需要考虑用户态协议dpdk了

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

泻药

先声明:我没用过openresty,我猜测它是一个类似vert.x一样的异步框架,只不过它只支持lua,在techempower上可以看到这两个性能极为接近,但是我个人看好在round 15中vert.x可以超出,因为最新3.5.1的版本中对http和json均做出了改进,以优化性能

扯远,如果我的猜测没有错的话

那我可以回答楼主的问题,就是如果mysql卡,openresty再快,也不能解决问题

u r absolutely right

所以我们在讨论vert.x的时候也强调过,思维要跟上,如果你用vert.x等先进的工具

后面拖着的还是mysql的话,意义不是特别大,因为mysql等db会让系统整个速度慢下来

木桶原理,一个系统的throughput取决于这个系统中吞吐最小的那个环节

所以一开始你应该先加上ap系统,e.g. cassandra, couchbase/couchdb等 以降低rdbms的负载

就算你无法全部替换掉rdbms,你也应该加上ap系统以减少db负载,增加吞吐

至少你也应该换上postgresql,替换掉mysql,以提升性能

vert.x为了提供更好的性能,除了提供jdbc client以外

还针对mysql&pg的异步api提供了一个async client,甚至针对pg,还提供了专门的pg client

因为mysql的有些操作,比如batch,不如pg

然后呢,你应该尽量减少事务/transaction,join等消耗性能的操作,以提升吞吐

参考facebook最早用mysql的方式

那一种极端的情况,你想一下,是不是所有的系统都需要db?

可不是所有的系统都需要db的哦,我们也可以用file system来替代db哦

只要我们能实现persistence的功能不就好了?只是file system没有提供事务,sql引擎等功能

那对于一些简单应用,尤其是互联网应用,file system是不是就足够了呢?

嗯,你可以考虑hdfs,vert.x自己也提供了一个file system,我们就在使用

最后,你有没想过有些系统是不需要存储的?

比如api gateway

不要让j2ee或者db这些古老的东西限制了你的想象力

系统不是一尘不变的,也不是所有系统都应该长那个模样的

系统设计是文学艺术一样的领域,可以充分发挥人的想象力和创造力的领域

我们从来都主张,程序员自己明白自己在做什么,就可以了

有什么问题,我们都可以探讨,但是千篇一律,只会让员工觉得不被尊重,像螺丝钉一样拧螺丝

这种工作根本看不到未来,员工只会觉得被疯狂剥削,痛苦不堪,最后士气低落

进而影响到企业的创造力和创新能力

嗯,扯远了

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

OpenResty 是快,但是MySQL卡了,你换什么都是卡的,这和你用哪个技术栈没有关系,我个人认为好的几点的是:

  1. 做网关,比如说 ngx-waf,从较高的位置处理了安全问题
  2. 高并发,异步非阻塞,的项目需求(甚至说你的MySQL卡,如果你用 ngx.timer.at 来实现异步写库,用户的请求完全可以不受 MySQL 卡的影响,当然 mysql 响应慢,积累太多连接不释放导致系统出问题就是另一回事了 )
  3. 对其他语言的兼容,可以直接在 lua 中嵌入 C 来写,又或者 lua 结合 redis 使用

—————– 3月6日 面试被问了类似的问题,想起这个问题重写一下答案————-

从深入角度来说,这里的 openresty 是基于 nginx 增加了模块,我们说的其实也就是 nginx 的性能,而 nginx 是异步非阻塞的,基于事件驱动的 server,相比其他的 server 在卡主的时候他为什么不卡?

就拿你的问题来说,mysql 卡了,这条请求的上下文会被卡在这里,不管是 nginx 还是 apache,都会卡住这条请求,但是问题关键还在于后续的请求进来后会怎么办

apache 的做法是开启一个新的进程来处理后续的请求,但系统进程资源是有限的,所以面对大量请求时,进程耗尽,apache 就会把所有后续的请求都卡住了。

nginx 只有一个master进程和已配置个数的 worker进程,master 进程把请求交给 worker 去处理,一个worker 在可能出现阻塞的地方会注册一个事件就放过去了(epoll模型),而不是干巴巴的等待阻塞被处理完,他会继续处理后续的请求(非阻塞),当这个事件处理完之后会通过callback来通知worker继续处理那条请求后续的事情(事件驱动)因此单个worker可以处理大量请求而不会轻易让整个系统卡住。

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

openresty本身是集成了lua组件的nginx,等于是把一部分后端服务的功能用lua集成到反向代理里面了。和mysql慢有个毛关系啊。数据库慢,你需要加缓存,拆分,看你哪个业务逻辑拖慢了整体的返回速度。业务逻辑复杂,拆域,中间层聚合,很多手段可以用。超时还可以用nginx上的静态持久化页面返回。

lvs -> nginx -> server -> database,后端哪一个环节慢,都不是反向代理应该解决的事情,你没搞懂痛点在哪里。

实名反对圆胖肿的答案。一点常识,永远不要觉得你比数据库厂家更懂文件系统。直接写文件系统,灾备,数据丢失,回滚都自己做吗?Linux上次爆出的ext4数据丢失的bug忘了?

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

异步提高了服务器整体负载能力,而不是提高某个请求的速度。

而openresty可以用写同步的方式写异步,简化开发。

更新下这个答案:

多任务程序分成两种:

一种是并行,指的是把一个大型任务拆分成N个小任务,把这些小任务分派个N个WORKER(线程,服务器)来执行,最后再组合起来,输出结果,这种是为了提升单次任务的执行时间。

另一种是并发,主要目标是在同一个CPU上执行几个松耦合合的任务,充分利用CPU的核,让其足够忙碌,从而最大化程序的吞吐量,那么真正要做的是避免因为等待远程服务的返回,或者对数据库的查询,而阻塞线程的执行, 浪费宝贵的计算资源,因为这种等待的时间很可能相当长(摘自JAVA8实战)。

异步是第二种并发的一种实现方案,OpenResty通过把nginx的事件驱动机制与lua的协程相结合,实现了cosocket这种东西,把异步实现做了一个封装。使用cosocket,开发者就不需要考虑异步如何实现,同样用同步的编程方式,就可以完成异步请求MySQL,Redis以及各种网络服务,从而达到增大服务器吞吐量的目的。

当然,lua语言本身比较小巧,相对来讲处理单次请求的效率也会更高,但这个我认为不算是OpenResty一个非常重要的优势,毕竟对于网络服务来讲单次请求的延时,瓶颈往往还是在数据库

 

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

openresty解决的痛点是,nginx模块开发使用lua规范方便,不用C去开发,不需要特别熟悉nginx源码,可以很方便的开发出适合自己业务的高性能web Server模块,他也自带MySQL,redis,memcached等模块,再说到你说的数据上,那你把MySQL查询的数据放memcached,浏览器获取数据不就快了么

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

首先就单个请求而言,

单次请求响应时间是网络 + http服务器 + http到后端通信 + 后端 + 后端到数据库通信 + 数据库

那么现在openresty直接消除了第三项,第四项明显减少,整个响应时间是改善的,正因为有这个改善你才能问得出来这个问题。

不然,

“比如mysql卡,就算fastcgi极其快,跟cgi不是一样的吗?”

就多个请求而言,openresty降低了整个服务器和单次请求的footprint,使得服务器能承载更多的请求(直到把数据库撑死)。

你总不能说“反正数据库是瓶颈,我前面的东西放着快的不用用慢的也没有关系”吧。

另外某个人说“换成postgre以提高性能”,不好意思,postgre的优势在于功能和灵活性,论性能,mysql是稍好的。

“用文件系统代替数据库”,不好意思,你读写文件是自己实现缓存吗?下mysql自己测性能去谢谢。

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

我们通常所说的openresty快,是站在同一个”层“的概念去说的。

db属于被语言调用的下一个”层“,并不能放在一起讨论。

我们说PHP7 比PHP5速度提升了xx倍,但这种提升在数据库设计稀烂的情况下,同样没有颠覆性的现实意义。

我推荐所有正在使用nginx的普通用户可以考虑,使用openresty替代nginx,即使你现在的解决方案并不能用到openresty的任何一个功能。

做项目,不能只考虑眼前,当你业务发展到一定量的时候,一定会面临到安全,网关,反爬,日志,代理,高定制的负载均衡,限频,等一系列问题,当需要处理这些问题的时候,openresty就是一把利刃。另外openresty 实现一些高并发但逻辑不复杂的业务也是非常优秀的。复杂业务,由于lua语言的关系,开发难度会比较高(当然也可能只是对我来说,因为我比较菜)。

想多聊聊MySQL,时至今日, MySQL 依旧是一个优秀的关系型数据库。能够解决国内绝大部分中小公司的需求,和头部公司的超过一半以上的业务需求。 但经常有面试到的同学上来就聊,MySQL稀烂,一问他们的业务量,我就会心里嘀咕:不该啊, 再深入问下去,并不是MySQL稀烂,

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

解决了API网关能解决的痛点,再加上一定的编程能力。不过如果要我来选的话,我会用node来做类似的事情。毕竟JS的生态比lua好上太多

 

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

真没觉得解决啥痛点,lua本身就支持集成到nginx,这个步骤也没多费事

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

用脚本写出C的性能:

主要是 luajit , luajit 用的好性能基本接近 c ,相当于你在用 nginx 的 c 模块写网站

但这只是代码执行的性能,并不代表MySQL能被它拉快。

继续浏览内容
知乎
发现更大的世界
打开
Chrome
继续

只能说当初解决了nginx不可编程的问题,所以给nginx加了个lua jit,而且前人基于openRsety做了不少的库,所以能在nginx更方便方便编程,就这点解决了不少人的痛点。

虽然nginx官方后来也推出nginScript,但是它官方推动的不好,或者说它的库还远远不够用,导致nginScript的基础设施建设就没赶上openResty,但确实给人似乎多了一种选择。

当然就我个人而言,我更倾向于自己造轮子和跟喜欢不添加色素原生的东西,我更愿意用nginScript而非openResty。

发表回复