当前位置:网站首页>The core of openresty and cosocket
The core of openresty and cosocket
2022-07-29 06:50:00 【Flytiger1220】
cosocket It's all kinds of lua-resty-* The foundation of non blocking library , no Yes cosocket, Developers cannot use Lua To quickly connect various external network services .
Early OpenResty In the version , If you want to go with Redis、memcached These services interact , Need to use redis2-nginx-module、redis-nginx-module and memc-nginx-module these C modular . These modules are still in OpenResty In the distribution package of .
cosocket After the function is added , They have been lua-resty-redis and lua-resty-memcached replace , The base No one uses it anymore C The module is connected to external services .
What is? cosocket
cosocket yes OpenResty Proper nouns in , It is the English of coprocessing and network socket Put together , namely cosocket = coroutine + socket. therefore , You can put cosocket Translated into “ Co process socket ”.
cosocket Not only need Lua Support of CO process features , Also needed Nginx Support of very important event mechanism in , The two are combined in one rise , Finally, the nonblocking network is realized I/O. in addition ,cosocket Support TCP、UDP and Unix Domain Socket.
stay OpenResty Call a cosocket Correlation function , The internal implementation is what the following figure looks like :


User Lua Every time the script triggers a network operation , There will be an agreement yield as well as resume.
Encounter network I/O when , It will hand over control (yield), Register network events to Nginx Listening list , And give the authority to Nginx; When there is Nginx When the event reaches the trigger condition , Then wake up the corresponding process to continue processing (resume).
OpenResty It is on this basis that , Encapsulation implementation connect、send、receive Wait for the operation , Formed the present cosocket API. To deal with TCP Of API For example, let's introduce . Handle UDP and Unix Domain Socket , And TCP Interface base Ben is the same .
cosocket API And instruction introduction
TCP dependent cosocket API It can be divided into the following categories :
- Create objects :ngx.socket.tcp.
- Set timeout :tcpsock:settimeout and tcpsock:settimeouts.
- Establishing a connection :tcpsock:connect.
- send data :tcpsock:send.
- Receive data :tcpsock:receive、tcpsock:receiveany and tcpsock:receiveuntil.
- Connection pool :tcpsock:setkeepalive.
- Close the connection :tcpsock:close.
these API Context that can be used :
rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*_ because Nginx Various limitations of the kernel ,cosocket API stay set_by_lua*, log_by_lua*, header_filter_by_lua* and body_filter_by_lua* It can't be used in . And in the init_by_lua* and init_worker_by_lua* For the time being, it can't be used , however Nginx The kernel has no restrictions on these two phases .
Besides , With these API dependent , also 8 individual lua_socket_ At the beginning Nginx Instructions :
- lua_socket_connect_timeout: Connection timeout , Default 60 second .
- lua_socket_send_timeout: Send timeout , Default 60 second .
- lua_socket_send_lowat: Send threshold (low water), The default is 0.
- lua_socket_read_timeout: Read timeout , Default 60 second .
- lua_socket_buffer_size: The size of the cache for reading data , Default 4k/8k.
- lua_socket_pool_size: Connection pool size , Default 30.
- lua_socket_keepalive_timeout: Connection pool cosocket Object's free time , Default 60 second .
- lua_socket_log_errors:cosocket When something goes wrong , Whether to record the log , The default is on.
Some instructions and API It's the same function , For example, set timeout and connection pool size . however , If there is a conflict between the two ,API Priority of is higher than instruction , Will override the value set by the instruction . therefore , Generally speaking , It is recommended to use API To set up Set up , This will also be more flexible .
Through a concrete example , To understand how to use these cosocket API. send out TCP Request to a website , And print out the returned content :
resty -e 'local sock = ngx.socket.tcp()
sock:settimeout(1000) -- one second timeout
local ok, err = sock:connect("www.baidu.com", 80)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local req_data = "GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n"
local bytes, err = sock:send(req_data)
if err then
ngx.say("failed to send: ", err)
return
end
local data, err, partial = sock:receive()
if err then
ngx.say("failed to receive: ", err)
return
end
sock:close()
ngx.say("response is: ", data)
'Analyze this code :
- First , adopt ngx.socket.tcp() , establish TCP Of cosocket object , The name is sock.
- then , Use settimeout() , Set the timeout to 1 second . Note there is no distinction between timeouts here connect、receive, It is a unified setting .
- next , Use connect() To connect to the designated website 80 port , If you fail, just quit .
- If the connection is successful , Just use send() To send the constructed data , If the sending fails, exit .
- If the data is sent successfully , Just use receive() To receive the data returned by the website . here receive() The default parameter value of is *l, That is, only the data in the first row is returned ; If the parameter is set to *a, Is to receive data continuously , Until the connection is closed ;
- Last , call close() , Active shut down socket Connect .
Pick up Come down , Let's make some adjustments to this example :
The first move , Yes socket Connect 、 Send and read these three actions , Set the timeout respectively .
settimeout() The function is to uniformly set the timeout to a value . If you want to set it separately , You need to use settimeouts() function , For example, the following way of writing :
sock:settimeouts(1000, 2000, 3000)Indicates that the connection timeout is 1 second , The sending timeout is 2 second , The read timeout is 3 second . stay OpenResty and lua-resty In the library , Most of them are time related API Parameters of , Are in milliseconds
The second move ,receive Receive content of a specified size .
receive() The interface can receive a line of data , It can also receive data continuously . If you only want to receive 10K Size data , You should use receiveany() , It is designed to meet this demand
local data, err, partial = sock:receiveany(10240)About receive, There is another common user requirement , That is to keep getting data , Do not stop until you encounter the specified string .
receiveuntil() It's designed to solve this kind of problem , It won't look like receive() and receiveany() Return string , Instead, it returns an iterator . In this way, it can be called in the loop to read the matched data in segments , When reading is finished , It will return nil.
local reader = sock:receiveuntil("\r\n")
while true do
local data, err, partial = reader(4)
if not data then
if err then
ngx.say("failed to read the data stream: ", err)
break
end
ngx.say("read done")
break
end
ngx.say("read chunk: [", data, "]")
endreceiveuntil Returns the \r\n Previous data , And through the iterator, each time it reads 4 Bytes ,
The third action , Don't shut down directly socket, Instead, put it into the connection pool .
If there is no connection pool , Every time a request comes in, you need to create a new connection , It will lead to cosocket Objects are frequently created and pinned destroyed , Cause unnecessary loss of performance .
To avoid this problem , After using one cosocket after , You can call setkeepalive() Put it in the connection pool
local ok, err = sock:setkeepalive(2 * 1000, 100)
if not ok then
ngx.say("failed to set reusable: ", err)
end This code sets the idle time of the connection to 2 second , The size of the connection pool is 100. such , Calling connect() Function time , Will get priority from the connection pool cosocket object .
About the use of connection pool , There are two points to note :
First of all , You cannot put the wrong connection into the connection pool , Otherwise, when you use it next time , It will lead to the failure of sending and receiving data . This is why it is necessary to judge each API One reason for the success of the call .
second , Make sure the number of connections . The connection pool is worker Grade , Every worker Each has its own connection pool . therefore , If there is 10 individual worker, The connection pool size is set to 30, For back-end services , It's like 300 A connection .
边栏推荐
- Ansible(自动化软件)
- 网络工具中的“瑞士军刀”-nc
- Hongke share | let you have a comprehensive understanding of "can bus error" (III) -- can node status and error counter
- Floating point multiplication and division of vivado IP core floating point
- 注解(Annotation)
- Hongke share | bring you a comprehensive understanding of "can bus error" (I) -- can bus error and error frame
- 【经验】通过跳板机远程连接内网服务器的相关配置
- Hongke white paper | how to use TSN time sensitive network technology to build a digital factory in industry 4.0?
- Biased lock, lightweight lock test tool class level related commands
- 王树尧老师运筹学课程笔记 02 高等数学基础
猜你喜欢

