Workers/Clients Best Practices for good performance

57 views
Skip to first unread message

Michael Huys

unread,
Sep 26, 2019, 9:27:46 AM9/26/19
to Mojolicious
  • Mojolicious version: Unknown
  • Perl version: v5.16.3
  • Operating system: Red Hat Enterprise Linux Server release 7.6 (Maipo)

Steps to reproduce the behavior

Currently our application is quite slow, surely if a lot of EU's (+- 100) are connected. Our application is loadbalanced over 2 servers with below specs:

  • 12vCPU
  • 48Gb Ram

This is our Mojolicious configuration:

{
#
# Logging
#

log => {
    path  => $app->home() . '/var/log/otrs.WebServer.log',
    level => 'warn',
},

#
# Production Webserver ("Hypnotoad")
#

hypnotoad => {

    # Full path to the web server pid file. Don't change this, otherwise automatic web server reloading
    #   from the application will not work any more.
    pid_file => $app->home() . '/var/run/otrs.WebServer.pid',

    # One or more locations/ports to listen on incoming connections. Examples:
    #
    # Listen on all IPv4 interfaces
    # listen => [ 'http://*:8080' ],
    #
    # Localhost and an IPv4 on port 8080
    # listen => [ 'http://localhost:8080', 'http://192.168.1.1:8080' ],
    #
    # IPv6 on port 8080
    # listen => ['http://[::1]:8080'],
    #
    # HTTPS with custom certificate and key
    # listen => ['https://*:8443?cert=/etc/ssl/cert/otrs.crt&key=/etc/ssl/private/otrs.key'],
    #
    listen => ['http://localhost:8080'],

    # The number of worker processes to serve incoming requests.
    workers => 25,

    # Number of temporarily spawned workers, which allows new workers to be started while old ones are still
    # shutting down. This will reduce the performance costs of worker restarts.
    spare => 10,

    # Maximum number of connections, which will be accepted by each worker concurrently.
    clients => 20,

    # Maximum number of connections, which will be accepted by each worker, before it will be stopped and
    # replaced by a new one.
    # Setting this value to 0 causes the server to never stop workers after a certain amount of connections.
    accepts => 5000,

    # Maximum amount of time in seconds stopping a worker gracefully may take before being forced.
    graceful_timeout => 120,

    # Maximum amount of time in seconds before a worker without a heartbeat will be stopped gracefully.
    # Note that this value should usually be a little larger than the maximum amount of time you
    #   expect any one operation to block the event loop.
    heartbeat_timeout => 120,

    # Maximum amount of time in seconds a connection can be inactive before getting closed.
    inactivity_timeout => 120,

    # Activate support for operation behind a reverse proxy. This allows for the X-Forwarded-For and
    #   X-Forwarded-Proto headers to be picked up automatically by the server to identify the remote address.
    #
    # This should be set to 0 if using the Mojolicious web server directly without a reverse proxy in front of it,
    #   for security reasons.
    proxy => 1,
},

#
# Limits
#

max_request_size => 64 * 1024 * 1024,

#
# Websocket
#

websocket => {
    # Websocket heartbeat check settings in seconds.
    ping_interval      => 20,
    pong_timeout       => 10,
    inactivity_timeout => 30,
},

#
# Debugging
#

enable_debugger_http_trace    => 0,
enable_debugger_sql_trace     => 0,
enable_debugger_stderr_log    => 0,
enable_debugger_perl_profiler => 0,

};
`

Expected behavior

Good performance


Actual behavior

Bad performance ;-)

Any suggestions on the "Workers" and "Clients" setting? Like already said the application behaves performant if only 10 users are logged on. Once we go over 50 eu's application is going slower and slower.
We were thinking of increasing the workers a little bit more (eg. 30?) and decrease the clients to 5?
CPU usage on the servers are < 20%
Memory usage on the servers are < 50%

I know that this is dependent on your application, but the problem is that an external company has written this for us and they don't want to advice us on the best practice settings. :-(

sri

unread,
Sep 26, 2019, 9:32:22 AM9/26/19
to Mojolicious
I know that this is dependent on your application, but the problem is that an external company has written this for us and they don't want to advice us on the best practice settings. :-(

Without knowledge about what exactly the application does it's pretty much impossible to help
you. There is no one size fits all best practice for Mojolicious performance. Mojolicious is a
web framework that allows for many different paradigms to be used that all require different
optimizations.

--
sebastian

sri

unread,
Sep 26, 2019, 9:37:30 AM9/26/19
to Mojolicious
Side note: Please stop sending the same message over and over, they all go to the
moderation queue. And very soon Google will automatically block you from Groups
as a spammer.

--
sebastian

Stefan Adams

unread,
Sep 26, 2019, 9:38:18 AM9/26/19
to mojolicious
As @kraih said on the GitHub issue, "The correct configuration depends entirely on what the application does."

How you describe your issue sounds very similar to an issue I had.  For me, the problem was blocking vs. non-blocking code.  I had too much blocking code, to where practically no number of workers was sufficient to handle heavy usage.  My biggest problem, IIRC, was blocking code connecting to a database.  Now with Mojo::Pg, that's no longer an issue for me.

--
You received this message because you are subscribed to the Google Groups "Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mojolicious/93b1a43c-a7b2-4552-9029-c4171968c9a6%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages