[OGo-Users] ogo with alot of users

Martin Saini users@opengroupware.org
Wed, 19 Jan 2005 13:26:04 +0100


hi!

helge told me how to balance ogo with apache - here my update and config 
how I handle >2500 users with ogo.

first i have to say ther are 4 instances - 4 databases, one of them 1400 
users. the other 3 are smaller.
the problem i was faced with was the single ogo process handling all the 
requests. The solution for this is to start
many webui processes with different ports, all working with the same 
database. So i have 10 webui processes per instance.
now you have to balance the users between this webui-processes. I have 
no idea which ip-addresses the customers are using,
so for me it was not possible to balance them source-ip based. I found 
another nice thing for that: apache RewriteEngine (mod rewrite) with 
random function.

here a small example:

in httpd.conf
<virtualhost.....
.....
    RewriteMap ogo rnd:/etc/apache/rewrite/randomports.conf
    RewriteRule ^/ogo1(.*) /${ogo:ogo1} [R]

....
</virtualhost>

randomports.conf:
ogo1         20000|20001|20002|20003|20004|20005|20006|20007|20008|20009

for example the url: http:/hostname/ogo1 is rewritten to 
http:/hostname/[20001|20002|.....]

i am using debian, so in 
/etc/opengroupware.org/instancename/mod_ngobjweb.conf i have

<LocationMatch "^/20000/*">
    SetHandler ngobjweb-adaptor
    SetAppPort 20000
</LocationMatch>
<LocationMatch "^/20001/*">
    SetHandler ngobjweb-adaptor
    SetAppPort 20001
</LocationMatch>
<LocationMatch "^/20002/*">
    SetHandler ngobjweb-adaptor
    SetAppPort 20002
</LocationMatch>

....
... and so on.

of course you can also define this in httpd.conf

also (i don't know if the structur is the same with other distributions) 
in /etc/opengroupware.org/instancename/init.conf
i have changed some things to automatically start more than one 
webui-program.
here it is:


USER=ogo_username
WEBUI_VERSION=1.0a
WEBUI_PORT="20000 20001 20002 20003 20004 20005 20006 20007 20008 20009"
ZIDESTORE_VERSION=
ZIDESTORE_PORT=21000
XMLRPCD_VERSION=1.0a
XMLRPCD_PORT=22000
NHSD_VERSION=

so you see i have all the ports configured here.

to start webuis on this ports i have changed the init-script:

#!/bin/sh
#
# Initscript for the OpenGroupware.org application server
#
# This init script can handle multiple instances of OpenGroupware.org.
# Each instance needs a subdirectory in /etc/opengroupware.org with its
# instance name. In this directory there must be an init.conf which sets
# the following variables:
# ------------------------------------------------------------------------
# USER=
# WEBUI_VERSION=
# WEBUI_PORT=
# ZIDESTORE_VERSION=
# ZIDESTORE_PORT=
# XMLRPCD_VERSION=
# XMLRPCD_PORT=
# NHSD_VERSION=
# ------------------------------------------------------------------------
# These variables specify the user that shall execute the daemons (which
# must exist and needs the necessary application defaults set), as well
# as versions and listening ports for the respective daemons.
#
# You can use the ogo-create-instance script to easily create a user with
# all necessary defaults set, along with a proper instance entry in
# /etc/opengroupware.org.

WEBUIAPP=ogo-webui
ZSAPP=ogo-zidestore
XMLRPCAPP=ogo-xmlrpcd
NHSDAPP=ogo-nhsd
DPATH=/usr/sbin

clear_vars () {
    USER=
    WEBUI_VERSION=
    ZIDESTORE_VERSION=
    NHSD_VERSION=
    XMLRPCD_VERSION=
}

should_start () {
    if [ "$START_AT_BOOT" = "false" ]; then
        echo "OpenGroupware.org web application server not started as 
requested"
        exit 0
    fi
}

case "$1" in
    start)
        should_start
        echo -n "Starting OpenGroupware.org server instances:"
    for i in /etc/opengroupware.org/*/init.conf; do
        clear_vars
        . $i
        USER_HOME=$(getent passwd ${USER} | awk -F: '{print $6}')
        if [ "$WEBUI_VERSION" != "" ]; then
            for port in $WEBUI_PORT; do
                if ! test -d "${USER_HOME}/${port}"; then
                    mkdir "${USER_HOME}/${port}"
                    chown ${USER} "${USER_HOME}/${port}"
                fi
                if test -f "${USER_HOME}/${port}/core"; then
                    mv \
                        "${USER_HOME}/${port}/core" \
                        "${USER_HOME}/core.${port}.$( \
                            ls -gG --time=ctime --time-style='+%F_%k:%M' 
"${USER_HOME}/${port}/core" \
                            | sed -n 's/^.*  *\([0-9 -]*_[0-9 
:]*[0-9]\).*$/\1/p' \
                            | tr ' ' '0' \
                        )"
                fi
                ulimit -c unlimited
                start-stop-daemon -S -c ${USER} -a /usr/bin/daemon \
                    -n ${WEBUIAPP}-${WEBUI_VERSION}-${port} -- \
                    --respawn \
                    -c \
                    -D ${USER_HOME}/${port} \
                        -e "USER=${USER}" \
                        -F ${USER_HOME}/webui_${port}.pid -X 
"${DPATH}/${WEBUIAPP}-${WEBUI_VERSION} -WOPort ${port}" \
                        -O 
/var/log/opengroupware.org/${USER}/webui_${port}.debug \
                        -E 
/var/log/opengroupware.org/${USER}/webui_${port}.log
            done
        fi
        if [ "$ZIDESTORE_VERSION" != "" ]; then
        start-stop-daemon -S -u ${USER} -c ${USER} -a /usr/bin/daemon -n 
${ZSAPP}-${ZIDESTORE_VERSION} -- \
            -F ${USER_HOME}/zidestore.pid -X 
"${DPATH}/${ZSAPP}-${ZIDESTORE_VERSION} -WOPort ${ZIDESTORE_PORT}" \
            -O /var/log/opengroupware.org/${USER}/zidestore.debug \
            -E /var/log/opengroupware.org/${USER}/zidestore.log
        fi
        if [ "$XMLRPCD_VERSION" != "" ]; then
        start-stop-daemon -S -u ${USER} -c ${USER} -a /usr/bin/daemon -n 
${XMLRPCAPP}-${XMLRPCD_VERSION} -- \
            -F ${USER_HOME}/xmlrpcd.pid -X 
"${DPATH}/${XMLRPCAPP}-${XMLRPCD_VERSION} -WOPort ${XMLRPCD_PORT}" \
            -O /var/log/opengroupware.org/${USER}/xmlrpcd.debug \
            -E /var/log/opengroupware.org/${USER}/xmlrpcd.log
        fi
        if [ "$NHSD_VERSION" != "" ]; then
        start-stop-daemon -S -u ${USER} -c ${USER} -a /usr/bin/daemon -n 
${NHSDAPP}-${NHSD_VERSION} -- \
            -F ${USER_HOME}/nhsd.pid -X 
"${DPATH}/${NHSDAPP}-${NHSD_VERSION}" \
            -O /var/log/opengroupware.org/${USER}/nhsd.debug \
            -E /var/log/opengroupware.org/${USER}/nhsd.log
        fi
   
        echo -n " ${USER}"   
    done
    echo "."
    ;;

    stop)
        echo -n "Stopping OpenGroupware.org web application server 
instances:"
    for i in /etc/opengroupware.org/*/init.conf; do
        clear_vars
        . $i
        USER_HOME=$(getent passwd ${USER} | awk -F: '{print $6}')
        for port in $WEBUI_PORT; do
            if test -f "${USER_HOME}/${port}/core"; then
                mv \
                    "${USER_HOME}/${port}/core" \
                    "${USER_HOME}/core.${port}.$( \
                        ls -gG --time=ctime --time-style='+%F_%k:%M' 
