首页 > 其他分享 >systemd socket 实现按需启动

systemd socket 实现按需启动

时间:2024-09-26 19:45:58浏览次数:8  
标签:systemd socket 配置文件 启动 代码 sys 实例

当使用systemd按需启动某套接字进程后,其图示大致如下:

当需要访问该服务时候,systemd会接收请求流量,而后启动后端真实的服务,最后转发该流量,并且关闭原始套接字,图示如下:

实现一个socket步骤

所谓的按需启动,其实是systemd下的socket配置单元,其命名规则以.socket为后缀,主要服务于套接字模式的启动。

我们配置socket后,systemd会替我们监听端口,当访问该端口的时候,systemd会启动后端实例,并且将请求转发至该实例,后端完成需求后,由systemd销毁该实例。已达到按需启动的效果。

注意,我们想接入socket,编写的业务要符合该就不能再对外监听套接字了,虽然systemd不会卡这个,但是不符合按需启动的逻辑,所以,我们自己写的业务,想要接入systemd需要修改其代码,修改为符合systemd socket规则的,换句话说,服务器监听由systemd来替我们做了,我们只用关心其业务逻辑即可。甚至要从文件或者标准输入中获取客户端发送的数据。

创建简单的socket

所以,我们不仅需要配置socket,还需要配置其后端模板实例,先来创建一个socket,例如:

  ini 代码解读 复制代码
[Unit]
Description=a test sample web socket

[Socket]
ListenStream=9999
Accept=yes

我们将其命名为 testSampleWeb.socket,并且存放到/usr/lib/systemd/system目录下。

这段配置文件意思是:

  • Description: 该服务的简介
  • ListenStream: 对外监听的tcp端口
  • Accept: 为true表示为每个连接传入单独的服务

在此,我们仅需reloadsystemd配置档:

  bash 代码解读 复制代码
systemctl daemon-reload

在使用systemctl status testSampleWeb.socket查看当前状态:

可以看到,目前状态是关闭状态的,可以使用start操作先开启该服务:

此时,若查看9999端口占用情况,会发现是systemd占用的,且pid为1,例如:

创建后端实例

注意,此时我们还没有编写属于该socket背后的实例,所以,请求该端口,会抛错,例如:

而在systemd日志中,会详细的描述,找不到该socket的后端实例配置,如:

所以,我们需要在此目录下,创建后端实例配置文件@.service结尾,如socket配置文件为: testSampleWeb.socket, 则该实例service的配置文件是[email protected],其内容如下:

  ini 代码解读 复制代码
[Unit]
Description=sample python webs %i

[Service]
ExecStart=-/usr/bin/python3 /root/sampleWeb.py
StandardInput=socket

这个要注意,为什么不是创建.service结尾的配置呢,这是因为此前创建socket的时候,Accept设置为True,所以要创建以@.service结尾的配置文件。

该配置的含义是:

  • ExecStart: 执行的命令
  • StandardInput: 标准输入方式为socket

接着,我们需要编写该后端服务代码,其内容如下:

  python 代码解读 复制代码
import sys

msgData = ""

while True:
    datas = sys.stdin.read(1)
    msgData += datas

    if msgData.endswith("\r\n\r\n"):
        break

httpInfo = msgData.split("\r\n")

rHeader = httpInfo[0]

httpDicts = {}
if 1 < len(httpInfo):
    httpDicts = dict([x.split(":",1) for x in httpInfo[1:] if ":" in x])

contentLen = 0
if "Content-Length" in httpDicts:
    contentLen = int(httpDicts["Content-Length"])

body = sys.stdin.read(contentLen)

sys.stdout.write("请求报文为:\n")
sys.stdout.write("\n请求行:\n" + str(httpInfo[0]))
sys.stdout.write("\n\n首部行:\n")
[print(k,":",httpDicts[k]) for k in httpDicts]
sys.stdout.write("\n\n报文主体:\n")
sys.stdout.write(body)
sys.stdout.write("\n\n")

上述代码,是一个简单的拆分http报文协议的代码,你可能很好奇,为什么没有调用socket呢?从哪儿来的客户端信息呢?正如上面所述,systemd socket已经帮我们把台架子搭好了,我们仅需要从标准输入流获取数据,要想发送给客户端,只需要往标准输出吐出信息即可。

测试

需要先加载配置文件,而后重启socket,命令如下:

  bash 代码解读 复制代码
systemctl daemon-reload
systemctl start testSampleWeb.socket 

使用netstat查看端口为9999的监听信息

  bash 代码解读 复制代码
netstat -tulnp | grep 9999

使用curl工具,向该接口发送一个post请求,例如:

  bash 代码解读 复制代码
curl -X POST -d "site=juejin,name=pdudo" 127.0.0.1:9999

输出的结果是我们预测的分析http报文的结果:

总结

systemd提供了非常多的功能,其中socket只是其中的一小块,但是确实是非常有意思的,试想一下,服务器上有一个对外的服务,非常重要,但是访问的很少,可能一年也访问不了几次,如果有这样一个工具,当监听到有客户端进行访问的时候,再启动服务,进而响应客户端需求,处理完毕后,再销毁该后端服务,这样既能够解决业务访问需求,又能够避免占用过多的资源,恰恰好。

