首页 > 其他分享 >【网关开发】Openresty使用cosocket API 发送http与tcp网络请求

【网关开发】Openresty使用cosocket API 发送http与tcp网络请求

时间:2023-12-20 16:35:13浏览次数:33  
标签:status cosocket 网关 http err sock peer end local

背景

为网关提供健康检查功能时需要对节点发送http或者tcp探活请求。Openresty 提供cosocket来处理非阻塞IO。

实现

跟工程结合在一起,这里简单拼接数据结构

local function __default_check_alive(status)
    return status >= 200 and status <= 299
end
local function debug_ctx()
    local ctx =  {
        peer = {ip = '10.218.22.239', port = '8090'},                                                 --目标机器
        ahc = {
            type = 'http',
            timeout = 3,
            check_http_send = "GET /ping HTTP/1.1\r\nHost: service_test.com\r\n\r\n",  -- 发送的数据内容
        },
        status_check = __default_check_alive
    }
    return ctx
end

发送http请求

local stream_sock = ngx.socket.tcp    -- 引入模块
local re_find = ngx.re.find

local function __check_http_peer(ahc, peer, status_check)
    local ok
    local req = ahc.check_http_send

    local sock, err = stream_sock()            -- 创建 TCP 的 cosocket 对象
    if not sock then
        ngx.log(ngx.ERR, "failed to create stream socket: " .. err)
        return false, err
    end

    sock:settimeout(ahc.timeout * 1000)      --设置超时时间

    ok, err = sock:connect(peer.ip, peer.port)  --建立连接
    if not ok then
        return false
    end

    local bytes, err = sock:send(req)    --发送数据
    if not bytes then
        return false
    end

    local status_line, err = sock:receive()  -- 接收数据
    if not status_line then
        if err == "timeout" then
            sock:close()  -- timeout errors do not close the socket.
        end
        return false
    end

    if status_check then
        local from, to, err = re_find(status_line,
                                      [[^HTTP/\d+\.\d+\s+(\d+)]],      --利用正则获取status code
                                      "joi", nil, 1)
        if err then
            ngx.log(ngx.ERR, "failed to parse status line: "..err)
        end

        if not from then
            sock:close()
            return false
        end

        local status = tonumber(status_line:sub(from, to))
        if not status_check(status) then
            -- ngx.log(ngx.ERR, status_line)
            sock:close()
            return false
        end
    end

    sock:close()
    return true
end

发送tcp请求


-- functional, check peer by tcp, returns bool indicate up or down
local function __check_tcp_peer(ahc, peer)
    local ok
    local sock, err = stream_sock()
    if not sock then
        ngx.log(ngx.ERR, "failed to create stream socket: " .. err)
        return false, err
    end

    sock:settimeout(ahc.timeout * 1000)

    ok, err = sock:connect(peer.ip, peer.port)
    if not ok then
        return false
    end
    sock:close()
    return true
end

遇到的问题

API disabled in the context of init_worker_by_lua*

这是因为我使用的地方是在init_worker_by_lua阶段,这阶段是不允许使用cosocket的,除了这些阶段还有
set_by_lua、log_by_lua、header_filter_by_lua、body_filter_by_lua、init_by_lua* 都是不允许使用的

-- 修改调用
ngx.timer.at(0, function (p, self)
        local ctx = down_peer_checker.debug_ctx()
        ngx.log(ngx.INFO,"down_peer_checker  check_peer "..tostring(down_peer_checker.check_peer(ctx)))
    end)

HTTP/1.1 400 Bad Request

主要是请求字符串格式问题、

GET /ping HTTP/1.1\r\n Host: service_test.com\r\n        错误
GET /ping HTTP/1.1\r\nHost: service_test.com\r\n\r\n   正确

总结与思考
cosocket知识与参考文章:https://zhuanlan.zhihu.com/p/507329735
存在部分封装,源码地址 https://github.com/zhaoshoucheng/openresty/blob/main/pkg/lua_script/upstream/down_peer_checker.lua

