borni69 1 Posted March 3, 2023 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
esegece 47 Posted March 3, 2023 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
borni69 1 Posted March 3, 2023 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
Vincent Gsell 11 Posted March 3, 2023 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
borni69 1 Posted March 3, 2023 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
DelphiUdIT 176 Posted March 4, 2023 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
tgbs 14 Posted March 8, 2023 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
borni69 1 Posted March 10, 2023 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
mjustin 23 Posted March 11, 2023 (edited) 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 March 11, 2023 by mjustin Share this post Link to post
tgbs 14 Posted March 11, 2023 @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
DelphiUdIT 176 Posted March 11, 2023 (edited) 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 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. Edited March 11, 2023 by DelphiUdIT Share this post Link to post
tgbs 14 Posted March 11, 2023 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 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
DelphiUdIT 176 Posted March 11, 2023 (edited) 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 March 11, 2023 by DelphiUdIT Share this post Link to post
mjustin 23 Posted March 11, 2023 (edited) 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 March 11, 2023 by mjustin call HttpServer.Stop 1 Share this post Link to post
Remy Lebeau 1398 Posted March 13, 2023 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); 1 1 Share this post Link to post
borni69 1 Posted April 14 (edited) deleted... Edited April 14 by borni69 Share this post Link to post