要实现Linux下kbmmw 服务器的开机自动启动,必须使用linux daemon 技术,此项技术的实现具体可以通过网上查询,
今天主要写一下具体实现方式,Linux daemon的实现方法很多,但是都有一些不尽人意的问题,最近在Github 发现了一个
实现方式,经过测试发现,比较完美的实现了Linux daemon的开发。
https://github.com/EvgeniyKorepov/LinuxDaemonNewStyle
我们首先下载文件保存。
使用delphi 10.3.3 建立一个控制台工程,添加一个TDataModule,防止我们常规的kbmmw server等控件。
添加kbmmw smartservice.
加入刚才下载的两个文件。工程文件如图
另存工程名为 Linuxdaemon.
修改UnitDaemonNewStyle.pas 文件。
我是ubuntu 20.4,这一块修改为/var/run/ . 切记修改。
整个工程源码如下
program Linuxdaemon;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
kbmMWConfiguration,
kbmMWCrossSockethttpServerTransport,
kbmMWTCPServerTransport,
syscomm in 'syscomm.pas',
dmp in 'dmp.pas' {dmf: TDataModule},
httpservice in 'httpservice.pas' {kbmMWCustomHTTPSmartService1: TkbmMWCustomHTTPSmartService},
Posix.Syslog in 'Posix.Syslog.pas',
UnitDaemonNewStyle in 'UnitDaemonNewStyle.pas';
var
AEvent : TEventType;
procedure xalionserverstart;
begin
if not fileexists(homepath+'httpconfig.xml') then
begin
writeln('找不到配置文件:'+ homepath+'httpconfig.xml');
exit;
end;
{ TODO -oUser -cConsole Main : Insert code here }
syslog(LOG_NOTICE, 'KbmMW 应用服务器 '+vers);
syslog(LOG_NOTICE, '操作系统:'+Tosversion.ToString);
syslog(LOG_NOTICE, '内存: '+getservermemory);
syslog(LOG_NOTICE, 'CPU: '+getcpuinfo(True));
syslog(LOG_NOTICE, '运行信息'+ GetApplicationName+' '+runinfor);
dmf:=Tdmf.Create(nil);
dmf.UniConnection1.Server :=config.AsDefString('database.server', '127.0.0.1');
dmf.UniConnection1.Database :=config.AsDefString('database.database', '');
dmf.UniConnection1.Username :=config.AsDefString('database.username', '');
dmf.UniConnection1.Password:=config.AsDefString('database.password', '');
dmf.UniConnection1.ProviderName:=config.AsDefString('database.providerName', 'oracle');
dmf.UniConnection1.Connect;
if config.AsDefBoolean('tcptransport.open',False) then
begin
dmf.kbmMWTCPServerTransport1.Server :=dmf.kbmMWServer1;
dmf.kbmMWTCPServerTransport1.Host:=config.AsDefString('tcptransport.host', '0.0.0.0');
dmf.kbmMWTCPServerTransport1.Port:=config.AsDefInt32('tcptransport.port', 4000);
// dmf.kbmMWTCPServerTransport1.IOThreads:=100;
syslog(LOG_NOTICE, 'TCP服务侦听在:'+ dmf.kbmMWTCPServerTransport1.Port.ToString);
end;
// TkbmMWTCPIPIndyServerTransport(dmf.RESTserverP).Bindings.Clear;
with TkbmMWCrossSocketHttpServerTransport(dmf.RESTserverP) do
begin
host:=config.AsDefString('httptransportother.host', '0.0.0.0');
port:=config.AsDefInt32('httptransportother.port', 8080);
end;
dmf.kbmMWUNIDACConnectionPool1.MinConnections:=config.AsDefint32('databasepool.minnum',5);
dmf.kbmMWUNIDACConnectionPool1.MaxConnections:=config.AsDefInt32('databasepool.maxnum',30);
dmf.kbmMWServer1.AutoRegisterServices;
dmf.kbmMWServer1.Active:=True;
syslog(LOG_NOTICE, 'http服务侦听地址:'+TkbmMWCrossSocketHttpServerTransport(dmf.RESTserverP).host);
syslog(LOG_NOTICE, 'http服务侦听端口:'+TkbmMWCrossSocketHttpServerTransport(dmf.RESTserverP).port.tostring);
syslog(LOG_NOTICE, '使用UNIDAC 数据访问控件' );
syslog(LOG_NOTICE, '数据库类型:'+ dmf.UniConnection1.ProviderName);
syslog(LOG_NOTICE, '数据库版本:'+ dmf.UniConnection1.ServerVersionFull);
syslog(LOG_NOTICE, '数据库:'+ dmf.UniConnection1.Database);
syslog(LOG_NOTICE, '数据库客户端版本:'+ dmf.UniConnection1.ClientVersion);
syslog(LOG_NOTICE, '最大数据库连接池数:'+ dmf.kbmMWUNIDACConnectionPool1.MaxConnections.ToString );
syslog(LOG_NOTICE, '服务启动:'+formatdatetime('yyyy-mm-dd hh:nn:ss',now));
end;
procedure xalionserverstop;
begin
dmf.kbmMWServer1.Active:=False;
syslog(LOG_NOTICE, '服务停止:'+formatdatetime('yyyy-mm-dd hh:nn:ss',now));
end;
procedure xalionserverrestart;
begin
xalionserverstop;
xalionserverstart;
end;
begin
if ParamCount = 0 then
begin
syslog(LOG_ERR, 'No parameters');
ExitCode := EXIT_FAILURE;
exit;
end;
if ParamStr(1).ToLower.Equals('stop') then
begin
if Daemon.Stop(30) then
ExitCode := EXIT_SUCCESS
else
ExitCode := EXIT_FAILURE;
exit;
end;
if ParamStr(1).ToLower.Equals('reload') then
begin
if Daemon.Reload() then
ExitCode := EXIT_SUCCESS
else
ExitCode := EXIT_FAILURE;
exit;
end;
if not ParamStr(1).ToLower.Equals('start') then
begin
syslog(LOG_ERR, 'Unknow parameters');
ExitCode := EXIT_FAILURE;
exit;
end;
syslog(LOG_NOTICE, 'main START');
while Daemon.IsRunning do
begin
syslog(LOG_NOTICE, 'main LOOP');
Daemon.Execute(AEvent);
if AEvent <> TEventType.None then
syslog(LOG_NOTICE, 'main Daemon receive signal');
case AEvent of
TEventType.Start :
begin
// syslog(LOG_NOTICE, 'main Event START');
xalionserverstart;
end;
TEventType.Reload :
begin
// Reload config
//syslog(LOG_NOTICE, 'main Event RELOAD');
xalionserverrestart;
end;
TEventType.Stop :
begin
ExitCode := EXIT_SUCCESS;
Sleep(10);
break;
end;
end;
Sleep(1000);
end;
end.
编译此文件,并拷入/home/xalion/smartsrv 目录。
用root 权限建立一个服务描述文件 xalionserver.service。
内容为:
[Unit]
Description=xalionserver service
After=network.target
[Service]
Type=simple
ExecStart=/home/xalion/smartsrv/Linuxdaemon start
ExecReload=/home/xalion/smartsrv/Linuxdaemon reload
ExecStop=/home/xalion/smartsrv/Linuxdaemon stop
Restart=on-failure
RestartSec=30
TimeoutStopSec=120
[Install]
WantedBy=multi-user.target
保存。
进入/etc/systemd/system/
建立一个链接文件
sudo ln -s /home/xalion/smartsrv/xalionserver.service xalionserver.service
可以看到链接文件已经建立好了。
启动这个服务
sudo systemctl start xalionserver.service
我们去日志文件看看,是否正常运行
sudo nano /var/log/syslog
可以看到,所有的功能正常开始运行。
也可以查看服务运行状态
systemctl status xalionserver.service
我们使用浏览器访问
现在就剩下了自启动了。
在/etc/systemd/system/multi-user.target.want 目录下,建立同样的文件。
重新启动Linux 服务器。
直接在客户端打开浏览,一切都正常。
整个过程非常流畅。
来源:oschina
链接:https://my.oschina.net/u/4378879/blog/4259152