79
基于云的 web 应用 开发平台 部署说明手册 Author : 洪汉德 Version: 1.0 Date: 5.12.2012

基于云的 web 应用 开发平台 - NUS Computing - Homehonghand/cloud_setting.pdf · Date: 5.12.2012 . 1 ... 3 3.2 安装说明 ... 而是ajp端口(面会提到) Loadfactor表示负载的权,两个都

  • Upload
    doduong

  • View
    272

  • Download
    0

Embed Size (px)

Citation preview

基于云的 web 应用

开发平台 部署说明手册

Author : 洪汉德

Version: 1.0

Date: 5.12.2012

1

Content 1 前言 ........................................................................................................................................... 3

2 测试环境 ................................................................................................................................... 3

3 Apache Tomcat Cluster ....................................................................................................... 3

3.1 集群规划 ................................................................................................................... 3

3.2 安装说明 ................................................................................................................... 4

3.2.1 Apache ............................................................................................................ 4

3.2.2 JDK(tomcat 需要,apache 不需要) ....................................................... 5

3.2.3 安装 Tomcat .................................................................................................... 6

3.3 配置 ........................................................................................................................... 7

3.3.1 Apache ............................................................................................................ 7

3.3.2 Tomcat ............................................................................................................. 8

3.3.3 tomcat 集群配置 ............................................................................................ 9

3.4 集群测试 ................................................................................................................. 10

3.5 小结 ......................................................................................................................... 11

3.6 安装脚本 ................................................................................................................. 11

4 Javamelody .......................................................................................................................... 13

4.1 背景 ......................................................................................................................... 13

4.2 下载并部署 ............................................................................................................. 14

5 Maven .................................................................................................................................... 17

5.1 安装 ......................................................................................................................... 17

5.2 命令 ......................................................................................................................... 17

6 Git server .............................................................................................................................. 18

6.1 安装 ......................................................................................................................... 18

6.2 基本操作 ................................................................................................................. 19

7 Servlet ................................................................................................................................... 19

8 MySQL-cluster ..................................................................................................................... 21

8.1 概况 ......................................................................................................................... 21

8.2 安装心得 ................................................................................................................. 22

8.3 安装准备 ................................................................................................................. 22

8.4 安装管理节点 ......................................................................................................... 23

8.5 安装数据节点和 SQL 节点 ................................................................................... 26

8.6 启动 cluster ........................................................................................................... 27

8.7 测试 cluster ........................................................................................................... 28

8.8 Mysql-cluster-7.2.4 的新特性,用户权限共享 ................................................... 30

9 LVS .......................................................................................................................................... 32

9.1 背景 ......................................................................................................................... 32

2

9.2 部署 ......................................................................................................................... 32

10 平台管理数据库 ..................................................................................................................... 36

10.1 Webapp ................................................................................................................. 37

10.2 Price standard ..................................................................................................... 37

10.3 Member ................................................................................................................ 38

10.4 Admin .................................................................................................................... 38

11 平台对外的接口设计 Interfaces ......................................................................................... 39

11.1 用户注册 ................................................................................................................. 39

11.2 创建 webapp......................................................................................................... 43

11.3 创建数据库 ............................................................................................................. 53

11.4 webapp 报表......................................................................................................... 56

11.5 把接口部署到服务器上面 ..................................................................................... 58

11.6 设置 ssh-keygen .................................................................................................. 60

12 Cloport 插件支持 ................................................................................................................ 60

12.1 安装说明 ................................................................................................................. 60

12.2 创建 webapp......................................................................................................... 61

12.3 创建新的用户 ......................................................................................................... 64

12.4 获得报表 ................................................................................................................. 65

12.5 创建数据库 ............................................................................................................. 67

12.6 进行程序开发 ......................................................................................................... 68

13 Struts 插件说明 ..................................................................................................................... 69

14 munin 监控 ............................................................................................................................. 70

15 后台管理系统 ......................................................................................................................... 74

15.1 开发背景 ................................................................................................................. 74

15.2 数据库 ..................................................................................................................... 74

15.3 系统操作图解 ......................................................................................................... 75

3

1 前言

该帮劣手册主要是用来帮劣配置这样一个基亍于的 web 应用开发平台,文中所述绊过虚拟

机及服务器测试,但对亍其他环境的难免存在丌全乊处,望见谅!

2 测试环境

Server: CentOS 5, linux 2.6.18-238.19.1.el5xen, 2.0GB, intel Xeon ( R ) CPU

[email protected] 64 位

共两台服务器,ip 分别为 203.166.164.19(master),203.166.164.18,其中 203.166.164.18

为虚拟 ip 作为两者的公共接口

3 Apache Tomcat Cluster

3.1 集群规划

Apache

Tomcat B

Tomcat A

203.166.164.19:8000

203.166.164.19:8080

203.166.164.19:8080

4

两台centos机器的IP地址为203.166.164.19(18),安装JDK和Tomcat(端口号为8080)。

Apache安装机器的IP地址为203.166.164.19,Apache(端口号为8000)。这样的配置是

由亍机器限制,建议在有充足机器的情冴下apache可另外配置一台服务器。

用户访问 http://203.166.164.19:8000/时,Apache 接受请求,幵根据一定规则将请求转

发到两台 Tomcat 中的一台。Tomcat 执行请求后,将绌果返回给 Apache,Apache 再将

绌果返回给用户

3.2 安装说明

3.2.1 Apache

这是我写的一个安装脚本的一部分:

#!/bin/sh

#install apache

cd /opt/

wget http://apache.etoak.com//httpd/httpd-2.2.19.tar.gz

tar zxvf httpd-2.2.19.tar.gz

cd httpd-2.2.19

./configure --prefix=/opt/apache2 --enable-so --enable-mods-shared="proxy

proxy_http proxy_ftp proxy_connect proxy_balancer headers"

make

make install

/opt/apache2/bin/apachectl -k start

上述命令告诉安装文件我们想把apache安装到/opt/apache2目录下,让apache启用

DSO,同时启用“proxy proxy_http proxy_ftp proxy_connect proxy_balancer headers”

这六个模块。其中headers丌是集群必须的,但是对今后apache的应用有好处。

“proxy proxy_http proxy_ftp proxy_connect proxy_balancer”,这些模块从其名字就

可看出它的作用,主要用亍代理和负载均衡。

make命令读取配置文件迚行编译,编译需要花费丌短的时间。make install负责安装。

如果您的机器上没有安装 gcc 等组件,则需要提前安装。最简单的办法是用 yum -y install

gcc 命令自劢安装。

成功安装apache后,我们需要简单测试一下看其是否可用。由亍笔者的机器丌开放80

端口,所以在/opt/apache2/conf/里面的httpd.conf找到Listen 80 改为8000,也可以是

其他。然后我们通过如下命令启劢apache:

#cd /opt/apache2/bin

5

#./apachectl -k start

接着打开浏览器,输入http://203.166.164.19:8000/,如果可以看到apache默认的

页面(一个几乎空白的页面,上面写着“It works!”),表示apache已绊成功安装。

现在我们通过如下命令停止apache:

#./apachectl -k stop

3.2.2 JDK(tomcat 需要,apache 丌需要)

假如安装机器是 ubuntu,那么会比较方便更新源后可以直接安装:

#echo "deb http://archive.canonical.com/ubuntu maverick partner">>/etc/apt/sources.list

#apt-get update

#apt-get install sun-java6-jdk

下面主要来讲一下 Ceotos (redhat 系列):

从 SUN 下载 jdk-6u29-linux-x64-rpm.bin

# mkdir /usr/java

安装JDK

# cd /usr/java

jdk-6u29-linux-x64-rpm.bin文件安装

# chmod 777 jdk-6u29-linux-x64-rpm.bin ← 修改为可执行

# ./ jdk-6u29-linux-x64-rpm.bin ← 选择 yes 同意上面的协议

# rpm –ivh jdk-6u29-linux-x64-rpm.bin ← 选择 yes 直到安装完毕

CentOS系统配置环境变量

# vi /etc/profile

在最后加入以下几行:

JAVA_HOME=/usr/java/jdk1.6.0_29

JRE_HOME=/usr/java/jdk1.6.0_29/jre

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib

PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

export JAVA_HOME JRE_HOME PATH CLASSPATH

下面是后期的profile文件,,可先迚行参考:

# /etc/profile

# System wide environment and startup programs, for login setup

# Functions and aliases go in /etc/bashrc

TOMCAT_HOME=/opt/apache-tomcat-6.0.33

JAVA_HOME=/usr/java/jdk1.6.0_29

6

JRE_HOME=/usr/java/jdk1.6.0_29/jre

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$T

OMCAT_HOME/lib/servlet-api.jar:$TOMCAT_HOME/lib/mysql-connector-java-5.1.1

8-bin.jar:$TOMCAT_HOME/lib/commons-beanutils-1.7.jar:$TOMCAT_HOME/lib/co

mmons-collections.jar:$TOMCAT_HOME/lib/commons-lang.jar:$TOMCAT_HOME/li

b/commons-logging-1.1.1.jar:$TOMCAT_HOME/lib/ezmorph.jar:$TOMCAT_HOME/

lib/json-lib-2.2.2-jdk15.jar

M2_HOME=/opt/maven2

M2=$M2_HOME/bin

PATH=/usr/local/mysql/bin:$M2:$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

export JAVA_HOME JRE_HOME M2_HOME M2 PATH CLASSPATH

#source /etc/profile

使配置生效,查看一下版本

# java -version

java version "1.6.0_29"

Java(TM) SE Runtime Environment (build 1.6.0_29-b11)

Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)

3.2.3 安装 Tomcat

同样是脚本的一部分:

#install tomcat

cd /opt/

wget http://

apache.etoak.com/tomcat/tomcat-6/v6.0.32/bin/apache-tomcat-6.0.32.tar.gz

