服务器运维笔记+自动部署系统 nginx+tomcat+ant+memcached+awstats+qqhostinfo

之前系统采用的单一tomcat服务的模式,已经不能满足现阶段的需求了,经常宕机,因此决定换成nginx+tomcat+memcached的结构。

把所有的静态文件都交给nginx来处理,tomcat则只处理jsp、servlet,tomcat的session则托管给memcached实现集群;最后,用awstats来分析nginx的日志文件,用qqhostinfo这个插件在awstats中解析IP归属地。


说下文件夹的规划。把所有的东东都放到/app下。


/app/autodeploy :基于ant和svn的自动构建

/app/nginx           :nginx的配置文件、日志切割脚本、日志文件

/app/tomcat        :tomcat集群

/app/webapps   :web工程文件夹


安装JDK:这个就略过不说了,只要记得要export JAVA_HOME就行了

安装svn、ant :这两个都可以直接yum install来安装。

安装nginx       :网上有很多都是编译安装,我这情况比较简单,直接从官网上下载.rpm文件,安装得到nginx的资源库,然后再yum install安装nginx就行了。

安装tomcat    :这个直接下载后解压缩就行了。

安装memcached:同样是yum install 就可以了。


好,我们第一步是先把nginx+tomcat+memcached的集群跑起来。


先配置两个tomcat,把memcached相关的jar包都放到tomcat/lib下面去,然后修改tomcat/conf/context.xml

<?xml version='1.0' encoding='utf-8'?>
<Context>
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <Manager
                className="de.javakaffee.web.msm.MemcachedBackupSessionManager" 
                memcachedNodes="n1:127.0.0.1:11211"
                sticky="false"
                sessionBackupAsync="true"
                lockingMode="uriPattern:/path1|/path2"
                requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
                transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
                />
</Context>

然后修改server.xml,把tomcat-user.xml这个文件提取到其他文件夹,让多个tomcat共用这个文件。

多个tomcat做负载均衡,让每个tomcat的端口不一样、jvmRoute名字不一样。

<?xml version='1.0' encoding='utf-8'?>
<Server port="8105" shutdown="SHUTDOWN">
        <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
        <Listener className="org.apache.catalina.core.JasperListener" />
        <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
        <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
        <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

        <GlobalNamingResources>
                <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="/app/tomcat/tomcat-users.xml" />
        </GlobalNamingResources>

        <Service name="Catalina">
                <Executor name="tomcatThreadPool" namePrefix="catalina1-exec-" maxThreads="1000" minSpareThreads="200"/>
                <Connector
                        port="8081"
                        redirectPort="8543"
                        protocol="HTTP/1.1"
                        connectionTimeout="60000"
                        enableLookups="false"
                        executor="tomcatThreadPool"
                        acceptCount="1200"
                        URIEncoding="UTF-8"
                        compression="on"
                        compressionMinSize="2048"
                        noCompressionUserAgents="gozilla,traviata"
                        compressableMimeType="text/html,text/json,application/javascript,text/javascript,text/css,text/plain,text/xml" />

                <Connector port="8109" protocol="AJP/1.3" redirectPort="8543" />

                <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
                        <Realm className="org.apache.catalina.realm.LockOutRealm">
                                <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
                        </Realm>
                        <Host name="localhost" appBase="/app/webapps" unpackWARs="true" autoDeploy="true">
                                <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
                        </Host>
                </Engine>
        </Service>
</Server>


接下来,就是把tomcat里面的webapps文件夹复制成 /app/webapps,这样,ROOT就用来放自己的工程文件,manager文件夹就用来监控tomcat的状态。


另外,再配置一下tomcat的内存,修改tomcat/bin/catalina.sh,在文件开头加入下面这句,-server是为了给多个CPU提升性能,另外两个是分配内存,根据实际情况来就可以了。

export JAVA_OPTS="-server -Xms3072m -Xmx25600m"

OK,到这里,tomcat的配置就算是OK了。 


下面,开始nginx的配置。

nginx的默认配置文件是/etc/nginx/nginx.conf,但是这个文件,一要root权限,二是分散不好管理,我把nginx.conf移到/app/nginx/nginx.conf,再链接成/etc/nginx/nginx.conf就完事了。


user  nginx;
worker_processes  16;

error_log  /app/nginx/logs/error.log warn;
pid        /var/run/nginx.pid;

events {
    use epoll;
    worker_connections  1024;
}


