On Mon, Oct 06, 2008 at 01:07:49PM -0700, Gordon Mohr wrote:
> I can't find mention of this '-I' option elsewhere. (It's not in my
> 2.6.STABLE14-based man page.)
>
> Is there a writeup on this option anywhere?
>
> Did it only appear in later versions?
Right, sorry, it appeared in 2.7:
http://www.squid-cache.org/cgi-bin/cvsweb.cgi/squid/doc/squid.8.in
> Is there a long-name for the option that would be easier to search for?
No.
> I would be interested in seeing your scripts if there are other wrinkles
> to using Squid in this manner. We're currently using squid for
> load-balancing on dedicated dual-core machines, so one core is staying
> completely idle...
I'm including a perl script called 'multisquid' below that uses -I and
assumes that there are '.squid-N.conf' configure scripts where "N" is a
number 0, 1, etc. I'm also including a bash script 'init-squid' that
generates those from a squid.conf based on the number of subdirectories
under the cache_dir of the form 0, 1, etc (up to 4) exist. It makes
squid 0 a cache_peer parent of the others so it's the only one that
makes upstream connections, but they all can serve clients.
- Dave
> Dave Dykstra wrote:
> >Meanwhile the '-I' option to squid makes it possible to run multiple
> >squids serving the same port on the same machine, so you can make use of
> >more CPUs. I've got scripts surrounding squid startups to take
> >advantage of that. Let me know if you're interested in having them.
> >Currently I run a couple machines using 2 squids each on 2 bonded
> >gigabit interfaces in order to get over 200 Mbytes/second throughput.
> >
> >- Dave
------------------------------ multisquid ---------------------------
#!/usr/bin/perl -w
#
# run multiple squids.
# If the command line options are for starting up and listening on a
# socket, first open a socket for them to share with squid -I.
# If either one results in an error exit code, return the first error code.
# Writtten by Dave Dykstra, July 2007
#
use strict;
use Socket;
use IO::Handle;
use Fcntl;
if ($#ARGV < 2) {
print STDERR "Usage: multisquid squidprefix numsquids http_port [squid_args ...]\n";
exit 2;
}
my $prefix = shift(@ARGV);
my $numsquids = shift(@ARGV);
my $port = shift(@ARGV);
my $proto = getprotobyname('tcp');
if (!(($#ARGV >= 0) && (($ARGV[0] eq "-k") || ($ARGV[0] eq "-z")))) {
#open the socket for both squids to listen on if not doing an
# operation that doesn't use the socket (that is, -k or -z)
close STDIN;
my $fd;
socket($fd, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
setsockopt($fd, SOL_SOCKET, SO_REUSEADDR, 1) || die "setsockopt: $!";
bind($fd, sockaddr_in($port, INADDR_ANY)) || die "bind of port $port: $!";
}
my $childn;
for ($childn = 0; $childn < $numsquids; $childn++) {
if (fork() == 0) {
exec "$prefix/sbin/squid -f $prefix/etc/.squid-$childn.conf -I @ARGV" || die "exec: $!";
}
# get them to start at different times so they're identifiable by squidclient
sleep 2;
}
my $exitcode = 0;
while(wait() > 0) {
if (($? != 0) && ($exitcode == 0)) {
# Take the first non-zero exit code and ignore the other one.
# exit expects a byte, but the exit code from wait() has signal
# numbers in low byte and exit code in high byte. Combine them.
$exitcode = ($? >> 8) | ($? & 255);
}
}
exit $exitcode;
------------------------------ init-squid ---------------------------
#!/bin/bash
# This script will work with one squid or up to 4 squids on the same http port.
# The number of squids is determined by the existence of cache directories
# as follows. The main path to the cache directories is determined by the
# cache_dir option in squid.conf. To run multiple squids, create directories
# of the form
# `dirname $cache_dir`/$N/`basename $cache_dir`
# where N goes from 0 to the number of squids minus 1. Also create
# cache_log directories of the same form. Note that the cache_log option
# in squid.conf is a file, not a directory, so the $N is up one level:
# cache_log_file=`basename $cache_log`
# cache_log_dir=`dirname $cache_log`
# cache_log_dir=`dirname $cache_log_dir`/$N/`basename $cache_log_dir`
# The access_log should be in the same directory as the cache_log, and
# the pid_filename also needs to be in similarly named directories (the
# same directories as the cache_log is a good choice).
. /etc/init.d/functions
RETVAL=0
INSTALL_DIR=_your_base_install_dir_with_squid_and_utils_subdirectories_
#size at which rotateiflarge will rotate access.log
LARGE_ACCESS_LOG=1000000000
CONF_FILE=$INSTALL_DIR/squid/etc/squid.conf
CACHE_DIR=`awk '$1 == "cache_dir" {x=$3} END{print x}' $CONF_FILE`
CACHE_LOG=`awk '$1 == "cache_log" {x=$2} END{print x}' $CONF_FILE`
ACCESS_LOG=`awk '$1 == "access_log" {x=$2} END{print x}' $CONF_FILE`
squid_dirs()
{
# if $NUMSQUIDS is 1, echo the parameter, otherwise echo the parameter
# N times with $N before the basename of the parameter, where N is
# from 0 to $NUMSQUIDS-1
if [ $NUMSQUIDS = 1 ]; then
echo $1
return
fi
typeset N
N=0
while [ $N -lt $NUMSQUIDS ]; do
echo `dirname $1`/$N/`basename $1`
let N=$N+1
done
}
#see how many squid cache directories exist (up to 4)
NUMSQUIDS=0
for D in `NUMSQUIDS=4 squid_dirs $CACHE_DIR`; do
if [ ! -d $D ]; then
break
fi
let NUMSQUIDS=$NUMSQUIDS+1
done
if [ $NUMSQUIDS = 0 ]; then
NUMSQUIDS=1
SQUID=$INSTALL_DIR/squid/sbin/squid
PLURAL=""
else
PLURAL="s"
# create the squid.conf files for each squid
PID_FILENAME=`awk '$1 == "pid_filename" {x=$2} END{print x}' $CONF_FILE`
HTTP_PORT=`awk '$1 == "http_port" {print $2;exit}' $CONF_FILE`
SNMP_PORT=`awk '$1 == "snmp_port" {x=$2} END{print x}' $CONF_FILE`
ICP_PORT=`awk '$1 == "icp_port" {x=$2} END{print x}' $CONF_FILE`
ICP_PORT=`awk '$1 == "icp_port" {x=$2} END{print x}' $CONF_FILE`
#visible_hostname is the name that shows up in X-Cache and Via headers
VISIBLE_HOSTNAME=`awk '$1 == "visible_hostname" {x=$2} END{print x}' $CONF_FILE`
HOSTNAME=`hostname`
SQUID="$INSTALL_DIR/utils/sbin/multisquid $INSTALL_DIR/squid $NUMSQUIDS ${HTTP_PORT:-3128}"
CACHEBASE="$(dirname $CACHE_DIR)"
LOGBASE="$(dirname $(dirname $CACHE_LOG))"
PIDBASE="$(dirname $(dirname $PID_FILENAME))"
N=0
while [ $N -lt $NUMSQUIDS ]; do
SEDCMDS="-e \"s,$CACHEBASE/,$CACHEBASE/$N/,\""
if [ "$LOGBASE" != "$CACHEBASE" ]; then
SEDCMDS="$SEDCMDS -e \"s,$LOGBASE/,$LOGBASE/$N/,\""
fi
if [ "$PIDBASE" != "$CACHEBASE" ] && [ "$PIDBASE" != "$LOGBASE" ]; then
SEDCMDS="$SEDCMDS -e \"s,$PIDBASE/,$PIDBASE/$N/,\""
fi
NEWCONF=$INSTALL_DIR/squid/etc/.squid-$N.conf
rm -f $NEWCONF
eval sed $SEDCMDS $INSTALL_DIR/squid/etc/squid.conf | awk '
BEGIN{print "# DO NOT EDIT -- Automatically generated by '$0'";print}
/^[ \t#]*http_port[ \t]/ {
if (!got_http_port) {
#on first squid, add additional http_port after first one specified,
# or after first commented http_port if none specified
portnum=0
if (substr($0,1,1) != "#") portnum=$2
else if ("'$HTTP_PORT'" == "") {portnum=3128; print}
if (portnum != 0) {
print "#first port overridden by command line -I"
print "http_port", portnum
# have each squid also listen on their own port, the first one to
# be parent of others and the others for forced cache reloads
print "http_port", portnum - ('$N' + 1)
got_http_port=1
next
}
}
else if ((substr($0,1,1) != "#") && ("'$N'" != 0)) {
# only first squid listens on other http ports, skip this one
next
}
}
/^[ \t#]*snmp_port[ \t]/ {
#replace snmp_port with separate number for each squid
portnum=0
if (substr($0,1,1) != "#") portnum=$2
else if ("'$SNMP_PORT'" == "") {portnum=3401; print}
if (portnum != 0) {
portnum=portnum + '$N'
print "snmp_port", portnum
next
}
}
/^[ \t#]*icp_port[ \t]/ {
#only first squid listens on icp port
portnum=0
if (substr($0,1,1) != "#") portnum=$2
else if ("'$SNMP_PORT'" == "") {portnum=3130; print}
if (portnum != 0) {
if ("'$N'" != 0) portnum=0 # disables the icp port
print "icp_port", portnum
next
}
}
/^[ \t#]*cache_peer[ \t]/ {
#any squid after first one go only to first one as a cache_peer parent
if ("'$N'" != 0) {
if (substr($0,1,1) == "#") {
if (!got_cache_peer) {
#insert the line after the first commented-out one
print
portnum='${HTTP_PORT:-3128}' - 1
print "cache_peer localhost parent", portnum, "0 no-query"
got_cache_peer=1
next
}
}
else {
#skip any other uncommented cache_peer options on non-first squids
next
}
}
}
$1 == "visible_hostname" || /TAG: visible_hostname/ {
hostname=""
if (substr($0,1,1) != "#") hostname=$2
else if ("'$VISIBLE_HOSTNAME'" == "") {hostname="'$HOSTNAME'"; print}
if (hostname != "") {
print "visible_hostname",hostname "/'$N'"
}
}
{print}
' >$NEWCONF
chmod a-w $NEWCONF
let N=$N+1
done
fi
last_logline_has()
{
# if first parameter is 1, see if the last line of any of the cache logs
# of squids contains the other parameters; if the first parameter is 0,
# see if true for all of the cache logs
typeset ANY LDIR LFILE
ANY=$1
shift
for LDIR in $(squid_dirs $(dirname $CACHE_LOG)); do
LFILE=$LDIR/`basename $CACHE_LOG`
if tail -1 $LFILE | egrep -q "$*"; then
if [ "$ANY" = 1 ]; then
# found one match, return true
return 0
fi
else
if [ "$ANY" = 0 ]; then
# found one non-match, return false
return 1
fi
fi
done
# return true for ANY=0 (all matched), false for ANY=1 (none matched)
return $ANY
}
start_squid()
{
echo "Starting $NUMSQUIDS Squid${PLURAL}... "
$SQUID -DFS
# it can take a while to check out a large cache
LIMIT=60 # Number of Tries
a=1
while [ $a -le "$LIMIT" ]
do
a=$(($a+1))
sleep 10
$SQUID -k check
RETVAL=$?
if [ $RETVAL != 0 ] ; then
echo "Squid start failed!!!"
start_squid_fail
RETVAL=$?
break
else
if last_logline_has 0 "storeLateRelease: released" ;then
break
RETVAL=0
fi
fi
done
sleep 2
echo "done."
[ $RETVAL == 0 ]
}
start_squid_fail()
{
RETVAL=0
$SQUID -k shutdown 2>/dev/null|| true # in case all are not shut down
if last_logline_has 1 "(store_errors|faults)" ;then
echo "Clearing Caches and Restarting $NUMSQUIDS Squid${PLURAL}... "
for D in `squid_dirs $CACHE_DIR`; do
rm -rf $D/*
done
$SQUID -z
sleep 3
$SQUID -DFS
sleep 3
$SQUID -k check
RETVAL=$?
if [ $RETVAL != 0 ] ; then
echo "Squid start failed!!!"
$SQUID -k shutdown 2>/dev/null || true # in case all are not shut down
fi
else
echo "Script Can't Fix Squid Problem"
RETVAL=1
fi
[ $RETVAL == 0 ]
}
stop_squid()
{
echo -n "Stopping $NUMSQUIDS Squid${PLURAL}... "
$SQUID -k shutdown
RETVAL=$?
if [ $RETVAL != 0 ] ; then
echo "Squid stop failed!!!"
else
sleep 30
echo "done."
fi
[ $RETVAL == 0 ]
}
cleancache()
{
echo "Clearing Caches of $NUMSQUIDS Squid${PLURAL}... "
$SQUID -k shutdown 2>/dev/null||true # in case all are not shut down
for D in `squid_dirs $CACHE_DIR`; do
rm -rf $D/*
done
$SQUID -z
}
rotate()
{
echo "Rotating Caches of $NUMSQUIDS Squid${PLURAL}... "
$SQUID -k rotate
}
rotateiflarge()
{
for LDIR in $(squid_dirs $(dirname $ACCESS_LOG)); do
LFILE=$LDIR/`basename $ACCESS_LOG`
if [ "$(stat -c %s $LFILE)" -gt $LARGE_ACCESS_LOG ]; then
rotate
break
fi
done
}
start()
{
start_squid
[ $RETVAL == 0 ]
}
stop()
{
stop_squid
[ $RETVAL == 0 ]
}
case "$1" in
start)
cleancache
start
;;
stop)
stop
;;
status)
$SQUID -k check 2>/dev/null
exit $?
;;
reload)
$SQUID -k reconfigure
;;
restart)
stop
start
;;
cleancache)
cleancache
;;
rotate)
rotate
;;
rotateiflarge)
rotateiflarge
;;
*)
echo $"Usage: $0 {start|stop|status|restart|reload|cleancache|rotate|rotateiflarge}"
exit 1
esac
Received on Mon Oct 06 2008 - 21:37:34 MDT
This archive was generated by hypermail 2.2.0 : Tue Oct 07 2008 - 12:00:03 MDT