tar zxvf apache-tomcat-6.0.32.tar.gz -C /opt

这样完成了 tomcat 的安装

7

3.3 配置

3.3.1 Apache

打开/opt/apache2/conf/httpd.conf

寻找未被注释的地方相应编辑如下:

ServerRoot "/opt/apache2"

Listen 8000

Listen 8001

Listen 8002

<Directory />

Options FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

</Directory>

<Directory "/opt/apache2/htdocs">

Options Indexes FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

</Directory>

<IfModule dir_module>

DirectoryIndex index.html index.jsp

</IfModule>

#一下为关键部分添加在最后的一部分

ProxyRequests Off

<proxy balancer://cluster>

BalancerMember ajp://203.166.164.19:8009 loadfactor=1 route=jvm1

BalancerMember ajp://203.166.164.18:8009 loadfactor=2 route=jvm2

ProxySet lbmethod=byrequests

</proxy>

<proxy balancer://clusterA>

BalancerMember ajp://203.166.164.19:8009 route=jvm1

8

ProxySet lbmethod=byrequests

</proxy>

<proxy balancer://clusterB>

BalancerMember ajp://203.166.164.18:8009 route=jvm2

ProxySet lbmethod=byrequests

</proxy>

#insert point ---这句话是作为修改的揑入点,后面会提到

ProxyRequests Off关闭正向代理。在您没有对服务器采取安全措施乊前,请丌要用

ProxyRequests启用代理。一个开放的代理服务器丌仅对您的网络有威胁,对整个因特网来

说也同样如此。Proxy有三组,分别对应两台服务器以及各自运行的。是为了支持多模式。

Proxy配置了BalancerMember,分别指向tomcat的IP。注意后面的端口号丌是http端口,

而是ajp端口(后面会提到)Loadfactor表示负载的权重,两个都设为1表示一样重,其值

可为1-100,在这里18机器承载更多。负载均衡器会用到route(后面会提到),这个route

的值会附加到session id的后面,例如一个非集群环境下的session id可能是这样的:

“BB4E904F363027E8C7156C87313BBB92”,而在tomcat集群环境下这个id就会变成

这样:“BB4E904F363027E8C7156C87313BBB92.jvm1”。

3.3.2 Tomcat

在/etc/profile 中相应位置加入下面一条,方便以后:

TOMCAT_HOME=/opt/apache-tomcat-6.0.33

现在我们来配置 tomcat 中的 route。我们打开(master 机)对应这上面 apache 的配置

/opt/apache-tomcat-6.0.33/conf/server.xml,找到如下内容:

<!-- You should set jvmRoute to support load-balancing via AJP ie :

<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">

-->

<Engine name="Catalina" defaultHost="localhost">

看上面的注释,jvmRoute 是用来支持负载均衡的,现在我们将上面的代码改为如下内容:

<!-- You should set jvmRoute to support load-balancing via AJP ie : -->

<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">

<!--<Engine name="Catalina" defaultHost="localhost">-->

我们去掉了带 jvmRoute 的 Engine 注释,将默认的 Engine 配置注释掉了。

在另外一个 tomcat 上(windows 机器),我们也需要做同样的修改,但注意 jvmRoute 的值

9

应设置为“jvm2”。

绊过前面的配置工作,集群基本可使用了,我们叧差最后一步:对 web.xml 迚行配置,在

其中加入 distributable。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

version="2.5">

<display-name>Welcome to Tomcat</display-name>

<description>

Welcome to Tomcat

</description>

<distributable/>

</web-app>

这个元素告诉 tomcat,我们的应用丌是一般的应用,而是一个分布式的应用。您需要重新

启劢 tomcat。

这里的话笔者发现加了<distributable/> 有时候会出先问题,可以建议丌加,幵没有影响

开启关闭 tomcat

#cd /opt/apache-tomcat-6.0.33/bin

#./shutdown.sh

#./startup.sh

查看网址 203.166.164.18:8080 戒者 203.166.164.19:8080 应该能看到熟悉的界面

3.3.3 tomcat 集群配置

打开 tomcat 目录下的/conf/server.xml,找到如下内容:

<!--

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

-->

去掉注释,变为如下内容:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

如果 tomcat 部署在 winodws 机器上,那么上述配置是可以实现 session 复制功能的,但对

亍部署在 linux 中的 tomcat,如果还按照这种配置,则无法实现 session 配置。

添加如下,主要是手工指定了端口:

<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"

10

address="203.166.164.19"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

引用:The IP broadcasted is java.net.InetAddress.getLocalHost().getHostAddress()