"${USER_HOME}/${port}/core" \
                        | sed -n 's/^.*  *\([0-9 -]*_[0-9 
:]*[0-9]\).*$/\1/p' \
                        | tr ' ' '0' \
                    )"
            fi
            if [ -f ${USER_HOME}/webui_${port}.pid ]; then
                start-stop-daemon -K -p ${USER_HOME}/webui_${port}.pid -o
            fi
            if test -f "${USER_HOME}/${port}/core"; then
                mv \
                    "${USER_HOME}/${port}/core" \
                    "${USER_HOME}/core.${port}.$( \
                        ls -gG --time=ctime --time-style='+%F_%k:%M' 
"${USER_HOME}/${port}/core" \
                        | sed -n 's/^.*  *\([^ ]*_[^ ]*\).*$/\1/p' \
                    )"
            fi
        done
        if [ -f ${USER_HOME}/zidestore.pid ]; then
            start-stop-daemon -K -p ${USER_HOME}/zidestore.pid -o
        fi
        if [ -f ${USER_HOME}/xmlrpcd.pid ]; then
            start-stop-daemon -K -p ${USER_HOME}/xmlrpcd.pid -o
        fi
        if [ -f ${USER_HOME}/nhsd.pid ]; then
            start-stop-daemon -K -p ${USER_HOME}/nhsd.pid -o
        fi
        echo -n " ${USER}"
    done
    echo "."
        ;;
    move-coredumps)
        echo -n "Moving away OpenGroupware.org coredumps for instance: "
    for i in /etc/opengroupware.org/*/init.conf; do
        clear_vars
        . $i
        USER_HOME=$(getent passwd ${USER} | awk -F: '{print $6}')
        for port in $WEBUI_PORT; do
            if test -f "${USER_HOME}/${port}/core"; then
                mv \
                    "${USER_HOME}/${port}/core" \
                    "${USER_HOME}/core.${port}.$( \
                        ls -gG --time=ctime --time-style='+%F_%k:%M' 
"${USER_HOME}/${port}/core" \
                        | sed -n 's/^.*  *\([0-9 -]*_[0-9 
:]*[0-9]\).*$/\1/p' \
                        | tr ' ' '0' \
                    )"
            fi
        done
        echo -n " ${USER}"
    done
    echo "."
        ;;
    show-coredumps)
        find /ext/ogo/opengroupware.org -name "core.*" | sort -t. -k4
        ;;
    restart|force-reload)
        $0 stop
    sleep 1
        $0 start
        ;;
    reload)
        echo "Can't reload configuration without restarting. Use 
/etc/init.d/opengroupware.org restart."
        exit 0
        ;;
    *)
        echo "Usage: /etc/init.d/opengroupware.org 
{start|stop|reload|force-reload|restart}"
        exit 1
        ;;
esac


This setup is working quite nice, i have a small performance problem 
with searching addressbooks for private entries.
This takes quite a time, i think this is because of permission-lookups 
in the database???? may it is possible to
optimize the queries?? i have about 5000 records in the addressbook.

regards
martin