sshd就是一个非常好的例子,你可以在虚拟机上安装一个centos 7,先将sshd服务先关闭,而后在终端中输入:

  sql 代码解读 复制代码
systemctl start sshd.socket

恭喜你,你已经学会了systemd socket了。


作者:pdudo
链接:https://juejin.cn/post/7299731906254241819
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:systemd,socket,配置文件,启动,代码,sys,实例
From: https://www.cnblogs.com/cheyunhua/p/18434171

相关文章

  • 《黑神话:悟空》游戏启动时崩溃提示“找不到d3drm.dll”文件该怎么解决?黑神话悟空游戏
    在启动《黑神话:悟空》游戏时,出现崩溃情况,提示“找不到d3drm.dll”文件,令人十分困扰。别慌,这通常是由于该文件缺失所致。接下来为您详细介绍解决此问题的有效方法,帮助您顺利开启游戏之旅。本篇将为大家带来《黑神话:悟空》游戏启动时崩溃提示“找不到d3drm.dll”文件该怎么解决的......
  • 《星球大战:亡命之徒》游戏启动时崩溃提示“找不到D3DX9_41.dll”该怎么解决?星球大战亡
    启动《星球大战:亡命之徒》游戏时,遭遇崩溃,提示“找不到D3DX9_41.dll”,让人十分苦恼。别着急,这种情况大概率是相关文件缺失引起。下面将为您详细说明解决此问题的有效途径,助力您顺利进入游戏。本篇将为大家带来《星球大战:亡命之徒》游戏启动时崩溃提示“找不到D3DX9_41.dll”该怎......
  • 《圣剑传说Visions of Mana》游戏启动时闪退弹窗“找不到node.dll”该怎么修复?圣剑传
    启动《圣剑传说VisionsofMana》游戏时,竟出现闪退并弹窗“找不到node.dll”,这真让人手足无措。别担忧,此种状况往往是相关文件缺失造成。接下来为您详细阐述修复这一问题的可行办法,助您顺利开启游戏。本篇将为大家带来《圣剑传说VisionsofMana》游戏启动时闪退弹窗“找不到no......
  • 《超级机器人大战30》缺少roboex32.dll启动遇阻怎么办?轻松应对《超级机器人大战30》ro
    当《超级机器人大战30》因缺少roboex32.dll文件而启动遇阻时,可以尝试以下几种解决方案来轻松应对这一问题:一、下载并替换缺失的DLL文件寻找可靠来源:首先,需要在互联网上找到可靠的roboex32.dll文件下载源。建议访问官方网站、微软官方下载中心或知名的软件下载站点,以确保下载......
  • C# WebSocket Servers -- Fleck、SuperSocket、TouchSocke
    最近在维护老项目,感觉内存一直都有问题,定位到问题是WebSocketServer的问题,了解了Fleck、SuperSocket、TouchSocke等开源项目,这里记录一下。可能今后都不会用些轮子了,.net5、.net6、.net7、.net8项目已经集成了WebSocket,只要 app.UseWebSockets()代码就可以了,详情见 WebS......
  • Docker容器启动Redis设置密码并持久化
    启动命令dockerrun--namewh-redis-p6379:6379-v/root/RedisData:/data-d--restartunless-stoppedredis--appendonlyyes--requirepass'Your-password'dockerrun:启动一个新的Docker容器。--namewh-redis:给容器指定一个名称,容器名为wh-redis。指定名......
  • fmql之linux启动文件大小
    想要从flash启动linux,但是flash同时也要存储数据,所以看看启动文件占多大内存。本是基于“fmql之ubuntu移植”的基础上继续进行的:fmql之ubuntu移植-CSDN博客目的:flash放启动文件,ubuntu18放到SD卡,且自启动。 NOW:flash可以烧写BOOT.bin,image.ub和ubuntu放到SD卡,MIO配置......
  • 《消逝的光芒2》游戏无法正常启动:提示steam_api.dll错误的解决方法
    针对《消逝的光芒2》游戏无法正常启动并提示steam_api.dll错误的问题,可以尝试以下几种解决方法:一、验证游戏文件完整性打开Steam客户端:确保已经登录Steam账户。访问游戏库:在Steam主界面上方找到“库”选项,点击进入。选择游戏:在游戏库中找到《消逝的光芒2》,右键点击该游戏图......
  • python socket和socketserver
    Python提供了两个基本的socket模块。一个是socket,它提供了标准的BSDSocketAPI;另一个是socketServer,它提供了服务器中心类,可以简化网络服务器的开发。    下面先简要介绍socket模块包含的类及其使用。       1.开始了解socket模块前,先熟悉下Python的网络编程模块......
  • 将Java编译的 .jar文件做成windows服务 实现开机自启动
    将Java编译的.jar文件做成windows服务实现开机自启动1、将windows服务制作工具(在网上下载) 复制到 jar程序目录下,并改名为 install.exe2、新建xml文件,将文件名命名为 install.xml3、将下面内容复制到xml文件中,启动模式为自动启动Automatic   修改jar文件路径......