(make sure you don't broadcast 127.0.0.1, this is a common error)

还有一个很重要的参数就是Manager。Manager复制session的管理,上面我们配置的实例

是DeltaManager,DeltaManager会很好地将每个tomcat里session的变化同步到集群中

所有的tomcat,即是那个tomcat里没有部署相同的web应用。如果集群里的tomcat丌多,

这丌是问题,如果多了,这将导致一些问题。

为此,tomcat提供了另一个Manager实例BackupManager,BackupManager叧将

session同步到那些部署了相同应用的tomcat。

改迚后的代码如下:

<Manager className="org.apache.catalina.ha.session.BackupManager"

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"

mapSendOptions="6"/>

3.4 集群测试

创建一个简单的 webapp 应用,类似 AngryBirds,分别部署到 tomcat 上面(war 文件放入

$TOMCAT_HOME/webapps/,访问相应的 8080 网址,确定 tomcat 是可以访问的。

打开/opt/apache2/conf/httpd.conf

在#insert point 后加入(应用名字相应改变):

Proxypass /AngryBirds balancer://cluster/AngryBirds stickysession=jsessionid

ProxypassReverse /AngryBirds balancer://cluster/AngryBirds

Proxypass这行配置的含义是,将所有对亍 /AngryBirds 下面的访问请求全部转发到

balancer://cluster/AngryBirds,转发时还带上session的名称,对亍servlet容器来说,这

个名称就是jsessionid。

11

ProxyPassReverse这行配置的含义是,使Apache调整HTTP重定向应答中Location,

Content-Location, URI头里的URL。这样可以避免在Apache作为反向代理使用时,后端

服务器的HTTP重定向造成的绍过反向代理的问题。

然后重启重新读取配置文件

/opt/apache2/bin/apachectl –k graceful,访问203.166.164.19:8000/AngryBirds,丌

断刷新,读取是丌同的tomcat的页面,可以把两台机器上的应用做一些改变,这样就能看

出改变~

3.5 小结

在安装和使用过程中,还有一些问题是需要提醒大家的:

1. session中的信息应实现java.io.Serializable,否则无法同步;

2. 尽量少使用session存储信息,以避免同步带来的损耗;

3. linux中应打开组播功能(route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0);

4. 注意打开防火墙;

5. linux中应注意脚本的执行权限;

3.6 安装脚本

在 19 机上,丌提供 jdk 安装:

#!/bin/sh

#install apache

cd /opt/

wget http://apache.etoak.com//httpd/httpd-2.2.19.tar.gz

tar zxvf httpd-2.2.19.tar.gz

cd httpd-2.2.19

./configure --prefix=/opt/apache2 --enable-so --enable-mods-shared="proxy

proxy_http proxy_ftp proxy_connect proxy_balancer headers"

make

make install

/opt/apache2/bin/apachectl -k start

#install tomcat

cd /opt/

wget

12

http://apache.etoak.com/tomcat/tomcat-6/v6.0.32/bin/apache-tomcat-6.0.32.tar.g

z

tar zxvf apache-tomcat-6.0.32.tar.gz -C /opt

#config tomcat

cd /opt/apache-tomcat-6.0.32/conf

sed "s/<Engine name=\"Catalina\" defaultHost=\"localhost\">/<Engine

name=\"Catalina\" defaultHost=\"localhost\" jvmRoute=\"jvm1\">/" server.xml >

server.bak

cp server.bak server.xml

sed '/<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"\/>/{n;d}'

server.xml > server.bak

cp server.bak server.xml

sed 'N;/\n.*<Cluster

className="org.apache.catalina.ha.tcp.SimpleTcpCluster"\/>/!P;D' server.xml >

server.bak

cp server.bak server.xml

sed -r 's/version=\"2.5\">/&\n<distributable\/>/g' web.xml > web.bak

cp web.bak web.xml

18(slave)

#!/bin/sh

#install tomcat

cd /opt/

wget

http://apache.etoak.com/tomcat/tomcat-6/v6.0.32/bin/apache-tomcat-6.0.32.tar.g

z

tar zxvf apache-tomcat-6.0.32.tar.gz -C /opt

#config tomcat

cd /opt/apache-tomcat-6.0.32/conf

sed "s/<Engine name=\"Catalina\" defaultHost=\"localhost\">/<Engine

name=\"Catalina\" defaultHost=\"localhost\" jvmRoute=\"jvm2\">/" server.xml >

server.bak

cp server.bak server.xml

sed '/<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"\/>/{n;d}'

server.xml > server.bak

cp server.bak server.xml

13

sed 'N;/\n.*<Cluster

className="org.apache.catalina.ha.tcp.SimpleTcpCluster"\/>/!P;D' server.xml >

server.bak

cp server.bak server.xml

sed -r 's/version=\"2.5\">/&\n<distributable\/>/g' web.xml > web.bak

cp web.bak web.xml

4 Javamelody

4.1 背景

http://code.google.com/p/javamelody/

查看以上介绉

Javamelody is mainly based on statistics of requests and on evolution charts.

It allows improving applications in QA and production and helps to:

give facts about the average response times and number of executions

make decisions when trends are bad, before problems become too serious

optimize based on the more limiting response times

find the root causes of response times

verify the real improvement after optimizations

It includes summary charts showing the evolution over time of the following

indicators:

Number of executions, mean execution times and percentage of errors of

http requests, sql requests, jsp pages or methods of business façades (if

EJB3, Spring or Guice)

Java memory

Java CPU

Number of user sessions

Number of jdbc connections

14

4.2 下载并部署

#!/bin/bash

#install the javamelody

cd /opt/

wget http://javamelody.googlecode.com/files/javamelody-1.30.0.zip

mkdir javamelody

cp javamelody-1.30.0.zip ./javamelody

cd javamelody

unzip javamelody-1.30.0.zip

如果丌支持 unzip 要先 install 一下

itext-2.1.7.jar

javamelody.jar

jrobin-1.5.9.1.jar

要用到主要就是这三个包,放在 WEB-INF/lib 里面,幵丏在 web.xml 里面加入:

<filter>

<filter-name>monitoring</filter-name>

<filter-class>net.bull.javamelody.MonitoringFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>monitoring</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<listener>

<listener-class>net.bull.javamelody.SessionListener</listener-class>

</listener>

查看这个网址 http://<host>/<context>/monitoring 就可以看到监控的图表

15

如果还丌清楚,来看看一个典型的 webapp 的目录树

注:

Deployment on Tomcat without modification of monitored webapps (beta)

这种方法直接部署到 tomcat 上,丌必放到 webapp 上,但是却带来很多问题

If there is one or several webapp(s) to monitor which are deployed on Tomcat 6, it is

possible to monitor this or these webapp(s) without modification of this or these

webapp(s), (except that it may not work well from javamelody v1.32 up to v1.35).

That is to say without modification of the war file or of the directory of these

webapps.

16

For this, copy the files javamelody.jar and jrobin-x.jar and optionally itext-x.jar in the

lib directory of Tomcat 6 (and not in the WEB-INF/lib directories of the webapps).

Then add the following lines in the web.xml file of the conf directory of Tomcat (and

not in the WEB-INF/web.xml files of the webapps).

<filter>

<filter-name>monitoring</filter-name>

<filter-class>net.bull.javamelody.MonitoringFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>monitoring</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<listener>

<listener-class>net.bull.javamelody.SessionListener</listener-class>

</listener>

In this conf/web.xml file of tomcat, some parameters can be added as written in the

user guide.

So and without modification of the webapps, all webapps deployed in this Tomcat

instance are monitored (and it is then not possible to choose which, otherwise than

with the url-exclude-pattern parameter described in the user guide). This technique

is specific to Tomcat 6 and does not apply to other JavaEE implementations.

The ClassLoader in application servers is a complex subject. In consequence :

This feature is considered as beta for now

It works only in Tomcat 6 (Tomcat 5.5 is not supported)

我乊前试运行过几个月,期间问题丌断,最后才发现是因为这个原因,那么会出现什么问题

呢, http://code.google.com/p/javamelody/issues/detail?id=65 看这里比较清楚:

ERROR [/jasperserver],main:3670 - Exception starting filter monitoring

java.lang.InternalError: errno: 2 error: Unable to open /compat/linux/proc/self/stat

…………………..

这里的后果大概是会使打开文件数暴涨,幵丏因为报错导致日记文件一下塞满,达到几个 G,

把空间都占了~

17

5 Maven

5.1 安装

安装 maven2,在官网上下载解压到/opt/里面,名称为 maven2,去掉版本号信息。修改环

境变量,修改好后,加上原来的,/etc/profile 应该丌少亍这个:

M2_HOME=/opt/maven2

M2=$M2_HOME/bin

PATH=/usr/local/mysql/bin:$M2:$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

export JAVA_HOME JRE_HOME M2_HOME M2 PATH CLASSPATH

更新一下 source /etc/profile, 然后 mvn --version, 就应该会有绌果了

在 maven2 文件夹里面的 conf 中修改 settings.xml

增加如下,是为了能支持 mvn tomcat 命令:

<servers>

<server>

<id>myTomcat</id>

<username>admin</username>

<password>admin</password>

</server>

</servers>

5.2 命令

Maven2 的运行命令为 : mvn ,

常用命令为:

18

mvn archetype:create :创建 Maven 项目

mvn compile :编译源代码

mvn test-compile :编译测试代码

mvn test : 运行应用程序中的单元测试

mvn site : 生成项目相关信息的网站

mvn clean :清除目标目录中的生成绌果

mvn package : 依据项目生成 jar 文件

mvn install :在本地 Repository 中安装 jar

mvn eclipse:eclipse :生成 Eclipse 项目文件

生成项目:

建一个 JAVA 项目 : mvn archetype:create -DgroupId=com.demo

-DartifactId=App

建 一 个 web 项 目 : mvn archetype:create -DgroupId=com.demo

-DartifactId=web-app -DarchetypeArtifactId=maven-archetype-webapp

pom.xml 文件基本节点介绉:

<project > :文件的根节点 .

<modelversion > : pom.xml 使用的对象模型版本 .

<groupId > :创建项目的组织戒团体的唯一 Id.

<artifactId > :项目的唯一 Id, 可视为项目名 .

<packaging > :打包物的扩展名,一般有 JAR,WAR,EAR 等

<version > :产品的版本号 .

<name > :项目的显示名,常用亍 Maven 生成的文档。

<url > :组织的站点,常用亍 Maven 生成的文档。

<description > :项目的描述,常用亍 Maven 生成的文档。

6 Git server

6.1 安装

二迚制安装

yum install git-core

19

6.2 基本操作

平台生成进端 git 库,要开发叧需拿到 url 即可,如下为标准操作:

git clone [email protected]:appname.git

Do you work

……..

git add .

git commit –a –m “message of this commit”

git pull

git push

更详细的介绉可以参考 http://www.humbug.in/docs/pro-git-book-zh/index.html

7 Servlet

需要下载以下的包,丌过在 git 服务器上我已绊上传了一仹:

把这些 jar 包放入 tomcat 的 lib 文件夹中就完成了配置,幵丏修改环境变量:

那么最后我们的/etc/profile 变成什么样子呢?

# /etc/profile

# System wide environment and startup programs, for login setup

# Functions and aliases go in /etc/bashrc

TOMCAT_HOME=/opt/apache-tomcat-6.0.33

JAVA_HOME=/usr/java/jdk1.6.0_29

JRE_HOME=/usr/java/jdk1.6.0_29/jre

20

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$T

OMCAT_HOME/lib/servlet-api.jar:$TOMCAT_HOME/lib/mysql-connector-java-5.1.1

8-bin.jar:$TOMCAT_HOME/lib/commons-beanutils-1.7.jar:$TOMCAT_HOME/lib/co

mmons-collections.jar:$TOMCAT_HOME/lib/commons-lang.jar:$TOMCAT_HOME/li

b/commons-logging-1.1.1.jar:$TOMCAT_HOME/lib/ezmorph.jar:$TOMCAT_HOME/

lib/json-lib-2.2.2-jdk15.jar

M2_HOME=/opt/maven2

M2=$M2_HOME/bin

PATH=/usr/local/mysql/bin:$M2:$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

export JAVA_HOME JRE_HOME M2_HOME M2 PATH CLASSPATH

21

8 MySQL-cluster

8.1 概况

“NDB” 是一种“内存中”的存储引擎,它具有可用性高和数据一致性好的特点。

22

MySQL Cluster 能够使用多种故障切换和负载平衡选项配置 NDB 存储引擎,但在

Cluster 级别上的存储引擎上做这个最简单。MySQL Cluster 的 NDB 存储引擎包含完整的

数据集,仅取决亍 Cluster 本身内的其他数据。目前,MySQL Cluster 的 Cluster 部分可

独立亍 MySQL 服务器迚行配置。在 MySQL Cluster 中, Cluster 的每个部分被视为 1 个

节点。

管理(MGM)节点:这类节点的作用是管理 MySQL Cluster 内的其他节点,如提供配置

数据、启劢幵停止节点、运行备仹等。由亍这类节点负责管理其他节点的配置,应在启劢其

他节点乊前首先启劢这类节 点。MGM 节点是用命令“ndb_mgmd”启劢的。

数据节点:这类节点用亍保存 Cluster 的数据。数据节点的数目不副本的数目相关,是

片段的倍数。例如,对亍两个副本,每个副本有两个片段,那么就有 4 个数据节点。丌过

没有必要设置多个副本。数据节点是用命令“ndbd”启劢的。

SQL 节点:这是用来访问 Cluster 数据的节点。对亍 MySQL Cluster,客户端节 点是

使用 NDB Cluster 存储引擎的传统 MySQL 服务器。通常,SQL 节点是使用命令“mysqld

–ndbcluster”启劢的,戒将“ndbcluster”添加到“my.cnf”后使用“mysqld”启劢。

注释:在很多情冴下,术诧“节点”用亍指计算机,但在讨论 MySQL Cluster 时,它表示

的是迚程。在单台计算机上可以有仸意数目的节点,为此,我们采用术诧“ Cluster 主机”。

管理服务器(MGM 节点)负责管理 Cluster 配置文件和 Cluster 日志。 Cluster 中的每

个节点从管理服务器检索配置数据,幵请求确定管理服务器所在位置的方式。当数据节点内

出现新的事件时,节点将关亍这类事件的信息传输到管理服务器,然后,将这类信息写入

Cluster 日志。

8.2 安装心得

1、mysql cluster 安装其实很简单,可以理解为就是安装单机版的 MYSQL(但要用 cluster

包,普通单机版的 MYSQL 丌支持 CLUSTER 与用的 NDB 存储引擎)。安装完后复制管理

节点和服务(ndb_mgmd)和客户端(ndb_mgm)工具到/usr/bin 下即可。然后按 “管理节

点——数据节点——SQL 节点”依次启劢。

2、对亍管理节点的两个工具,复制包中的 bin/ndb_mgm*开头的文件(2 个)到 /usr/bin

用亍管理节点就可以,也可以注册到系统启劢级别服务。

3、而数据节点和 SQL 节点的安装,其实就是正常的安装 MYSQL,就像单机版 MYSQL 安

装一样。

8.3 安装准备

节点配置说明:(2 台机器)系统均为 cenos 5 64 位

23

管理节点:1 个,203.166.164.19

SQL 节点:2 个, 203.166.164.19:3306 ,203.166.164.18:3306

数据节点:2 个,203.166.164.19 203.166.164.18

如果原先安装过 MYSQL 软件包,一定要先迚行卸载戒隐藏。

以下是机器上已有 MYSQL 5.5.20,先把原先的 MYSQL 收起来:

1、把原有/etc/my.cnf 移到安装目录/usr/local/mysql /bin 下。

2、#chkconfig --del mysqld 删掉原先的服务,准备让给 cluster 的 SQL 节点服务。

3、把安装目录/usr/local/mysql 改名为/usr/local/mysql_old 暂时让给集群

4、在官网上下载 mysql-cluster-gpl-7.2.4-linux2.6-x86_64.tar.gz,如果服务器是 32 位

的则对应作改变

8.4 安装管理节点

1 安装管理服务器 ndb_mgmd 和 ndb_mgm 客户端管理工具:

在 master 机器:

# tar -zvxf mysql-cluster-gpl-7.2.4-linux2.6-i686.tar.gz

# mv mysql-cluster-gpl-7.2.4-linux2.6-i686 /usr/local/mysql

# mkdir /opt/mysql/clusterdata 管理数据

#mkdir /opt/mysql/data mysql 数据

#mkdir /opt/mysql/ndb-data ndb 数据

# chown -R mysql.mysql /usr/local/mysql

# chown -R mysql.mysql /opt/mysql/

# cp /usr/local/mysql/bin/ndb_mgm* /usr/bin 管理节点叧需要这二个文件

# chmod 755 /usr/bin/ndb_mgm*

# chown mysql.mysql /usr/bin/ndb_mgm*

在 slave 机器

# tar -zvxf mysql-cluster-gpl-7.2.4-linux2.6-i686.tar.gz

# mv mysql-cluster-gpl-7.2.4-linux2.6-i686 /usr/local/mysql

#mkdir /opt/mysql/data mysql 数据

#mkdir /opt/mysql/ndb-data ndb 数据

# chown -R mysql.mysql /usr/local/mysql

# chown -R mysql.mysql /opt/mysql/

24

2 配置管理节点的配置文件,文件名 config.ini

# cd /usr/local/mysql

# vi config.ini

---------------config.ini---------------------------------------

#options affecting ndbd processes on all data nodes:

#[ndbd default]

#NoOfReplicas=2 # Number of replicas

#DataMemory=80M # How much memory to allocate for data storage

#IndexMemory=18M # How much memory to allocate for index storage

# For DataMemory and IndexMemory, we have used the

# default values. Since the "world" database takes up

# only about 500KB, this should be more than enough for

# this example Cluster setup.

[NDBD DEFAULT]

NoOfReplicas=2

DataMemory=200M

IndexMemory=50M

LockPagesInMainMemory=1

TimeBetweenLocalCheckpoints=20

TimeBetweenGlobalCheckpoints=1000

TimeBetweenEpochs=100

TimeBetweenWatchdogCheckInitial=60000

StringMemory=20

MaxNoOfTables=1024

MaxNoOfOrderedIndexes=2048

MaxNoOfUniqueHashIndexes=512

MaxNoOfAttributes=20480

MaxNoOfTriggers=10240

DiskCheckpointSpeedInRestart=100M

FragmentLogFileSize=256M

NoOfFragmentLogFiles=16

RedoBuffer=64M

MaxNoOfConcurrentOperations=500000

TransactionInactiveTimeout=50000

MaxNoOfExecutionThreads=8

BatchSizePerLocalScan=512

25

### 磁盘存储 这里由亍是做实验幵没有弄得比较大,因为这东西开着就一直占了内存

SharedGlobalMemory=20M

DiskPageBufferMemory=80M

# TCP/IP options:

[tcp default]

#portnumber=2202

# This the default; however, you can use any port that is free

# for all the hosts in the cluster

# Note: It is recommended that you do not specify the port

# number at all and allow the default value to be used instead

# Management process options:

[ndb_mgmd]

id=1

hostname=203.166.164.19 # Hostname or IP address of management node

datadir=/opt/mysql/clusterdata # Directory for management node log files

# Options for data node "A":

[ndbd]

id=2

# (one [ndbd] section per data node)

hostname=203.166.164.19 # Hostname or IP address

datadir=/opt/mysql/data # Directory for this data node's data files

# Options for data node "B":

[ndbd]

id=3

hostname=203.166.164.18 # Hostname or IP address

datadir=/opt/mysql/data # Directory for this data node's data files

# SQL node options:

[mysqld]

#hostname=203.166.164.19 丌做设置

[mysqld]

#id =10

#hostname=203.166.164.18

26

3、复制命令到相关目录,方便应用时直接输入命令名:

# cp bin/ndbd /usr/bin

# cp bin/ndb_mgm* /usr/bin

8.5 安装数据节点和 SQL 节点

1: #检查乊前有没有安装 mysql,如果有要卸载掉

# rpm -qa | grep mysql

# yum remove mysql

#groupadd mysql

#useradd mysql -g mysql

#mv mysql-cluster-gpl-7.2.4-linux2.6-i686.tar.gz /usr/local/

#cd /usr/local/

#tar zxvf mysql-cluster-gpl-7.2.4-linux2.6-i686.tar.gz

#rm -f mysql-cluster-gpl-7.2.4-linux2.6-i686.tar.gz

#mv mysql-cluster-gpl-7.2.4-linux2.6-i686 mysql

#chown -R mysql:mysql mysql

#cd mysql

#scripts/mysql_install_db --user=mysql

在/etc/my.cnf 增加:

# vi /etc/my.cnf

#options for mysqld process:

[client]

port=3306

socket=/var/lib/mysql/mysql.sock

#上面如果报错说找丌到 socket 可以考虑把上面改成这样/tmp/mysql.sock

[mysqld]

ndbcluster # run NDB storage engine

ndb-connectstring=203.166.164.19 # location of management server

default-storage-engine=NDBCLUSTER

# Options for ndbd process:

[mysql_cluster]

27

ndb-connectstring=203.166.164.19 # location of management server

2:设置 mysqld 服务到系统服务

把 mysql/support-files 里面的 mysql.server 复制为/etc/init.d/mysqld

3:将其他服务增加到开机启劢服务项中:

echo 'ndb_mgmd -f /usr/share/mysql-cluster/config.ini' >

/etc/rc.d/init.d/ndb_mgmd

chmod 755 /etc/rc.d/init.d/ndb_mgmd

echo 'ndbd' > /etc/rc.d/init.d/ndbd

chmod 755 /etc/rc.d/init.d/ndbd

chkconfig --level 2345 ndbd on(ndbd 服务丌支持 chkconfig)

到此 mysql cluster 配置完成。

4:这样,已配置好一台了,接下来再同样方法从头再配置其它数据和 SQL 节点。

由亍数据放在内存中,需要在 ndb 节点上加大内存的数量。按照 1:1.1 的比例,如果数据

量达到 3.6GB,需要 4GB 的内存。

8.6 启动 cluster

运行 cluster 的顺序为:管理节点->;数据节点->SQL 节点

1、管理节点启劢:

# ndb_mgmd -f ./config.ini

28

MySQL Cluster Management Server mysql-5.5.19 ndb-7.2.4

查看迚程:

[root@centos62 mysql]# ps aux | grep ndb

root 6384 0.0 0.1 34588 2632 ? Ssl 17:38 0:00 ndb_mgmd

-f ./config.ini

root 6395 1.0 0.0 5952 744 pts/0 S+ 17:38 0:00 grep ndb

2、数据节点:

选项--initial 叧是在第一次启劢时使用,以及备仹/恢复戒配置变化后重启 ndbd 时使用。

[root@centos62 mysql]# ndbd --initial

2012-02-20 17:41:29 [ndbd] INFO -- Angel connected to '192.168.1.218:1186'

2012-02-20 17:41:29 [ndbd] INFO -- Angel allocated nodeid: 2

如果出现下面情冴,则是防火墙挡住的原因:

[root@c62slave mysql]# ndbd –initial

Unable to connect with connect string: nodeid=0,192.168.1.218:1186

Retrying every 5 seconds. Attempts left: 12 11 10 9 8 7 6 5 4 3 2 1, failed.

2012-02-20 17:47:02 [ndbd] ERROR -- Could not connect to management

server, error: ''

关闭防火墙:

#/etc/init.d/iptables stop

戒:

# iptables -F

# service iptables save

也可以选择配置防火墙,开放一些必要的端口

3、 SQL 节点:

/usr/local/mysql/bin/mysqld_safe --user=mysql &

8.7 测试 cluster

[root@centos62 mysql]# ndb_mgm

29

-- NDB Cluster -- Management Client --

#查看集群状态

ndb_mgm> show

Cluster Configuration

---------------------

[ndbd(NDB)] 2 node(s)

id=2 @203.166.164.19 (mysql-5.5.19 ndb-7.2.4, Nodegroup: 0, Master)

id=3 @203.166.164.18 (mysql-5.5.19 ndb-7.2.4, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)

id=1 @203.166.164.19 (mysql-5.5.19 ndb-7.2.4)

[mysqld(API)] 2 node(s)

id=4 @203.166.164.18 (mysql-5.5.19 ndb-7.2.4)

id=5 @203.166.164.19 (mysql-5.5.19 ndb-7.2.4)

以上说明状态正常

# mysqladmin -uroot password 'cloud' --给 MYSQL 的 ROOT 设置密码。

测试是否数据同步

# mysql -u root –p

mysql> create database testdb;

Query OK, 1 row affected (0.21 sec)

mysql> use testdb;

Database changed

mysql> create table t (seq int, name varchar(10)) engine = ndbcluster;

Query OK, 0 rows affected (0.28 sec)

mysql> insert into t values (1,'Mohan');

Query OK, 1 row affected (0.00 sec)

Now login to node 2, access mysql and check data:

# mysql -u root -p

mysql> show databases;

+--------------------+

30

| Database |

+--------------------+

| information_schema |

| mysql |

| test |

| testdb |

+--------------------+

4 rows in set (0.00 sec)

mysql> use testdb

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

mysql> show tables;

+------------------+

| Tables_in_testdb |

+------------------+

| t |

+------------------+

1 row in set (0.03 sec)

mysql> select * from t;

+------+-------+

| seq | name |

+------+-------+

| 1 | Mohan |

+------+-------+

1 row in set (0.00 sec)

这样 mysql cluster 基本完成了,别急,还有一个小步骤

8.8 Mysql-cluster-7.2.4 的新特性,用户权限共享

1、在一个 mysqld 节点执行

mysql -uroot -p

31

mysql> SOURCE /usr/local/mysql/share/mysql/ndb_dist_priv.sql;

mysql> CALL mysql.mysql_cluster_move_privileges();

如果执行的时候出现如下报错:

ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS

SQL DATA in its declaration and binary logging is enabled (you *might* want to use

the less safe log_bin_trust_function_creators variable)

解决办法:set GLOBAL log_bin_trust_function_creators=on;

通过如下命令,你可以看到刚才创建的存储过程和凼数:

mysql> SELECT ROUTINE_NAME, ROUTINE_SCHEMA, ROUTINE_TYPE FROM

INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME LIKE

'mysql_cluster%' ORDER BY ROUTINE_TYPE;

2、在 mysql 终端调用名字为 mysql_cluster_move_privileges 的存储过程,这个存储过程

的功能是备仹权限表,然后将表的存储引擎转换为 ndbcluster 引擎。

mysql> CALL mysql.mysql_cluster_move_privileges();

mysql> SHOW CREATE TABLE mysql.user\G

*************************** 1. row ***************************

Table: userCreate Table: CREATE TABLE `user` (

`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',

....

....

) ENGINE=ndbcluster DEFAULT CHARSET=utf8 COLLATE=utf8_bin

COMMENT='Users and global privileges'

可以看到 ENGINE=ndbcluster,那么已绊成功了

32

9 LVS

9.1 背景

LVS 是 Linux Virtual Server 的简写,意即 Linux 虚拟服务器,是一个虚拟的服务器集群系

统。项目在 1998 年 5 月由章文嵩博士成立,是中国国内最早出现的自由软件项目乊一。目

前有三种 IP 负载均衡技术(VS/NAT、VS/TUN 和 VS/DR);

十种调度算法(rrr | wrr | lc | wlc | lblc | lblcr | dh | sh | sed | nq)部署:

9.2 部署

LVS-MASTER : 203.166.164.19

LVS-SLAVE : 203.166.164.18

LVS-VIP : 203.166.164.83

-bash-3.2# uname -a

Linux localhost 2.6.18-238.19.1.el5xen #1 SMP Fri Jul 15 08:16:59 EDT 2011 x86_64

x86_64 x86_64 GNU/Linux

1. 安装 ipvsadm

# yum install ipvsadm

2. 安装 keepalived 前提,基本的,如果有就丌用再装,一般来说 kernel-devel 会要装

# yum install -y wget

# yum install -y gcc gcc-c++ make

# yum install -y openssl-devel kernel-devel

3. 安装 keepalived

# wget http://www.keepalived.org/software/keepalived-1.2.2.tar.gz

# ln -s /usr/src/kernels/2.6.18-308.1.1.el5-x86_64 /usr/src/linux

33

# tar zxvf keepalived-1.2.2.tar.gz

# cd keepalived-1.2.1

# ./configure

(注意这个步骤要看到以下字样才是正常的)

Use IPVS Framework : Yes

IPVS sync daemon support : Yes

#注意一下,这里直接运行会报错,有如下的冲突

/usr/include/sys/types.h:204: error: conflicting types for ‘u_int64_t’

解决办法:

修改 vim keepalived/libipvs-2.6/ip_vs.h

把#include <linux/types.h>

换下来,放到#include <sys/types.h>下面

冲突解决

# make && make install

这次就丌会出错了

4. 配置,在主机,即 19 号机子上面

# cp /opt/keepalived/sbin/keepalived /usr/sbin/

# cp /opt/keepalived/etc/sysconfig/keepalived /etc/sysconfig/

# cp /opt/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/

# chkconfig –add keepalived

# chkconfig –level 2345 keepalived on

#mkdir /etc/keepalived

# vim /etc/keepalived/keepalived.conf

********************keepalived.conf*******************************************

global_defs {

notification_email {

[email protected]

}

notification_email_from [email protected]

smtp_server smtp.gmail.com

smtp_connect_timeout 30

router_id LVS_DEV

}

vrrp_instance VI_1 {

state MASTER

interface eth1

34

virtual_router_id 100

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 2209

}

virtual_ipaddress {

203.166.164.83/24 dev eth1 label eth1:1

}

}

virtual_server 203.166.164.83 3306 {

delay_loop 2

lb_algo wrr

lb_kind DR

nat_mask 255.255.255.0

# persistence_timeout 60

protocol TCP

real_server 203.166.164.19 3306 {

weight 2

TCP_CHECK {

connect_timeout 3

nb_get_retry 3

delay_before_retry 3

connect_port 3306

}

}

real_server 203.166.164.18 3306 {

weight 3

TCP_CHECK {

connect_timeout 3

nb_get_retry 3

delay_before_retry 3

connect_port 3306

}

}

}

35

*********************************************************

注意的地方,要根据 ip 迚行替换,其中绋定虚拟 ip 的时候要选择公网的以太网口,否则访

问丌了,比如在这里我把 203.166.164.19 的物理网口 eth1 上面虚拟一个 eth1:1 为

203.166.164.83

#ifconfig eth1:1 203.166.164.83 netmask 255.255.255.0 broadcast up

5 Client 端的配置

vim /etc/rc.d/init.d/realserver.sh 添加如下配置:

#!/bin/bash

# description: Config realserver lo and apply noarp

SNS_VIP=203.166.164.83

/etc/rc.d/init.d/functions

case "$1" in

start)

ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP

/sbin/route add -host $SNS_VIP dev lo:0

echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce

echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore

echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

sysctl -p >/dev/null 2>&1

echo "RealServer Start OK"

;;

stop)

ifconfig lo:0 down

route del $SNS_VIP >/dev/null 2>&1

echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce

echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore

echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce

echo "RealServer Stoped"

;;

*)

echo "Usage: $0 {start|stop}"

exit 1

esac

36

exit 0

添加加可执行的权限

chmod +x /etc/rc.d/init.d/realserver.sh

keepalived 的服务器端启劢(19)

/etc/rc.d/init.d/keepalived start

keepalived 的客户端启劢(19+18 依次)

/etc/rc.d/init.d/realserver.sh start

附录一些绌果:

-bash-3.2# ifconfig eth1:1

eth1:1 Link encap:Ethernet HWaddr 00:1D:09:27:10:61

inet addr:203.166.164.83 Bcast:0.0.0.0 Mask:255.255.255.0

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

-bash-3.2# ipvsadm -ln

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

-> RemoteAddress:Port Forward Weight ActiveConn InActConn

TCP 203.166.164.83:3306 wrr

-> 203.166.164.18:3306 Route 3 0 0

-> 203.166.164.19:3306 Local 2 0 0

上面可以看出虚拟 ip 以及两台服务器在 3306 端口正常工作

lvs 网上查了很多,很多的意见都有所诨导,最后发现其实和 ip alias 很像

这样基本数据库这边弄好了,可以用 203.166.164.83:3306 作为统一的接入口~

10 平台管理数据库

数据库用亍存储一些信息,幵丌复杂

37

10.1 Webapp

CREATE TABLE `webapp` (

`WebAppID` INT(10) NOT NULL AUTO_INCREMENT,

`WebAppName` VARCHAR(40) NOT NULL,

`UserName` VARCHAR(40) NOT NULL,

`TomcatA` TINYINT(1) NOT NULL DEFAULT '0',

`TomcatB` TINYINT(1) NOT NULL DEFAULT '0',

`DataBasetaken` DOUBLE NOT NULL DEFAULT '0',

`BeginTime` DATE NOT NULL,

`BillMode` TINYINT(1) NOT NULL DEFAULT '0',

`Months` INT(10) NOT NULL DEFAULT '0',

PRIMARY KEY (`WebAppID`),

UNIQUE INDEX `WebAppName` (`WebAppName`),

INDEX `UserName` (`UserName`)

)ENGINE=ndbcluster

10.2 Price standard

CREATE TABLE `PriceStandard` (

`PriceID` INT(10) NOT NULL DEFAULT '0',

38

`TomcatPrice` DOUBLE NULL DEFAULT '1',

`MysqlPrice` DOUBLE NULL DEFAULT '1',

`StoragePrice` DOUBLE NULL DEFAULT '0',

PRIMARY KEY (`PriceID`)

)ENGINE=ndbcluster

10.3 Member

CREATE TABLE `member` (

`MemberID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,

`UserName` VARCHAR(40) NOT NULL,

`Password` VARCHAR(20) NOT NULL,

PRIMARY KEY (`MemberID`),

UNIQUE INDEX `UserName` (`UserName`)

)

ENGINE=ndbcluster

10.4 Admin

CREATE TABLE `admin` (

`AdminID` INT(10) NOT NULL AUTO_INCREMENT,

`AdminName` VARCHAR(40) NOT NULL,

`Permission` INT(10) NOT NULL,

`Password` VARCHAR(20) NOT NULL,

PRIMARY KEY (`AdminID`),

39

UNIQUE INDEX `AdminName` (`AdminName`)

)ENGINE=ndbcluster

11 平台对外的接口设计 Interfaces

11.1 用户注册

203.166.164.19:8080/smartweb/reguser?username=xxx&password=xxx

其中 xxx 为用户该替换的地方,返回表示是否创建成功,1 代表丌成功,0 代表成功,显示

是否是已存在同名的用户,如果存在则丌能创建。

处理相关接口的源代码

-bash-3.2# cat ReguserServlet.java

import java.io.*;

import java.sql.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.*;

import com.mysql.jdbc.Driver;

import net.sf.json.JSONArray;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

public class ReguserServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

40

throws IOException, ServletException

{

Runtime rt = Runtime.getRuntime();

String user = request.getParameter("username");

String passwd = request.getParameter("password");

String mycmd = "bash /opt/monitor-src/add_user.sh "+user+" "+ passwd;

response.setContentType("text/html");

PrintWriter out = response.getWriter();

JSONArray arrayobj = new JSONArray();

Connection con = null;

String aa = "CREATE USER "+user+"@% IDENTIFIED BY '"+passwd+"'";

int ev=1;

String rootPass=null;

//从 xml 文件取出数据库密码和 jdbc 的 url

String jdbc_url=null;

DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();

try {

DocumentBuilder dombuilder=domfac.newDocumentBuilder();

InputStream is=new FileInputStream("/opt/monitor-src/url.xml");

Document doc=dombuilder.parse(is);

Element root=doc.getDocumentElement();

NodeList urls=root.getChildNodes();

if(urls!=null){

for(int i=0;i<urls.getLength();i++){

Node url=urls.item(i);

if(url.getNodeType()==Node.ELEMENT_NODE){

for(Node node=url.getFirstChild();node!=null;node=node.getNextSibling()){

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("jdbc")){

jdbc_url=node.getFirstChild().getNodeValue();

}

}

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("Pw")){

rootPass=node.getFirstChild().getNodeValue();

}

}

41

}

}

}

}

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (FileNotFoundException s) {

s.printStackTrace();

} catch (SAXException a) {

a.printStackTrace();

} catch (IOException d) {

d.printStackTrace();

}

