背景

为网关提供健康检查功能时需要对节点发送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. Android 执行shell命令 非root

    一个开源的项目已经完成了这个功能 app_process-shell-use,这个项目网上讲解的,很多,我这边就把操作时一些简要步骤说明一下 但是该方式有缺点:必须要先USB连接,debug的时候,运 ...

  2. cesium中添加建筑白模

    1.在cesium中添加模型依赖于Cesium ion帐户的资产id,在这里创建账户. 2.上传模型(模型文件类型在Cesium ion中有说明,模型的提取办法可在这里查看)到账户中并平铺为3D Ti ...

  3. 15 Python模块

    本篇是 Python 系列教程第 15 篇,更多内容敬请访问我的 Python 合集 一个模块其实就是一个文件(以.py结尾).使用模块的好处是便于维护和重用代码. 要创建一个模块,只需编写一个新的文 ...

  4. CSS & JS Effect – FAQ Accordion & Slide Down

    效果 参考: Youtube – Responsive FAQ accordion dropdown | HTML and CSS Tutorial 几个难点 1. 如何 align left for ...

  5. Figma 学习笔记 – Layout Grid

    前言 我原本以为, 在 Figma 只要用 Auto Layout 就可以打天下. 真的是 too young too simple. 要做一个简单的 7:3 比例, 用 Auto Layout 是做 ...

  6. 2024-09-21:用go语言,给定一个字符串 s,字符串中的每个字符要么是小写字母,要么是问号‘?‘。对于一个仅包含小写字母的字符串t,我们定义cost(i)为在t的前i个字符中与t[i]相同的字

    2024-09-21:用go语言,给定一个字符串 s,字符串中的每个字符要么是小写字母,要么是问号'?'.对于一个仅包含小写字母的字符串t,我们定义cost(i)为在t的前i个字符中与t[i]相同的字 ...

  7. `std::packaged_task`、`std::thread` 和 `std::async` 的区别与联系

    std::packaged_task.std::thread 和 std::async 的区别与联系 std::packaged_task.std::thread 和 std::async 都是 C+ ...

  8. 墨天轮最受DBA欢迎的数据库技术文档-监控篇

    好久不见,<墨天轮最受欢迎的技术文档>系列文章回归啦!本期主题数据库监控篇,希望能够帮助到大家!此外,为感谢大家支持,原文文末也给大家带来了返场福利,欢迎大家进入原文参与~ 数据库监控是许 ...

  9. iOS本地化NSLocalizedString的使用小结

    在iOS设备,包括iPhone和iPad是全球可用.显然,iOS用户都来自不同国家,说着不同的语言.为了提供出色的用户体验,你可能希望以多种语言提供您的应用程序.适应应用程序以支持特定语言的过程通常被 ...

  10. Failed to mount component: template or render function not defined 使用 require 引入组件的时候报错

    为什么有的时候使用require引入组件不会报错,有的时候就会报错,需要加上default就不会报错  ? webpack 支持 CommonJS和 ES6模块打包,当我们引用组件的时候,在 scri ...