背景

为网关提供健康检查功能时需要对节点发送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

【网关开发】Openresty使用cosocket API 发送http与tcp网络请求的更多相关文章

  1. iOS开发--用户点击频繁,多个异步网络请求取消问题?

    一.业务环境描述 当一个view同时添加两个tableView为subView的时候,两个tableView分别为mainTable和subTable. 当用户点击mainTable上的某一条数据时, ...

  2. Win(Phone)10开发第(3)弹,简单的Demo程序网络请求json解析列表显示

    先分享一个由Json字符串直接生成解析对应的类的工具: jsonclassgenerator14 百度天气接口 下面是由一个小功能(又特么的是天气)的实现,记录下下UAP的流程和结构(其实跟之前一模一 ...

  3. python 学习笔记之手把手讲解如何使用原生的 urllib 发送网络请求

    urllib.urlopen(url[,data[,proxies]]) : https://docs.python.org/2/library/urllib.html python 中默认自带的网络 ...

  4. 第三篇、微信小程序-网络请求API

    wx.request(OBJECT)发起的是https请求.一个微信小程序,同时只能有5个网络请求连接. OBJECT参数说明: 效果图: net.js Page({ data:{ result:{} ...

  5. openresty开发系列11--openresty的api入门

    openresty开发系列11--openresty的api入门 1)ngx_lua模块的hello world编辑nginx下conf配置文件nginx.conf# vi nginx.conf在se ...

  6. openresty开发系列1--网关API架构及选型

    微服务架构在项目中的应用越来越多,我们知道在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些 ...

  7. 微服务架构学习与思考(10):微服务网关和开源 API 网关01-以 Nginx 为基础的 API 网关详细介绍

    微服务架构学习与思考(10):微服务网关和开源 API 网关01-以 Nginx 为基础的 API 网关详细介绍 一.为什么会有 API Gateway 网关 随着微服务架构的流行,很多公司把原有的单 ...

  8. 微服务架构学习与思考(11):开源 API 网关02-以 Java 为基础的 API 网关详细介绍

    微服务架构学习与思考(11):开源 API 网关02-以 Java 为基础的 API 网关详细介绍 上一篇关于网关的文章: 微服务架构学习与思考(10):微服务网关和开源 API 网关01-以 Ngi ...

  9. 超越村后端开发(4:API开发)

    1.users相关的api开发 1.在settings中添加APPID,SECRET 2.在apps/users/views.py内: from chaoyuecun.settings import ...

  10. CTP API开发之一:CTP API简介

    官网下载CTP API 综合交易平台CTP(Comprehensive Transaction Platform)是由上海期货信息技术有限公司(上海期货交易所的全资子公司)开发的期货交易平台,CTP平 ...

随机推荐

  1. FFmpeg开发笔记(五十)聊聊几种流媒体传输技术的前世今生

    ​自从互联网普及之后,用于视频直播的流媒体技术就发展起来.这几十年中,比较有影响的主要有MMS.RTSP.RTMP.HLS.SRT.RIST几种,分别介绍如下. 1.MMS协议 MMS全称Micros ...

  2. SpringMVC:注解配置SpringMVC

    目录 创建初始化类,代替web.xml 创建SpringConfig配置类,代替spring的配置文件 创建WebConfig配置类,代替SpringMVC的配置文件 测试功能 使用配置类和注解代替w ...

  3. C++ weak_ptr除了解决循环引用还能做什么?

    C++: weak_ptr到底有什么用? 很多人对std::weak_ptr的认识只是不增加std::shared_ptr的引用计数,可以用来解决std::shared_ptr可能造成的循环引用问题. ...

  4. Identity – 安全基础知识

    前言 一旦涉及到用户, 那么安全就上一个层次了. 这篇主要是说说一些安全的基础 用户密码保存 网络上有太多资料说这些基础了, 我就不拉过来了. 大致记入一些重点就好了. - 为什么不可以明文保存 因为 ...

  5. QT6 QML编程

    QT6 QML编程 使用AI技术辅助生成 QT界面美化视频课程 QT性能优化视频课程 QT原理与源码分析视频课程 QT QML C++扩展开发视频课程 免费QT视频课程 您可以看免费1000+个QT技 ...

  6. Vue3——集成 sass

    安装 sass npm install sass sass-loader -D 使用 scss 语法!!!需要加上 lang="scss" <style scoped lan ...

  7. ModbusTCP通信协议分析

    前言 大家好!我是付工.前面给大家介绍了一系列关于RS485与Modbus的知识. 终于有人把RS485说清楚了 终于有人把Modbus说明白了 通透!终于把ModbusRTU弄明白了 今天跟大家聊聊 ...

  8. push_back和 emplace_back背后的逻辑

    push_back 与 emplace_back 的区别 push_back: 功能:将一个对象(或其副本)添加到 vector 的末尾. 参数:接受一个对象(或其副本)的引用. 过程: 如果传入的是 ...

  9. std::variant快速上手

    std::variant 是 C++17 引入的一种类型安全的联合体,用来存储多个可能类型中的一种值,且保证使用时的类型安全.相比于传统的 union,std::variant 不仅能够存储不同类型的 ...

  10. OCR+PDF解析配套前端工具开源详解!

    面对日常生活和工作中常见的OCR识别.PDF解析.翻译.校对等场景,配套的可视化工具能够极大地提升我们的使用体验和工作效率. 通过可视化界面,我们可以直观地看到文本识别.解析和翻译的结果,便捷评估产品 ...