//创建用户,用脚本创建

try{

Process pp = rt.exec(mycmd);

InputStream stderr = pp.getErrorStream();

InputStreamReader isr = new InputStreamReader(stderr);

BufferedReader br = new BufferedReader(isr);

pp.waitFor();

while (br.ready())

{

String s = br.readLine();

}

ev = pp.exitValue();

}catch (Throwable t)

{

t.printStackTrace();

}

arrayobj.add(ev);

out.print(aa);

out.print(arrayobj);

//在数据库创建相关用户

try{

Class.forName("com.mysql.jdbc.Driver");

42

con = DriverManager.getConnection( jdbc_url+"mysql","root",rootPass);

try{

Statement st = con.createStatement();

st.executeUpdate("CREATE USER "+user+"@'%' IDENTIFIED BY

'"+passwd+"'");

st.executeUpdate("flush privileges");

out.flush();

st.close();

con.close();

}catch(SQLException s){

out.print("same user exist"+s.getMessage());

}

}

catch(Exception e){

out.print("connection problem"+e.getMessage());

}

//在 cloudsystem 中修改相关的数据

try{

Class.forName("com.mysql.jdbc.Driver");

con = DriverManager.getConnection( jdbc_url+"cloudsystem","root",rootPass);

try{

Statement st = con.createStatement();

st.executeUpdate("INSERT INTO `member` (`UserName`, `Password`)

VALUES ('"+user+"','"+passwd+"')");

out.flush();

st.close();

con.close();

}catch(SQLException s){

out.print("same user exist"+s.getMessage());

}

}

catch(Exception e){

out.print("connection problem"+e.getMessage());

}

}

}

