当前位置: 首页 > 科技观察

API网关选择:我用的是OpenResty!

时间:2023-03-15 19:17:00 科技观察

今天想跟大家聊聊网关选择的话题。为什么我最终选择了OpenResty?图片来自抱图网互联网公司。无论大小,其内部技术架构基本相似,体现在以下几个方面:数据量太大,如何自定义存储和访问量大,如何集群部署,响应速度流量负载均衡慢,如何提高处理速度,引入多级缓存。如果机器多,如何保证某台服务器突然抽风不影响业务集群的服务稳定性。麻雀虽小,五脏俱全,但今天要说的网关,却是其中的关键一环。不管公司大小,基本都需要有这个系统。那么网关是做什么用的呢?什么是网关?网关是连接客户端和服务器的中间桥梁。它将很多通用的、非业务的逻辑分离出来,放在网关系统的前面,减少了很多重复的开发工作。它是整个网站的核心。独特的流量入口。为了提高系统的可扩展性,网关通常采用高内聚低耦合的组件架构。常用组件功能:黑名单拦截日志参数验证权限流负载均衡路由转发监控灰度分发多协议支持熔断、降级、重试、数据聚合等系统设计一般采用责任链设计模式,定义抽象interface,每个组件实现自己专属的功能,职责单一。并根据不同的业务请求API,增删部分节点,动态构建新的节点链,满足多样化的业务需求。网关选择目前比较常用的网关有以下几种:Tomcat/Jetty+NIO+Servlet3NginxSpringWebFluxSoulSpringcloudGatewayZuulOpenRestyKongNetty各个框架的自建资料网上基本都有。限于篇幅,这里就不一一分析了。每个框架的优点和缺点。我们打算选择OpenResty,原因如下:可以实现跨网络的gRPC请求转发,底层采用HTTP/2协议。支持SSL/TLS证书加密,通信安全。在性能方面,它支持更高的并发请求。低性能开销和低延迟。FlipOpenResty下图为Netcraft2021年10月最新Web服务器排行榜:Netcraft是一家总部位于英国巴斯的互联网服务公司,始于1995年,公司官网每月发布调查数据报告:WebServerSurveyseries,已成为服务器市场份额供人们了解当今全球网站。OpenResty现在世界排名第三,并且由于Nginx扩展为动态服务器而获得发展势头。我们常用的12306剩余票查询功能,京东的商品详情页,在这些高流量的背后,其实是OpenResty在提供服务。OpenResty最擅长部署在流量入口处,处理各种高并发流量。接下来,让我们更深入地了解一下框架。OpenResty的诞生,是因为Nginx采用master-worker进程模型,分工明确,职责单一,这也是其高性能的原因之一。①master进程对进程进行管理,处理指令如:-sreload,-sstop,并通过进程间通信将管理指令发送给worker进程,实现对worker进程的控制。②工作进程工作进程不断接收客户端的连接请求并进行处理。该数量通常设置为与CPU核心数一致,Nginx也会将每个进程绑定到每个CPU上,以充分利用其多核特性。多个工作进程会竞争共享锁,只有抢到锁的进程才能处理客户端的请求。如果请求是接受事件,则将其添加到接受队列;如果是读或写事件,则将其添加到读写队列中。可能有人会问,为什么OpenResty是基于Nginx框架的呢?主要原因是Nginx的高并发能力。反向代理服务器通常流量很大,不涉及复杂的计算。它们是I/O密集型服务。Nginx采用基于epoll机制的事件驱动,异步非阻塞,大大提高并发处理能力。但是Nginx是用C语言开发的,二次开发的门槛比较高。市场应用广泛,更多的是基于nginx.conf预留的配置参数,如:反向代理,负载均衡,静态web服务器等,如果要让Nginx访问MySQL,定制难度很大并开发一些业务逻辑。OpenResty通过嫁接将Nginx和Lua脚本结合起来,既保留了Nginx的高并发优势,又具备脚本语言的开发效率,大大降低了开发门槛。Lua是最快的,运行速度接近C的动态脚本语言。LuaJIT预编译并缓存了一些常用的lua函数和工具库,下次调用时直接使用缓存的字节码,速度非常快。另外,Lua支持协程,这点很重要。协程是用户态的操作。上下文切换不需要涉及内核态,系统资源开销小。另外协程占用内存小,初始2KB。OpenResty核心架构OpenResty是一个基于Nginx的Web平台,内嵌了一个LuaJIT虚拟机来运行Lua脚本。使用Lua编程语言编写Nginx核心以及各种NginxC模块的脚本。如上图所示:每收到一个客户端请求,就会有一个worker进程跟进,通过抢占锁的方式进行处理。worker内部会创建一个lua协程来绑定请求,也就是说一个请求对应一个lua协程。lua协程通过网络发送请求,并向nginx添加event事件。然后,当前协程处于yield状态,放弃CPU控制权。当服务器响应数据时,网络进程会创建一个新的event事件,唤醒之前的协程,并返回结果。注意:不同lua协程之间的数据隔离保证了不同客户端的请求不会互相影响。此外,一次只有一个协程在一个worker中运行。cosocket结合了Lua协程+Nginx事件通知两个重要特性。cosocket是OpenResty世界中最具技术性和实用性的部分。它使我们能够以极低的成本、优雅的姿态进行网络编程,并且比传统的socket编程效率高出数倍。无论资源占用、执行效率、并发能力都非常优秀。为了方便开发,OpenResty将一次HTTP请求分为11个阶段,每个阶段都有自己专属的职责。函数说明:set_by_lua,用于设置变量。rewrite_by_lua,用于转发,重定向等access_by_lua,用于访问,权限等content_by_lua,用于生成返回内容。balancer_by_lua,负载均衡,路由转发。header_filter_by_lua,用于响应头过滤处理。body_filter_by_lua,用于响应体过滤。log_by_lua,记录。OpenResty提供了大量的LuaAPI接口用于操作Nginx。只要熟悉lua语法,清楚了解Nginx的运行流程,就可以轻松的对Nginx进行二次开发。无论作为应用网关还是高性能Web应用,都支持连接各种丰富的后端存储,如:MySQL、Redis、Memcache、PostgreSQL等,周边生态非常丰富.https://github.com/openresty/lua-nginx-module/#accessbylua注意:OpenResty的API使用范围有限,每个API都有对应的使用阶段列表。如果超出范围使用,会报错。①部署安装本文以CentOS系统为例。添加openresty仓库,方便我们以后通过yumupdata命令安装或更新我们的软件包:yuminstallyum-utils-yyum-config-manager--add-repohttps://openresty.org/package/centos/openresty。repo安装软件:yuminstallopenresty-y安装命令行工具resty:yuminstallopenresty-resty-y②项目实际修改nginx.conf配置文件:worker_processesauto;worker_rlimit_nofile1000000;events{useepoll;worker_connections150000;}http{includemime.types;default_typeapplicationmain/addoctet-stream$rformat;log_reformat-$remote_user[$time_local]"$request"''$status$content_length$body_bytes_sent"$http_referer"''"$http_user_agent""$http_x_forwarded_for""$upstream_response_time""$request_time"';access_loglogs/access.logmain;server{listen8080;location/{access_by_lua_block{localheaders=ngx.req.get_headers(0)localtrace_id=headers["X-Trace-Id"]ngx.log(ngx.ERR,trace_id)}#ngx.say("

你好!

")proxy_passhttp://168.12.8.10:8080;}}server{listen8082;位置/{default_typetext/html;content_by_lua_block{ngx.say("

HelloOpenresty!

")}}}}nginx.conf分为三层嵌套:最外层http,表示处理http协议http内部的server监听端口,启动一个LuaJIT虚拟机,在同一个端口内部执行lua代码,区分不同的业务功能,采用location配置,通过不同的路径处理不同的业务逻辑。添加环境变量:echo"exportPATH=$PATH:/usr/local/openresty/nginx/sbin">>/etc/profilesource/etc/profile启动openresty,启动命令同nginx:nginx-c/usr/local/openresty/nginx/conf/nginx.conf访问Web服务:curlhttp://localhost:8082/如果正常,浏览器页面会输出HelloOpenresty!如果修改了nginx.conf配置项,我们可以重启一下:nginx-sreload作者:汤姆哥编辑:陶家龙来源:转载自公众号微科技(ID:weiguanjishu)