转载自:https://www.cnblogs.com/zhaosc-haha/p/17069977.html

标签:status,cosocket,网关,http,err,sock,peer,end,local
From: https://www.cnblogs.com/alioth01/p/17916774.html

相关文章

  • Java登陆第二十六天——Http
    Http是一种基于TCP/IP的协议。相同的,它有客户端和服务端。Http的交互方式客户端向服务端发送的总是请求;服务端向客户端返回的总是响应Http的版本HTTP/0.9:初代目单行HTTP,只能返回一个HTML页面HTTP/1.0:二代目每次请求和响应都会建立和关闭一次连接(短链接)新增了三种......
  • Charles对Android手机Https请求的抓包
    Charles对Android手机Https请求的抓包•前情提要:本文只是对android手机进行抓包的描述,由于android手机系统原因,android7.0系统及以上需要在app中配置证书信任才能进行https抓包,android7.0(不含)以下系统,只需要配置好证书即可进行https抓包,本文分CharlesWindows版使用说明一、......
  • HTTP 协议
    HTTP协议HTTP:HyperTextTransferProtocol的缩写,译为超文本传输协议。层级:应用层协议端口:基于TCP/IP协议簇,默认使用80/tcp端口作用:http协议定义了客户端和服务器之间数据交换的规则和格式,从而实现客户端和服务器之间的超文本数据传输超文本:不限于纯文本内容,还可以包含......
  • Rails ActionDispatch::Http::UploadedFile to File
    RailsでFileをActionDispatch::Http::UploadedFileに変換する方法require'mime/types'File.open(path)do|file|filename=File.basename(file.path),ActionDispatch::Http::UploadedFile.new(filename:filename,type:MIME::Types.type_for(filename).first......
  • apache HttpClient异常-ProtocolException: Target host is not specified
    昨夜,甘肃临夏州积石山县发生6.2级地震,影响到甘肃、青海地区。截至目前,已有100多人遇难。百度了一下当地天气,还挺冷,夜间温度低到-15℃。时间就是生命,祈祷难民尽快得到救援!  分享今天解决的一个生产问题告警。如下HTTP工具类中的httpClientPost方法使用apache的HttpClient(ma......
  • C# HttpPostedFile传值,储存
    HttpContext.Current.Request.Files附件保存接口实现///<summary>///Post请求,Params传参///</summary>///<paramname="url"></param>///<paramname="onHeading"></param>......
  • 使用网关采集modbus设备数据转换成profinet协议的方案
    1 方案描述这个方案是使用vfbox网关采集modbus设备的数据,然后转换成profinet协议发送给平台。这种转换方法只需要简单的配置网关参数,不需要进行软件编程,很方便的就把modbus数据转换成了profinet协议。在电脑上通过软件配置网关参数,告诉网关要采集的数据的寄存器地址,然后在配置一下......
  • Java http请求json数据
    publicstaticStringsendJson(Stringurl,Stringjson){StringreturnValue="调用接口失败";CloseableHttpClienthttpClient=HttpClients.createDefault();ResponseHandler<String>responseHandler=newBasicResponseHandler();try{......
  • EtherCAT转PROFINET工业网关-GT200-PN-EC
    GT200-PN-EC是实现PROFINET控制器和EtherCAT伺服或变频器设备之间的数据交换网关。它可以将多个EtherCAT设备连接到PROFINET网络中,并在它们之间建立可靠的通信通道。产品特点:1、使用方便:用户不必了解复杂的PROFIdrive行规和CIA402协议规范,西门子PLC通过此网关控制EtherCAT总线......
  • 异步记录第三方接口调用日志的优雅实现(HttpClient+装饰者模式+异步线程池)
    对于第三方接口调用日志这个功能,笔者在工作中曾见过以下两种方式:Restemplate+装饰者模式+MQ实现网关监控+Feign拦截器+观察者模式实现其中观察者模式的实现是我最为佩服的设计,个人认为以上两种实现都显得略过臃肿,应该简化设计,让异步记录的实现更加简洁优雅,因此产生了这样......