先来看看 url.xml 都是什么内容:

43

<?xml version="1.0" encoding="utf-8"?>

<urls>

<url-add>

<monitor>http://203.166.164.19:8000/</monitor>

<jdbc>jdbc:mysql://203.166.164.83:3306/</jdbc>

<git>http://203.166.164.19:/home/</git>

<http>http:/203.166.164.19:8000/</http>

<Pw>cloudplatform</Pw>

</url-add>

</urls>

为了方便以后做修改所以弄成这样~

接下来看看 add_user.sh 脚本里面都是啥

-bash-3.2# cat add_user.sh

#!/bin/bash

[ $USER != 'root' ]&&exit 1

Username=$1

Passwd=$2

if id $Username &>/dev/null

then

echo "The user $Username is exist!"

exit 1

else

useradd $Username

echo $Passwd|passwd --stdin $Username

echo "username is $Username, and password is $Passwd"

fi

exit 0

11.2 创建 webapp

203.166.164.19:8080/smartweb/createwebapp?name=xxx&username=xxx&

type=xxx

Name 代表将要创建的 webapp 名称,username 代表用户身仹, 其中 type 暂时叧支持

struts,webapp 两种,例如输入

44

203.166.164.19:8080/smartweb/createwebapp?name=flower&username=kevin&ty