http {

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /app/nginx/logs/access.log  main;

    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 8 32k;
    client_max_body_size 30m;
    client_body_buffer_size 1024k;

    sendfile    on;
    tcp_nopush  on;
    tcp_nodelay on;

    keepalive_timeout  65;

    gzip            on;
    gzip_vary       on;
    gzip_min_length 1k;
    gzip_buffers    4 16k;
    gzip_types      text/plain application/x-javascript text/css application/xml;

    upstream tomcat{
        server 127.0.0.1:8081 weight=1;
        server 127.0.0.1:8082 weight=1;
    }

    server{

        listen      80;
        server_name localhost;
        index index.html;
        root /app/webapps/ROOT;
        error_page  404 = /404.html;
        error_page  500 502 503 504 = /50x.html;


        location ~ .*.(do|jsp)$ {
            index index.jsp;
            proxy_redirect  off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://tomcat;
            proxy_connect_timeout 10;
            proxy_read_timeout 10m;
            proxy_buffer_size 4k;
            proxy_buffers 64 32k;
        }

        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
            expires      10d;
        }

        location ~ .*\.(js|css)?$ {
            expires      1d;
        }

        location ~ ^/awstats/ {
            index awstats.qht.html;
            access_log off;
            error_log off;
            charset gb2312;
            auth_basic "";
            auth_basic_user_file /app/nginx/admin.pass; #用htdpasswd生成
        }

    }

}

文件里awstats的股份,是用来做日志分析的,后面再讲。 upstream 就是用来搞负载均衡的了,把.jsp和.do的请求都给了tomcat,其他的都nginx拦截下来。图片缓存10天,js缓存1天。


配置好了,启动memcached先,用service来启动。

现在就可以启动nginx和tomcat了,至于具体先启动哪一个,没啥特别的讲究。nginx可以用service来启动,tomcat就暂时用普通用户的身份通过startup.sh启动就行了。

# service nginx start

现在,tomcat+nginx的集群就应该可以正常工作了。 


由于nginx的轻量,日志文件不会自动切割,几天下来生成的access.log文件就上G了,肯定不行的了,得切割。 用脚本实现。

#!/bin/bash
# Script Name: nginx-log-split.sh
# Author: xiaosilent@gmail.com
# Create Date: 2012-12-14

LOG_PATH=/app/nginx/logs
DATE=$(date -d yesterday +%Y-%m-%d)

cd $LOG_PATH

mv access.log access_$DATE.log
mv error.log error_$DATE.log

kill -USR1 $(cat /var/run/nginx.pid)

很简单的脚本,就实现了自动切割, 然后,我们把任务加入到crontab,这样就不用手工搞了。每天晚上12点弄一下就可以了,这就保证每天一个日志文件了。

# crontab -e

出来vi的界面,把脚本加入进去就行了。

00 00 * * * /app/nginx/nginx-log-split.sh

00 01 * * * /usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=qht

00 10 * * * /usr/local/awstats/tools/awstats_buildstaticpages.pl -update -config=qht -lang=cn -dir=/app/webapps/ROOT/awstats -awstatsprog=/usr/local/awstats/wwwroot/cgi-bin/awstats.pl

先说下,后面的两个脚本,是用来自动生成awstats的报告的。


前面已经两处出现awstats相关的东西了,现在就说下。 从官网上下载rpm然后安装,安装好后的文件在/usr/local/awstats。

把qqhostinfo相关文件传到/usr/local/awstats/wwwroot/cgi-bin/plugins下面,把pm和pl文件里的关于qqwry.dat文件的路径改成绝对路径

执行下 /usr/local/awstats/tools/awstats_configure.pl文件,第一个问题要求输入web server路径的时候填写none,因为我们用的是nginx。后面的都默认。

然后修改/etc/awstats/awstats.domain.conf文件,指定其中的LogFile,然后再跟着加一句: LogdPlugin "qqhostinfo" 就搞定了。


把上面crontab里面的后两个命令搞一遍,就可以访问到统计信息了。




最后贴下自动部署的脚本:

#!/bin/bash
# Script Name: autodeploy.sh
# Description: auto deploy QHT on CentOS
# Author: xiaosilent@gmail.com
# Create Date: 2012-10-16
# Update Date: 2012-12-14


echo "step1. 载入全局变量..."
source /etc/profile

echo "step2. 输出新的环境变量..."
export TOMCAT_HOME=/app/tomcat
export DEPLOY_HOME=/app/autodeploy
export WEBAPPS_HOME=/app/webapps

echo "step3. 生成内部临时变量..."
SOURCE_DIR=$DEPLOY_HOME/source
VERSION_FILE=$DEPLOY_HOME/svn.txt

echo "step4. 删除旧版本号..."
rm -rf $VERSION_FILE


echo "step5. 清理并更新源代码..."
svn cleanup $SOURCE_DIR
svn update  $SOURCE_DIR

echo "step6. 输出新版本号..."
svnversion $SOURCE_DIR>$VERSION_FILE


echo "step7. 通过ANT构建系统,耗时较长..."
ant -f $DEPLOY_HOME/build.xml

