介绍OpenResty?是一个基于Nginx和Lua的高性能Web平台,集成了大量优秀的Lua库、第三方模块和大部分依赖物品。用于轻松构建能够处理超高并发和高扩展性的动态Web应用程序、Web服务和动态网关。物流网关基于OpenResty构建。今天就和大家聊一聊OpenResty在物流网关的故事。为什么选择OpenRestyLogisticsGateway在建设之初就注重性能、稳定性、可扩展性和可持续性。技术选型阶段关注三个方面:在网络I/O模型方面,出于性能考虑,需要非阻塞I/O模型;由于物流网关对外提供了Http/s协议,因此有成熟的技术支持Http/s协议;世界瞬息万变,拥抱良好生态才能促进可持续发展。结合这三个方面的需求,发现OpenResty是一个不错的选择。首先,OpenResty使用协程来实现同步非阻塞cosockets。使用cosockets既可以享受同步编程的简单,又可以享受非阻塞IO的性能优势。其次,Nginx对Http/s请求的处理,目前在业界是无可比拟的,其性能和稳定性是有目共睹的。同时有望利用插件机制来扩展功能。在这方面,Kong网关项目(本项目基于OpenResty)提供了一个很好的参考方案。插件扩展方式物流网关功能复杂。核心组件包括安全、认证、限流、协议转换和日志记录。网关的这些核心功能都是插件化的。这些插件可以根据不同的商家动态加载。和卸载,以满足不同业务的需要。物流网关的插件机制依赖于Nginx处理请求的生命周期模型。安全、认证、限流三个插件在Rewrite/Access阶段动态加载执行,协议转换和负载均衡在Content阶段动态加载执行,日志在Log动态加载执行阶段是异步处理的。每个请求都需要根据业务配置动态加载。这些配置存储在MySQL数据库中。在高并发场景下,如果每个请求都需要访问MySQL数据库,那么MySQL数据库肯定会成为瓶颈,直到宕机。因此,多级缓存。缓存设计物流网关采用多级缓存。首先是ngx.shared.DICT实现的本地缓存。集中缓存使用Redis。物流网关不直接访问数据库,而是通过调用RPC服务访问数据库。Redis中的缓存是长期有效的。Redis和MySQL之间的数据同步依赖于双写机制。本地缓存与Redis的同步同时采用两种方式。一种是使用Redis实现一个简单的MQ,网关集群节点订阅元数据变化消息,当有变化时,清除相关的本地缓存;为了容错,本地缓存有一个过期日期,保证数据总是有机会同步到本地缓存。负载均衡器的设计物流网关自研了一个支持RPC协议的Lua客户端。功能与Java版客户端类似。值得一提的是,负载均衡器的设计更加智能,性能差异非常大。这种差异很可能与主机的网络、CPU负载和内存使用有关。这个影响因素是动态变化的,所以静态的负载均衡配置(比如round-robin、random、weight等负载均衡策略)很难满足需求,理想的负载均衡器应该能够根据RPC服务负载。物流网关的调度算法采用最小连接数调度算法,类似于人们去超市排队结账时,总是选择长度最短的队列。连接数的计算如下:发送请求时连接数+1,返回响应或异常时连接数-1。json跨语言陷阱Json作为成熟的序列化解决方案已经存在很长时间了,但是Json在跨语言方面并不成熟,A==json.decode(A).encode在建立跨语言时并不总是可以的.比如二进制序列化,在Java中转成base64字符串。比如0X3F会被序列化为“/”,而OpenResty自带的cjson会将“/”反序列化为字符串“/”。到目前为止没有问题,但是cjson序列化字符串“/”时,得到的是“\/”,因为“/”按照json规范需要进行转义。最终的结果是网关的输入是“/”,输出是“\/”。因此,物流网关开发了无损json序列化组件,完全基于字符串来操作json,从而避免了类型转换带来的问题。下图是一个json字符的解析过程。性能优化OpenResty提供了一个优秀的性能分析工具,可以在运行时对系统进行采样并生成火焰图。通过火焰图可以快速定位到性能瓶颈所在的代码行。物流网关在单机全链路压力测试中TPS可达10万,最大限度发挥硬件性能。总结目前,物流网关作为京东物流开放技术平台的核心服务,支持所有Http/s协议的开放业务,已顺利通过2018年618全球年中购物节和11.11全球好货节。.借助Lua出色的表达能力和插件机制,物流网关在过去的一年里实现了功能的快速演进,真正实现了对业务发展的快速响应。【本文来自专栏作者张凯涛微信公众号(凯涛的博客)公众号id:kaitao-1234567】点此查看作者更多好文