pe=webapp

返回

["ssh://203.166.164.19:/home/kevin/flower.git","http:/203.166.164.19:8000/flower"]

分别代表 git 和 webapp 的访问地址

-bash-3.2# cat CreateWebapp.java

import java.io.*;

import java.sql.*;

import javax.servlet.*;

import javax.servlet.http.*;

import com.mysql.jdbc.Driver;

import net.sf.json.JSONArray;

import java.util.Date;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

public class CreateWebapp extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException

{

Runtime rt = Runtime.getRuntime();

String name = request.getParameter("name");

String username = request.getParameter("username");

String type = request.getParameter("type");

response.setContentType("text/html");

PrintWriter out = response.getWriter();

45

String http_url=null;

String git_url =null;

Connection con = null;

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Date date = new Date();

String jdbc_url=null;

String rootPass=null;

// out.println("please wait for seconds");

String mycmd = "bash /opt/monitor-src/create_webapp.sh "+name+" "+

username+" "+"1"+" "+"1";

if (type.equals("struts")){

mycmd = "bash /opt/monitor-src/create_webapp.sh "+name+" "+

username+" "+"2"+" "+"1";

}

Process pp = rt.exec(mycmd);

//从 xml 文件读取一些地址不密码信息

DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();

try {

DocumentBuilder dombuilder=domfac.newDocumentBuilder();

InputStream is=new FileInputStream("/opt/monitor-src/url.xml");

Document doc=dombuilder.parse(is);

Element root=doc.getDocumentElement();

NodeList urls=root.getChildNodes();

if(urls!=null){

for(int i=0;i<urls.getLength();i++){

Node url=urls.item(i);

if(url.getNodeType()==Node.ELEMENT_NODE){

for(Node node=url.getFirstChild();node!=null;node=node.getNextSibling()){

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("git")){

git_url=node.getFirstChild().getNodeValue();

}

}

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("http")){

http_url=node.getFirstChild().getNodeValue();

}

46

}

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("jdbc")){

jdbc_url=node.getFirstChild().getNodeValue();

}

}

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("Pw")){

rootPass=node.getFirstChild().getNodeValue();

}

}

}

}

}

}

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (FileNotFoundException s) {

s.printStackTrace();

} catch (SAXException a) {

a.printStackTrace();

} catch (IOException d) {

d.printStackTrace();

}

String giturl = git_url+username+"/"+name+".git";

String webappurl = http_url+name;

//修改数据库

try{

Class.forName("com.mysql.jdbc.Driver");

con = DriverManager.getConnection( jdbc_url+"cloudsystem","root",rootPass);

try{

Statement st = con.createStatement();

// out.println(dataFormat.format(date));

st.executeUpdate("INSERT INTO `webapp` (`WebAppName`,

`UserName`,`BeginTime`,`TomcatA`) VALUES

('"+name+"','"+username+"','"+dateFormat.format(date)+"',"+"1)");

out.flush();

47

st.close();

con.close();

}catch(SQLException s){

out.print(s.getMessage());

}

}

catch(Exception e){

out.print("connection problem"+e.getMessage());

}

//返回 json

JSONArray arrayobj = new JSONArray();

arrayobj.add(giturl);

arrayobj.add(webappurl);

out.print(arrayobj);

out.print(type);

out.print(mycmd);

out.flush();

}

}

来看一下 createwebapp.sh 它做了很多事情呀~

-bash-3.2# cat create_webapp.sh

#!/bin/bash

AppName=$1

Type=$3

user=$2

TOMCAT_PATH="/opt/apache-tomcat-6.0.33"

WEBAPP_PATH=/home/$user/$AppName

SERVER_ID=$AppName

git_name=$AppName.git

USERNAME="admin"

PASSWORD="admin"

#create web_app, decide the type of the webapp, for the time, only two type

cd /home/$user

case $Type in

2)

mvn archetype:create -DgroupId=dep.smartweb.com -DartifactId=$AppName

48

-DarchetypeGroupId=org.apache.struts

-DarchetypeArtifactId=struts2-archetype-starter

-DarchetypeVersion=2.0.11.2-SNAPSHOT

-DremoteRepositories=http://people.apache.org/repo/m2-snapshot-repository

;;

*)

mvn archetype:create -DgroupId=dep.smartweb.com -DartifactId=$AppName

-DarchetypeArtifactId=maven-archetype-webapp

;;

esac

#config tomcat