function compile_js(){
for file in `ls $1`
do
    if [ -d $1/$file ]; then
        compile_js $1/$file
    else
        local path=$1/$file
        local name=$file
    fi
    if [ ${#path} -gt "0" ]; then
        java -jar $DEPLOY_HOME/compiler.jar --charset utf-8 --js $path --js_output_file $path.min
        echo "压缩JS:"$path
        mv $path.min $path
    fi
done
}

echo "step8. 最后压缩JS文件,耗时最长..."
compile_js $WEBAPPS_HOME/ROOT/resources/js

echo ""
echo ""
echo "final. 成功完成自动部署,如无意外,可以关闭PuTTY了。"
echo ""

<project name="build" default="build" basedir=".">
        <property environment="env" />
        <property name="tomcat.home" value="${env.TOMCAT_HOME}" />
        <property name="webapps.home" value="${env.WEBAPPS_HOME}" />
        <property name="project.dir" value="${basedir}/source" />
        <property name="path.dir" value="ROOT" />
        <property name="build.dir" value="${basedir}/build" />
        <property name="src.dir" value="${build.dir}/src" />
        <property name="web.dir" value="${build.dir}/WebContent" />
        <property name="class.dir" value="${web.dir}/WEB-INF/classes" />
        <property name="lib.dir" value="${web.dir}/WEB-INF/lib" />
        <tstamp>
                <format property="build.time" pattern="yyyy-MM-dd" />
        </tstamp>

        <path id="build.classpath">
                <fileset dir="${tomcat.home}/tomcat1/lib">
                        <include name="*.jar" />
                </fileset>
                <fileset dir="${lib.dir}">
                        <include name="*.jar" />
                </fileset>
                <pathelement location="${class.dir}" />
        </path>

        <target name="build">

                <echo>step7.1 删除可能已经存在的build文件夹</echo>
                <delete dir="${build.dir}" />

                <echo>step7.2 新建build文件夹及其附属文件夹</echo>
                <mkdir dir="${build.dir}" />
                <mkdir dir="${src.dir}" />
                <mkdir dir="${class.dir}" />
                <mkdir dir="${lib.dir}" />

                <echo>step7.3 复制Java源代码到build文件夹的src下</echo>
                <copy todir="${src.dir}" overwrite="true">
                        <fileset dir="${project.dir}/src" />
                </copy>

                <echo>step7.4 复制WebContent的源码到build文件夹的WebContent下</echo>
                <copy todir="${web.dir}" overwrite="true">
                        <fileset dir="${project.dir}/WebContent" />
                </copy>

                <echo>step7.5 在build文件夹下编译源码</echo>
                <javac fork="true" memoryinitialsize="512m" memorymaximumsize="1536m" srcdir="${src.dir}" destdir="${class.dir}" includes="**" encoding="utf-8" debug="true">
                        <classpath refid="build.classpath" />
                </javac>


                <echo>step7.6 将src下的非java文件复制到class文件夹下</echo>
                <copy todir="${class.dir}" overwrite="true">
                        <fileset dir="${src.dir}" excludes="**/*.java" />
                        <fileset file="${basedir}/svn.txt" />
                </copy>


                <echo>step7.7 关闭正在运行的Tomcat</echo>
                <!--
                以下注释掉的两种,是在windows平台上关闭Tomcat用的,分别是用bat和服务方式关闭。
                <exec executable="${tomcat.home}/bin/shutdown.bat" failοnerrοr="false" />
                <exec executable="net"><arg line=" stop Tomcat7" /></exec>
                下面注释掉的,是在Linux平台上,关闭服务方式启动的Tomcat。
                <exec executable="service"><arg line=" tomcat stop" /></exec>-->


                <exec executable="sh"><arg line=" ${tomcat.home}/tomcat1/bin/shutdown.sh" /></exec>
                <exec executable="sh"><arg line=" ${tomcat.home}/tomcat2/bin/shutdown.sh" /></exec>


                <echo>step7.8 暂停,休息5s</echo>
                <sleep seconds="5" />


                <echo>step7.9 删除原工程文件和Tomcat的work目录</echo>
                <delete dir="${webapps.home}/${path.dir}/resources" />
                <delete dir="${webapps.home}/${path.dir}/WEB-INF" />
                <delete dir="${tomcat.home}/tomcat1/work" />
                <delete dir="${tomcat.home}/tomcat2/work" />


                <echo>step7.10 将编译好的新版本程序复制到工程文件夹来</echo>
                <copy todir="${webapps.home}/${path.dir}">
                        <fileset dir="${web.dir}" />
                </copy>


                <echo>step7.11 重新启动Tomcat</echo>
                <!--以下注释掉的两种,是在windows平台上启动Tomcat用的,分别是用bat和服务方式启动。
                <exec executable="${tomcat.home}/bin/startup.bat" failοnerrοr="false" />
                <exec executable="net"><arg line=" start Tomcat7" /></exec>
                <exec executable="service"><arg line=" tomcat start" /></exec>-->


                <exec executable="sh"><arg line=" ${tomcat.home}/tomcat1/bin/startup.sh" /></exec>
                <exec executable="sh"><arg line=" ${tomcat.home}/tomcat2/bin/startup.sh" /></exec>


                <echo>step7.final OK 服务器基本部署已经完成,下面开始JS文件压缩操作!</echo>


        </target>
</project>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值