前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >openresty+lua+kafka方案与Tomcat接口并发度对比分析

openresty+lua+kafka方案与Tomcat接口并发度对比分析

作者头像
小勇DW3
发布2019-08-20 16:22:48
1.3K0
发布2019-08-20 16:22:48
举报
文章被收录于专栏:小勇DW3

1、openresty+lua+kafka

1.1 openresty+lua+kafka方案

  之前的项目基于nginx反向代理后转发到Tomcat的API接口进行业务处理,然后将json数据打入kafka中,但是随着业务的扩大,访问量越来越大,并发数也很高,导致程序遇到性能问题;

基于nginx的高性能特点,现在考虑使用一种openresty+lua+kafka,直接在nginx阶段将数据打入kafka中,来提高性能。

1.1.1 OpenResty运行原理

  Nginx 采用的是 master-worker 模型,一个 master 进程管理多个 worker 进程,基本的事件处理都是放在 woker 中,master 负责一些全局初始化,以及对 worker 的管理。在OpenResty中,每个 woker 使用一个 LuaVM,当请求被分配到 woker 时,将在这个 LuaVM 里创建一个 coroutine(协程)。协程之间数据隔离,每个协程具有独立的全局变量_G。

  协程和多线程下的线程类似:有自己的堆栈,自己的局部变量,有自己的指令指针,但是和其他协程程序共享全局变量等信息。线程和协程的主要不同在于:多处理器的情况下,概念上来说多线程是同时运行多个线程,而协程是通过代码来完成协程的切换,任何时刻只有一个协程程序在运行。并且这个在运行的协程只有明确被要求挂起时才会被挂起。

原理图如下:

1.1.2 OpenResty的优势

  其是由Nginx核心加很多第三方模块组成,其最大的亮点是默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。

借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。

而且OpenResty提供了大量组件如Mysql、Redis、Memcached等等,使在Nginx上开发Web应用更方便更简单。目前在京东如实时价格、秒杀、动态服务、单品页、列表页等都在使用Nginx+Lua架构,其他公司如淘宝、去哪儿网等。

1.2 方案实施

申请线上云主机,部署公司内部部署平台NDP;

配置openresty:

代码语言:javascript
复制
worker_processes  8;

pid        /home/xxxx/nginx.pid;


events {
    use epoll;
    worker_connections  65535;
    multi_accept on;
}


http {
    lua_package_path "/home/xxxxxx/lib/?.lua;;";
    include       mime.types;
    default_type  application/octet-stream;
    #access_log off;
    keepalive_requests 8192;
    keepalive_timeout 300s 300s;
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 1024m;
    client_body_buffer_size 10m;

    log_format  main  '$remote_addr$time_iso8601$request'
                      '$status$upstream_response_time$request_time'
                      '$http_user_agent$http_x_forwarded_for';

    access_log off;
    # access_log  /home/xxxxxx/access.log  main;

    sendfile on;
    #提高I/O性能
    tcp_nodelay on;
    proxy_buffering off;
    #此请求不缓存
    #add_header Expires "Fri, 01 Jan 1980 00:00:00 GMT";
    #add_header Pragma "no-cache";
    #add_header Cache-Control "no-cache, max-age=0, must-revalidate";
    resolver xxxxx;

    # healthcheck shared
    # lua_shared_dict healthcheck 1m;

    # 数据书籍服务汇总
    include ./service_hub/*;

}

配置依赖lua依赖:

配置server服务:

代码语言:javascript
复制
server {
        listen 8080;
        #数据上报
        # 默认读取 body
        lua_need_request_body on;
        location /xxxx {
           # access_log  /home/xxxx/risk_doubt.log  main;
           # 响应正常,内容为空
           empty_gif;
           content_by_lua_block{ 
            -- 引入lua所有api
            local topic = "xxxx"
            local cjson = require "cjson"  
            local producer = require "resty.kafka.producer"  
            -- 定义kafka broker地址,ip需要和kafka的host.name配置一致  
            local broker_list = {  
                { host = "xxx", port = 9092 },
                { host = "yyy", port = 9092 },
                { host = "zzz", port = 9092 }
            }  
            -- 定义json便于日志数据整理收集  
            local data_json = {}  
            ngx.req.read_body()
        local args = ngx.req.get_body_data()
        -- 将ip传入json参数中
        data_json["body"] = args
        data_json["ip"] = ngx.var.remote_addr
        -- 转换json为字符串
        -- ngx.log(ngx.ERR, "args:", tostring(data_json))
            local message = cjson.encode(data_json);  
            ngx.log(ngx.ERR, "args:", message)
        -- 定义kafka异步生产者  
            local bp = producer:new(broker_list, { producer_type = "async" })  
            -- 发送日志消息,send第二个参数key,用于kafka路由控制:  
            -- key为nill(空)时,一段时间向同一partition写入数据  
            -- 指定key,按照key的hash写入到对应的partition  
            -- local ok, err = bp:send(topic, nil, message)  

            -- if not ok then  
            --     ngx.log(ngx.ERR, "kafka send err:", err)  
            --     return  
            -- end  
       }
        }
       
        
}

1.3 压力测试:

线上被测云主机性能:8核,16G内存,400M网卡流量。

  该次测试是在 1000并发量,1分钟16秒压测时间段内的数据:

二、Tomcat接口的测试:

代码语言:javascript
复制
    @PostMapping(value = "/xxxx")
    public Object test(String str, HttpServletRequest request) throws IOException
    {
        //logger.info("receive msg...");
        return null;
    }

同上的压测环境进行压测:

 三、性能分析:

1、同样的压测环境,openresty的TPS性能确实要比单纯的Tomcat要好;

2、根据TPS的性能曲线可以看到,openresty的TPS曲线要比tomcat的更加稳定;

中间遇到的问题分析:

其实参考资料你会发现,测试结果中openresty的TPS数值比起网上很多数值要低不少,有不少网友的压测结果是10W+,为什么有这么大的差距呢,主要原因还是楼主所使用的线上云主机网卡流量有限制,只有400M,

导致了openresty的性能无法得到充分的发挥,后期项目中会考虑换用1G以上的网卡流量。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、openresty+lua+kafka
  • 二、Tomcat接口的测试:
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档