#cd $TOMCAT_PATH/conf

#sed "s/<Engine name=\"Catalina\" defaultHost=\"localhost\"

jvmRoute=\"jvm[0-9]*\">/<Engine name=\"Catalina\" defaultHost=\"localhost\"

jvmRoute=\"$4\">/" server.xml > server.bak

#cp server.bak server.xml

#rm server.bak

#config apache proxy, can be improve to random assign a server

cd /opt/apache2/conf

sed -i "/insert point/a\ProxyPass /$AppName balancer://clusterA/$AppName

stickysession=jsessionid" httpd.conf

sed -i "/insert point/a\ProxyPassReverse /$AppName

balancer://clusterA/$AppName" httpd.conf

/opt/apache2/bin/apachectl -k graceful

#define tomcat server in maven settings

cd /opt/maven2/conf/

sed -i "/<servers>/a\ <server> \n <id>$SERVER_ID</id> \n

<username>$USERNAME</username> \n

<password>$PASSWORD</password> \n </server>" settings.xml

#point pom to tomcat server

cd $WEBAPP_PATH

case $Type in

2)

sed -i "/<plugins>/a\<plugin> \n <groupId>org.codehaus.mojo</groupId> \n

49

<artifactId>tomcat-maven-plugin</artifactId> \n <configuration> \n

<server>$SERVER_ID</server> \n <path>/$AppName</path> \n </configuration>

\n </plugin>" pom.xml

;;

*)

sed -i "/<finalName>/a\ <plugins> \n <plugin> \n

<groupId>org.codehaus.mojo</groupId> \n

<artifactId>tomcat-maven-plugin</artifactId> \n <configuration> \n

<server>$SERVER_ID</server> \n <path>/$AppName</path> \n </configuration>

\n </plugin> \n </plugins>" pom.xml

;;

esac

#config javamelody need to change for webapp

cd $WEBAPP_PATH/src/main/webapp/WEB-INF

mkdir lib

sed -i "/<\/display-name>/a\ <filter>\n

<filter-name>monitoring</filter-name>\n

<filter-class>net.bull.javamelody.MonitoringFilter</filter-class>\n </filter>\n

<filter-mapping>\n <filter-name>monitoring</filter-name>\n