6、 Network interconnection and Internet

NLP word segmentation

Network Security Learning (II)

CDM—码分复用(简单易懂)

【经验】通过跳板机远程连接内网服务器的相关配置

软件定义边界SDP

吴恩达老师机器学习课程笔记 02 单变量线性回归

基于噪声伪标签和对抗性学习的医学图像分割注释有效学习

Shallow reading of shared lock source code of abstractqueuedsynchronizer (AQS)

Let the computer run only one program setting
随机推荐
关于SQL Server语句入门级应用阶段性学习——找工作必备(一)
【冷冻电镜】RELION4.0 pipeline命令总结(自用)
Conversion of fixed-point number to floating-point number of vivado IP core
C语言数据类型
Analysis of four isolation levels of MySQL things
【冷冻电镜入门】加州理工公开课课程笔记 Part 3: Image Formation
JMM 内存模型概念
网络工具中的“瑞士军刀”-nc
Joint modeling of price preference and interest preference in conversation recommendation - extensive reading of papers
Network Security Learning (I)
量子机器学习中的安全性问题
王树尧老师运筹学课程笔记 01 导学与绪论
Why does 5g N2 interface control plane use SCTP protocol?
SQL developer graphical window to create database (tablespace and user)
10种常见的软件架构模式
3、 Wide area communication network
finally 和 return 的执行顺序
【冷冻电镜|论文阅读】emClarity:用于高分辨率冷冻电子断层扫描和子断层平均的软件
Hongke case | PAC: an integrated control solution integrating SoftPLC control logic, HMI and other service functions
矩阵分解与梯度下降