Jump to content
borni69

WEB Standalone console APP “Indy http” in production ?

Recommended Posts

Hi today we run our backend API system on Linux Ubuntu using ISAPI mod files on Linux With apache in front.

We run this system in docker containers.


 

We have autoscale when the system reaches 80 simultane requests, it increases a new docker instance.  

 

Normal traffic 1 to 2 instances,   peak 3.

 

This means the Delphi app will never need to handle more than 80 requests at the same time.

 

We are considering to do this with a new setup using an Nginx proxy in docker, and then use standalone console APP to handle the requests.

 

Is this a good idea ?

Is a  standalone console APP  “Indy http”  ment for  production ?  or only test.

 

Hope to get some advice

 

Thanks

Share this post


Link to post

Hello,

 

I don't use ISAPI, but I've been running Indy servers 24/7 for several years now without any problems, so yes, Indy's fine for production. Just keep in mind that each connection runs in it's own thread, so if there are 80 concurrent connections, the server will be using 80 threads.

 

Kind Regards,

Sergio

Share this post


Link to post
30 minutes ago, esegece said:

Hello,

 

I don't use ISAPI, but I've been running Indy servers 24/7 for several years now without any problems, so yes, Indy's fine for production. Just keep in mind that each connection runs in it's own thread, so if there are 80 concurrent connections, the server will be using 80 threads.

 

Kind Regards,

Sergio

Thanks, we also use 80 threads today so this is the same  🙂.  

Share this post


Link to post

Hi !

Idem !

We have Indy based tenant Prod logs 60 connections "average" (so, 60 connections threads), with no problem at all.

As a detail, we have Nginx on front, fine configured, with geoip and ip2fail and few other tools. (Delphi servers have not to deal with server side ssh currently)

Architecture detail : Server only manage connections and context : it communicates throught our bus with "services" (which is standalone delphi linux console app) which perform workers duty. The Servers do not perfoms business stuffs directly.

 

Share this post


Link to post
2 hours ago, Vincent Gsell said:

Hi !

Idem !

We have Indy based tenant Prod logs 60 connections "average" (so, 60 connections threads), with no problem at all.

As a detail, we have Nginx on front, fine configured, with geoip and ip2fail and few other tools. (Delphi servers have not to deal with server side ssh currently)

Architecture detail : Server only manage connections and context : it communicates throught our bus with "services" (which is standalone delphi linux console app) which perform workers duty. The Servers do not perfoms business stuffs directly.

 

Thanks for this update 🙂  We will test it ...

Share this post


Link to post

I used two standalone Indy web server (https): one in a Linux server and one in a Windows 11 system. The web servers (Linux and Windows are the same, simple compiled for different OS) use a TLSv1_2 secure connection and were tested in one year with direct public connection without any filter.

SSLLabs (SSL Labs - Test SSL web server) give a valuation of "A" grade to the web server.

 

Tipically every day the application registered 1 thousand of attack, some are simple scanners like others are trying to violate the server. The web servers never went down.

 

With new processors and systems, the number of the Threads is not a problem.

 

I think that Indy is more than mature to use in a production enviroment.

 

Bye

Share this post


Link to post

Sorry, but could you give an example of how you organize a loop in a linux console program and an Indy httpserver. Is there an option without a sleep() or while?
I need this program run forever or until I stop via route to webmodules action. Thanks

Share this post


Link to post
On 3/8/2023 at 2:06 PM, tgbs said:

Sorry, but could you give an example of how you organize a loop in a linux console program and an Indy httpserver. Is there an option without a sleep() or while?
I need this program run forever or until I stop via route to webmodules action. Thanks

 

Not sure I understand you but in Delphi you can.

1)   File -  New  - other  - Web - Web Server Application - 

 

-Wizzard

2 )  Then select Windows and Linux

3)  Stand alone Console app

4) port 8080

5) Complete

 

Add Linux and compile..  then it should work.

 

Maybe I misunderstood your question..

 

 

B

 

 

 

Share this post


Link to post
On 3/8/2023 at 2:06 PM, tgbs said:

Sorry, but could you give an example of how you organize a loop in a linux console program and an Indy httpserver. Is there an option without a sleep() or while?
I need this program run forever or until I stop via route to webmodules action. Thanks

Maybe this helps:

 

"How can I keep a Free Pascal console application running "forever"?"

https://stackoverflow.com/questions/14090697/how-can-i-keep-a-free-pascal-console-application-running-forever

 

(it is related to the Indy TIdHTTPServer also)

 

Basically a ReadLn could be a solution to keep the server running. But this does not answer the "or until I stop ..." part of your question and is worth a separate question. 

I suggest to ask the question as a new post in the Delphi-Third-Party / Indy subforum at https://en.delphipraxis.net/forum/35-indy/.

 

Edited by mjustin

Share this post


Link to post

@borni69 thanks. This is clear to me

 

4 hours ago, mjustin said:

Maybe this helps:

 

"How can I keep a Free Pascal console application running "forever"?"

https://stackoverflow.com/questions/14090697/how-can-i-keep-a-free-pascal-console-application-running-forever

 