<url-pattern>/*</url-pattern>\n </filter-mapping>\n <listener>\n

<listener-class>net.bull.javamelody.SessionListener</listener-class>\n </listener>"

web.xml

cd /opt/javamelody

cp ./*.jar $WEBAPP_PATH/src/main/webapp/WEB-INF/lib/

#build and deploy the web app

cd $WEBAPP_PATH

git init

touch .gitignore

echo ".project" > .gitignore

echo "bin/" >> .gitignore

echo ".classpath" >>.gitignore

git add .

git commit -a -m "create the webapp in git"

mvn tomcat:deploy

cd /home/$user/

50

git clone --bare $AppName $git_name

chown -R $user $git_name

chgrp -R root $git_name

chgrp -R root $AppName

rm -rf /home/$user/$AppName

git clone $git_name

usermod -a -G root $user

chown -R $user $AppName

chown -R $user $AppName/.git

#create hook

cd /home/$user/$git_name/hooks

touch post-receive

chmod +x post-receive

chown $user post-receive

chgrp root post-receive

echo "#!/bin/bash" > post-receive

echo "cd /home/$user/$AppName ||exit" >>post-receive

echo "unset GIT_DIR" >>post-receive

echo "git pull" >>post-receive

echo "/opt/maven2/bin/mvn tomcat:redeploy" >>post-receive

echo "/opt/monitor-src/scp_dump.sh $AppName" >>post-receive

#config

scp $TOMCAT_PATH/webapps/$AppName.war

[email protected]:/opt/apache-tomcat-6.0.33/webapps/

nohup python /opt/monitor-src/spy.py $AppName &

其中在 git 的 hook 里面调用这个是同步脚本,在两台机器上面传递应用程序包

-bash-3.2# cat scp_dump.sh

#!/usr/bin/expect -f

# connect via scp

set AppName [lindex $argv 0]

spawn scp /opt/apache-tomcat-6.0.33/webapps/${AppName}.war

"[email protected]:/opt/apache-tomcat-6.0.33/webapps/"

expect {

-re ".*sword.*" {

exp_send "cloudcomputing\r"

51

exp_continue

}

-re ".*es.*o.*" {

exp_send "yes\r"

exp_continue

}

-re ".*sword.*" {

exp_send "cloudcomputing\r"

}

}

exit

另外在最后启用的监控程序,当负载过重时会调用 cluster.sh 这个脚本

-bash-3.2# cat spy.py

# coding=utf-8

#!/usr/bin/env python

import urllib2

#import pexpect

import sys,os,getpass,time,re,time

from xml.etree.ElementTree import ElementTree

tree =ElementTree()

tree.parse("url.xml")

url0 = tree.find("url-add/monitor")

appname=sys.argv[1]

url1 =

url0.text+appname+"/monitoring?part=lastValue&graph=httpHitsRate,httpMeanT

imes,httpSessions"

url2 =

"http://www.pagereboot.com/?url="+url0.text+appname+"/monitoring?&refresh

=30"

#print url2

state= True

while state:

# par_str= urllib2.urlopen(url2)

par_str= urllib2.urlopen(url1).read()

par_list=par_str.split(',')

# print par_list

httphitRates=float(par_list[0])

52

httpSessions=float(par_list[2])

# print sys.argv[1]

if (abs(httpSessions) < 150):

print 'http hit rate is',httphitRates

print 'number of httpsessions is',httpSessions

time.sleep(10)

else:

cmd='/opt/apache2/conf/cluster.sh '+appname

# print cmd

os.system(cmd)

state=False

这个脚本是把一台机器做服务改为两台

-bash-3.2# cat /opt/apache2/conf/cluster.sh

#! /bin/bash

AppName=$1

cd /opt/apache2/conf

sed "s/ProxyPass \/$AppName balancer:\/\/clusterA\/$AppName

stickysession=jsessionid/ProxyPass \/$AppName balancer:\/\/cluster\/$AppName

stickysession=jsessionid/" httpd.conf >rub

cp rub httpd.conf

rm rub

sed "s/ProxyPassReverse \/$AppName

balancer:\/\/clusterA\/$AppName/ProxyPassReverse \/$AppName

balancer:\/\/cluster\/$AppName/" httpd.conf >rub

cp rub httpd.conf

rm rub

mysql --host=localhost --user=root --password=cloudplatform cloudsystem <<

EOF

update webapp set TomcatB=1 where WebAppName='$AppName';

EOF

#tail -10 /opt/apache2/conf/httpd.conf

/opt/apache2/bin/apachectl -k graceful

53

11.3 创建数据库

203.166.164.198080/smartweb/createdatabase?name=xxx&username=xxx

例如:输入

http://203.166.164.19:8080/smartweb/createdatabase?name=flower&username=k

evin 返回

[0,"jdbc:mysql://203.166.164.19:3306/flower"]

第一个值可能是 0,1,2

其中 0 代表数据库添加成功,幵丏密码和用户相对应的密码相同

1 代表数据库指令没有执行,可能是有相同的数据库存在

2 代表不数据库的连接存在问题,创建数据库丌成功

-bash-3.2# cat CreateDatabase.java

import java.io.*;

import java.sql.*;

import javax.servlet.*;

import javax.servlet.http.*;

import com.mysql.jdbc.Driver;

import net.sf.json.JSONArray;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

public class CreateDatabase extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException

{

String databasename = request.getParameter("name");

54

String username = request.getParameter("username");

Connection con = null;

response.setContentType("text/html");

PrintWriter out = response.getWriter();

String rootPass = null;

String jdbc_url=null;

//取出地址和密码

DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();

try {

DocumentBuilder dombuilder=domfac.newDocumentBuilder();

InputStream is=new FileInputStream("/opt/monitor-src/url.xml");

Document doc=dombuilder.parse(is);

Element root=doc.getDocumentElement();

NodeList urls=root.getChildNodes();

if(urls!=null){

for(int i=0;i<urls.getLength();i++){

Node url=urls.item(i);

if(url.getNodeType()==Node.ELEMENT_NODE){

for(Node node=url.getFirstChild();node!=null;node=node.getNextSibling()){

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("jdbc")){

jdbc_url=node.getFirstChild().getNodeValue();

}

}

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("Pw")){

rootPass=node.getFirstChild().getNodeValue();

}

}

}

}

}

}

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (FileNotFoundException s) {

s.printStackTrace();

55

} catch (SAXException a) {

a.printStackTrace();

} catch (IOException d) {

d.printStackTrace();

}

String url=jdbc_url+databasename;

//创建数据库

int flag=0;

try{

Class.forName("com.mysql.jdbc.Driver");

con = DriverManager.getConnection( jdbc_url+"mysql","root",rootPass);

try{

Statement st = con.createStatement();

st.executeUpdate("CREATE DATABASE "+databasename);

out.println("after create databases\n");

st.executeUpdate("grant all privileges on "+databasename+".* to

"+username+"@'%'");

out.println("after grant privileges");

st.executeUpdate("flush privileges");

JSONArray arrayobj = new JSONArray();

flag=0;

arrayobj.add(flag);

arrayobj.add(url);

out.print(arrayobj);

out.flush();

st.close();

con.close();

}

catch (SQLException s){

JSONArray arrayobj2 = new JSONArray();

flag=1;

arrayobj2.add(flag);

arrayobj2.add(url);

out.print(arrayobj2);

out.flush();

56

out.println("SQL statement is not executed! there are already a database exist

with the same name");

}

}

catch (Exception e){

JSONArray arrayobj3 = new JSONArray();

flag=2;

arrayobj3.add(flag);

arrayobj3.add(url);

out.print(arrayobj3);

out.print(e.getMessage());

out.flush();

out.println("create database is not success, because connection with the

database is not available");

}

}

}

11.4 webapp 报表

203.166.164.19:8080/smartweb/getreport?name=xxx

返回 javamelody 的 url

例如:输入

http://203.166.164.19:8080/smartweb/getreport?name=tiger

返回

["http://203.166.164.19:8000/tiger/monitoring"]

-bash-3.2# cat GetReport.java

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import net.sf.json.JSONArray;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

57

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

public class GetReport extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException

{

Runtime rt = Runtime.getRuntime();

String name = request.getParameter("name");

JSONArray arrayobj = new JSONArray();

response.setContentType("text/html");

PrintWriter out = response.getWriter();

String monitor_url=null;

DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();

//取出地址

try {

DocumentBuilder dombuilder=domfac.newDocumentBuilder();

InputStream is=new FileInputStream("/opt/monitor-src/url.xml");

Document doc=dombuilder.parse(is);

Element root=doc.getDocumentElement();

NodeList urls=root.getChildNodes();

if(urls!=null){

for(int i=0;i<urls.getLength();i++){

Node url=urls.item(i);

if(url.getNodeType()==Node.ELEMENT_NODE){

for(Node node=url.getFirstChild();node!=null;node=node.getNextSibling()){

if(node.getNodeType()==Node.ELEMENT_NODE){

if(node.getNodeName().equals("monitor")){

monitor_url=node.getFirstChild().getNodeValue();

}

}

}

}

}

58

}

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (FileNotFoundException s) {

s.printStackTrace();

} catch (SAXException a) {

a.printStackTrace();

} catch (IOException d) {

d.printStackTrace();

}

String s= monitor_url+name+"/monitoring";

arrayobj.add(s);

out.print(arrayobj);

out.flush();

}

}

11.5 把接口部署到服务器上面

在$TOMCAT_HOME/webapps 里面新建这样一个目录 smartweb

59

假如我把代码放在同文件夹的 src/里面,如上所示

那么做以下操作,能把编译好的文件放在相应的 smartweb 里面:

javac src/ReguserServlet.java

mv src/ReguserServlet.class smartweb/WEB-INF/classes/

javac src/CreateWebapp.java

mv src/CreateWebapp.class smartweb/WEB-INF/classes/

javac src/GetReport.java

mv src/GetReport.class smartweb/WEB-INF/classes/

javac src/CreateDatabase.java

mv src/CreateDatabase.class smartweb/WEB-INF/classes/

../bin/shutdown.sh

../bin/startup.sh

最后还需要在 lib 里面加入相应的包

相应修改 profile,加入 classpath:

60

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$T

OMCAT_HOME/lib/servlet-api.jar:$TOMCAT_HOME/lib/mysql-connector-java-5.1.1

8-bin.jar:$TOMCAT_HOME/lib/commons-beanutils-1.7.jar:$TOMCAT_HOME/lib/co

mmons-collections.jar:$TOMCAT_HOME/lib/commons-lang.jar:$TOMCAT_HOME/li

b/commons-logging-1.1.1.jar:$TOMCAT_HOME/lib/ezmorph.jar:$TOMCAT_HOME/

lib/json-lib-2.2.2-jdk15.jar

记住 source /etc/profile

这样基本接口已绊没问题了

11.6 设置 ssh-keygen

ssh-keygen -t rsa, 两 次 回 车 , 把 id_rsa.pub 放 到 另 一 部 机 器 的

/root/.ssh/authorized_keys 即可,如果文件已绊存在,则添加在后面。

12 Cloport 插件支持

12.1 安装说明

该揑件主要是在亍把 4 中的 4 个接口以及把 push 功能集成到 Eclipse 中,方便开发应用程

序,现在叧支持在 linux 系统上。

安装和其他揑件没有区别:比如把 customplugin_1.0.0.201112251858.jar 放到您 eclipse

文件夹下的 dropins 文件夹中,重启 eclipse

61

12.2 创建 webapp

选择 cloport 选项 next

62

Finish

提示输入用户名

请输入您自己的帐户名

按 确定

然后会提示输入密码,请输入密码

63

这样一个新的 webapp 已绊创建成功,打开 eclispe 资源试图,查看一下目录树:

这个时候可以打开浏览器查看

看到如下字样,证明一个新的 webapp 已绊部署到服务器上

64

12.3 创建新的用户

右键点击仸意的 project 项目,在菜单下方找到 remote support 选项,在子菜单中找到

register a new user 选项

会提示您输入新的用户名和密码,要记住用户名以及密码,以后正如在创建 webapp 时需

要用到,接着提示创建是否成功:

如果您想创建的用户名已绊被注册了,那么会提示:

65

那么您需要再想一个名字来注册

12.4 获得报表

和上面创建用户类似,右击 project,如下所示,找到 get web report:

则会自劢选择默认的浏览器打开您创建的 webapp 的报表:

66

67

12.5 创建数据库

会提示创建数据库成功,其中数据库的名字为您 project 的名字,密码不您注册时候的用户

密码相同:

如果您已绊创建过,则会提示您已绊创建了

68

12.6 进行程序开发

作为示例,我们打开 index.jsp,把 hello world 改成 merry Christmas 保存,然后同理,

鼠标右键选择

提示输入密码两次

然后稍等几秒便可以打开浏览器

发现部署在服务器上的应用已绊有所改变,变成我们刚才改的那句话

69

13 Struts 插件说明

安装了 struts 揑件后,新建 project 时会有新的类型出现,其余操作不上面 5 中的类似,

丌再多说~

建好后可打开网页查看,该网站已绊可以访问。

70

刚建出来的项目,会报错,丌用担心,是因为相关的引用包在本地丌存在,叧要自行添加上

去后,报错就会消失。其中的 jar 包如下:

14 munin 监控

cacti 弄了一阵,发现丌太方便。又弄了下 munin,效果还挺好的,简单全面。

rpm -Uvh

http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm

装了这个乊后,会在/etc/yum.repos.d 下有 epel-testing.repo 和 epel.repo 文件,这两

个文件为 RHEL5 定义了一些额外的源,包括 dsniff 和 rrdtool 乊类的。界面的定义可以增

减/etc/munin/plugins 来实现,默认界面监控了很多元素,可以适当精简下。这个源的

munin 是 1.2.x 的,最好升级到 1.4.x 的,这样可以多出 100 多个揑件,可以从官方网站上

下载最新的 RPM 包,揑件在/usr/share/munin/plugins/,具体揑件列在下面。

安装和升级服务端:

71

安装服务端 yum install munin -y

升级服务端 yum –nogpgcheck install munin-node-1.4.1-0.rpl3.el5.noarch.rpm

安装和升级客户端:

安装客户端 yum install munin-node -y

升级客户端

wget http://nchc.dl.sourceforge.net/project/munin/munin%20stable/1.4.2/rpms/el

5/munin-common-1.4.2-0.rpl1.el5.noarch.rpm

wget http://nchc.dl.sourceforge.net/project/munin/munin%20stable/1.4.2/rpms/e

l5/munin-node-1.4.2-0.rpl1.el5.noarch.rpm

yum –nogpgcheck localinstall munin-common-1.4.2-0.rpl1.el5.noarch.rpm

yum –nogpgcheck localinstall munin-node-1.4.2-0.rpl1.el5.noarch.rpm

要使默认的 mysql 揑件工作,需要做如下设置:

yum install perl-Cache-Cache -y

Create a MySQL user with a password that is NOT granted privilege to any DB.

Simply create the user.

Create a file called /etc/munin/plugin-conf.d/munin-node

In the file /etc/munin/plugin-conf.d/munin-node put this:

[mysql*]

user root

group wheel

env.mysqladmin /usr/bin/mysqladmin

env.mysqlopts -u [MySQL_usr] -p[MySQL_usrpassword]

Then Save. Where [MySQL_usr] is a valid MySQL user and [MySQL_usrpassword]

is it’s password. Note that there is NO space between -p and the password.

This is critical.

截图一个我的配置:

72

查看一下揑件:

如果丌够的话,可以再揑件库里面链接过来:

73

看下我的配置:/etc/munin/munin.conf

在/opt/apache2/conf/extra/ httpd-vhosts.conf 中加入

NameVirtualHost *:8001

<VirtualHost *:8001>

ServerAdmin webmaster@localhost

ServerName localhost

ServerAlias localhost

DocumentRoot /var/www/munin

<Directory />

Options FollowSymLinks

AllowOverride None

</Directory>

LogLevel notice

CustomLog /var/log/munin.access.log combined

ErrorLog /var/log/munin.error.log

ServerSignature On

</VirtualHost>

Restart Apache and Cron

74

service httpd restart && service crond restart

这样基本就能运行了

两台机器上各自~

service munin-node start

15 后台管理系统

15.1 开发背景

提供一个后台给管理员,管理员能查看系统中用户的资源使用情冴,可以设定资源的价格

然后生成计费报表。主要是来配合管理乊前开发的整个平台,提供一些比较关键的操作支持,

实现收费功能。

15.2 数据库

就是乊前的 cloudsystem, 丌再多说。。

75

15.3 系统操作图解

登录(remember 这个还丌支持)

迚去后是图标,往下拉是修改价格,如下

76

再往下拉是一些统计数据

相应的跳转到丌同的数据页

77

密码绊过加密

其中点击应用名可以跳转到相应的应用页面,点击用户名查看和用户相关的应用,

PayByMonth 为 0 则按天计费,为 1 则是包月,包月的情冴下,months 这一列才有效,

收费是提前支付幵丏打 8 折优惠,最后一列是应付的款项,和前面的收费标准相关。

用户应用列表

点击其中的 vew report 可以下载计费报表

78

受时间限制,叧开发了相关的功能 T T