(it is related to the Indy TIdHTTPServer also)

 

Basically a ReadLn could be a solution to keep the server running. But this does not answer the "or until I stop ..." part of your question and is worth a separate question. 

I suggest to ask the question as a new post in the Delphi-Third-Party / Indy subforum at https://en.delphipraxis.net/forum/35-indy/.

 

There are people here in this thread who are happy with this webserver. So far I haven't seen any other way to make it go forever other than some variant of looping. Either with sleep, or with CheckSynchronize. Readln for a Linux server doesn't sound serious to me. For my minor programs I have used sleep. And I use a webaction for example webserver:port/stopserver to stop it. I asked if there was a more elegant way to make this webserver work forever. Thanks

Share this post


Link to post

I don't use cosole application, i use a graphic (FMX) application (based on Indy demo).

This is for ease of use only. In fact, the FORM does nothing except handle events and start / stop the server.
All LOGs are sent to the console via writeln.

Exact same thing in Linux.

 

Now with TLS 1.3 support :classic_biggrin:

 

Bye

 

P.S.: There is one flaw in certificate management, which is that the certificate's private key must be exposed and accessible to the application. This may be a vulnerability if the server is accessed locally by third parties.

 

image.thumb.png.fe698a08b28ad9060d286cf49c03392b.png1722977267_SSLReport-Cloud.dyn-o-saur_com.thumb.png.6b647983a534f3aaae675785c3451783.png

Edited by DelphiUdIT

Share this post


Link to post
1 hour ago, DelphiUdIT said:

I don't use cosole application, i use a graphic (FMX) application (based on Indy demo).

This is for ease of use only. In fact, the FORM does nothing except handle events and start / stop the server.
All LOGs are sent to the console via writeln.

Exact same thing in Linux. 

 

Now with TLS 1.3 support :classic_biggrin:

 

Bye

 

P.S.: There is one flaw in certificate management, which is that the certificate's private key must be exposed and accessible to the application. This may be a vulnerability if the server is accessed locally by third parties.

 

Thanks but my question is for Linux server, without GUI.

Share this post


Link to post
2 hours ago, tgbs said:

Thanks but my question is for Linux server, without GUI.

I saw, but the main loop should be ... A LOOP .... and in a console app there aren't so many variants ....

 

It simply instantiates all objects at runtime (the graphical application you see instantiates everything at runtime, it's just for convenience and debugging that there is a graphical window).
 
In the main loop you can do:
var EndLife: boolean;
begin
	EndLife := false;
     // Runtime object creation
     // End
	{$IFDEF POSIX}
	//is used to intercept the CTRL-C, in order to terminate the program correctly
	sigIntHandler._u.sa_sigaction := @my_handler_ctrl_c;
	sigemptyset(sigIntHandler.sa_mask);
	sigIntHandler.sa_flags := SA_SIGINFO;
    sigaction(SIGINT, @sigIntHandler, 0);
	{$ENDIF}
	while not EndLife do
      begin
		//In here you can put for example a WAITFOR with 100ms timeout, you can update a log file, send an I'M ALIVE, capture a variable to stop / start the web server
		.........
	   end;
     // Runtime object destruction
     // End
end;

//Capture CTRL-C, CTRL-BREAK, LOGOFF, SHUTDOWN, CLOSE ... events. I DIDN'T TEST THEM !!!
{$IFDEF POSIX}
procedure my_handler_ctrl_c(segnale: integer; segnale_info: Psiginfo_t; context: Pucontext_t);
begin
  //writeln('Caught signal ', segnale);
  EndLife := True;
  _exit(1);
end;
{$ENDIF}

 

These are simply an advise, i don't test it but i think may be a start point.

 

Bye

Edited by DelphiUdIT

Share this post


Link to post
4 hours ago, tgbs said:

So far I haven't seen any other way to make it go forever other than some variant of looping. Either with sleep, or with CheckSynchronize.

I have not used it in my programs, but SyncObjs.TEvent seems to be standard practice (and should be available on the Linux platform)

Draft code:
 

begin
  HttpServer := TMyHttpServer.Create;
  try
    HttpServer.Start;
    // now the server is processing requests
    // wait for terminate signal
    while MyEvent.WaitFor(MaxInt) <> wrSignaled do;
    // now terminate
    HttpServer.Stop;
  finally
    HttpServer.Free;
  end;
end;

The handler code for the http://webserver:port/stopserver URL would call MyEvent.SetEvent, and this will cause to leave the WaitFor loop.

Edited by mjustin
call HttpServer.Stop
  • Like 1

Share this post


Link to post
On 3/11/2023 at 8:58 AM, mjustin said:

// now the server is processing requests
// wait for terminate signal
while MyEvent.WaitFor(MaxInt) <> wrSignaled do;

 

Why are you using MaxInt for the timeout, and not simply using Infinite instead?  Then you can get rid of the while loop.

// now the server is processing requests
// wait for terminate signal
MyEvent.WaitFor(Infinite);

 

  • Like 1
  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×