gdufo

 

maven2 配置代理上网

在currentuser目录下.m2文件夹中,新增一个setting.xml文件      

 <settings>

          <proxies>
           <proxy>
              <active>true</active>
              <protocol>http</protocol>
              <host>10.110.1.238</host>  =>代理服务器地址
              <port>3128</port>
              <username>proxyuser</username>
              <password>somepassword</password>
              <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
            </proxy>
          </proxies>
 
        </settings>

posted @ 2012-06-06 14:28 gdufo 阅读(1247) | 评论 (0)编辑 收藏

maven tomcat eclipse 配置 debug

单击Eclipse菜单“Run”中的“Run Configurations”。

2、在弹出的对话框中的左侧树中找“到Maven Build”,在其上点击右键并单击“New”。

3、在右侧的“Name”一栏填入自定义的名称。单击在“Main”选项卡的“Browse Workspace”按钮,选择目标项目,选择后在“Base directory”一栏中会出现形如“${workspace_loc:/project_a}”的内容(project_a是前文所述应用项目A,它 会根据你所选的目标项目而改变)。

4、在“Goals”一栏中填入“tomcat:run”。

5、在“Maven Runtime”选择你需要的Maven环境(注意:必须是2.0.8以上的版本)。

6、单击“Apply”,配置完成。

经过测试,通过以上配置,在eclipse自身的Run(“右箭头”)和Debug(“小虫子”)按钮下都会找到以你先前配置中“Name”值为名 的条目(条目最前端也会有“m2”标识),单击之后即可启动基于Tomcat之上的相应项目的运行操作或调试操作。至于是运行项目还是调试项目,只取决于 你单击的条目是在“右箭头”按钮下还是在“小虫子”按钮下。从这方面来看,他们还是很智能化的。


posted @ 2012-06-06 14:25 gdufo 阅读(4351) | 评论 (0)编辑 收藏

TOMCAT6配置负载均衡和集群 _2

http://blog.csdn.net/dangerous_fire/article/details/6278435

最近要配置tomcat集群,在网上搜了很多文章,但照着步骤一步一步做到最后却无法成功,着使我费了两天的劲查看了apache 和 tomcat的大量文档,才将问题一一解决。为方便自己和新手配置tomcat集群,我将整理好的过程晒一晒,希望可以帮到后来人少走一些弯路。

==================

目标:
使用 apache 和 tomcat 配置一个可以应用的 web 网站,要达到以下要求:
1、 Apache 做为 HttpServer ,后面连接多个 tomcat 应用实例,并进行负载均衡。
2、 为系统设定 Session 超时时间,包括 Apache 和 tomcat
3、 为系统屏蔽文件列表,包括 Apache 和 tomcat

注:本例程以一台机器为例子,即同一台机器上装一个apache和2个Tomcat。

一、前期准备工作:安装用的程序(前提保证已安装了JDK1.5以上的版本)
APAHCE 2.2.8下载:apache_2.2.8-win32-x86-no_ssl.msi
TOMCAT6.0.14下载:apache-tomcat-6.0.14.zip直接解压。

二、安装过程
APAHCE安装目录:D:/Apache。
两个TOMCAT目录:自行解压到(D:/TomcatCluster/)下。
分别为 tomcat6-a,tomcat6-b

三、配置
1、Apache配置
1.1 httpd.conf配置
修改APACHE的配置文件D:/Apache/conf/httpd.conf

这里并没有使用mod_jk.so进行apache和tomcat的链接,从2.X以后apache自身已集成了mod_jk.so的功能。只需简单的把下面几行去掉注释,就相当于以前用mod_jk.so比较繁琐的配置了。
这里主要采用了代理的方法,就这么简单。

将以下Module的注释去掉
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so

再找到
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
加上index.jsp修改成

<IfModule dir_module>
DirectoryIndex index.html index.jsp
</IfModule>

此处添加index.jsp 主要为了配置完成以后利用index.jsp输出测试信息!

在 httpd.conf 最后面加入
ProxyRequests Off
<proxy balancer://cluster>
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>

上面的两个BalancerMember成员是我们配置的tomcat集群。


1.2 httpd-vhosts.conf设置
接下来进行虚拟主机的设置。
APACHE的虚拟主机设置如下:
首先要修改 conf/httpd.conf
找到

# Virtual hosts
#Include conf/extra/httpd-vhosts.conf

把Include语句注释去掉。改成

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

在文件(extra/httpd-vhosts.conf)最下面加入

<VirtualHost *:80>
 ServerAdmin adminname
 ServerName localhost
 ServerAlias localhost
 ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On lbmethod=bytraffic
 ProxyPassReverse / balancer://cluster/
</VirtualHost>

其中的域名和路径根据你自己情况设置

负载均衡有三种方式,可以通过设置 lbmethod 选择自己需要的方式,详细可查看apache文档

proxy是位于客户端与实际的服务器之间的服务器,一般称为facade server,负责将外部的请求分流,也负责对内部的响应做一些必要的处理。
如果结合mod_cache,则可提高访问速度,适当的减轻网络流量压力。
闲话少说,直接拿个例子来:
    设本站地址为 www.test.com
    ProxyPass /images/ !
    ProxyPass /js/ !
    ProxyPass /css/ !
    ProxyPass /example http://www.example.com/
    ProxyPassReverse /example http://www.example.com/
    ProxyPass / ajp://127.0.0.1:8009/
    ProxyPassReverse / ajp://127.0.0.1:8009/
还是上一篇的例子,ProxyPass易理解,就是转发url上的请求,而其中的配置顺序也是需要遵守。
要禁止转发的url需要放在一般的请求之前。
对于
http://www.test.com/images/ 
http://www.test.com/js/
http://www.test.com/css/
的请求是不予转发的,对于http://www.test.com/example/的请求,会转发到http://www.example.com
值得注意的就是ProxyPassReverse的配置了,这是反向代理。
为什么要在这里加上这样的配置?我们来看个例子:
 在没有加这样的反向代理设置的情况下,访问http://www.test.com/example/a
 如果www.example.com对请求进行了redirect至http://www.example.com/b
 那么,客户端就会绕过反向代理,进而访问http://www.test.com/example/b
 如果设置了反向代理,则会在转交HTTP重定向应答到客户端之前调整它为http://www.test.com/example/a/b
 即是在原请求之后追加上了redirect的路径。
更多更详细的关于mod_proxy的描述可以参见手册:
http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_proxy.html


2 配置 tomcat
2.1 配置 server 的关闭
我们需要在一台机器上跑两个不同的 tomcat ,需要修改不同的 tomcat 的关闭口,避免出现端口被占用的情况。
其中tomcat6-a用默认值,不修改。
tomcat6-b修改。在tomcat6-b/conf下的 server.xml 中找到 server, 将:
<Server port="8005" shutdown="SHUTDOWN">
改为
<Server port="9005" shutdown="SHUTDOWN">

2.2 配置 Engine
把原来的配置注释掉,把下面一句去掉注释。并标明jvmRoute="jvm2"
<Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm2">

以下是原来的配置。
<Engine name="Catalina" defaultHost="localhost">
 
2.3. 配置 Connector
原来的默认配置。

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

将tomcal6-b 中的 protocol="HTTP/1.1" 的 Connector 端口改为 8081 避免冲突。tomcat6-a 中的保持不变。
protocol="AJP/1.3" 的 Connector 是apache和tomcat链接的关键,前台apache就是通过AJP协议与tomcat进行通信的,以完成负载均衡的作用。
也可以用HTTP协议。大家注意它们是如何连接通信的,(port="8009")就是连接的接口了。

把tomcat6-b的<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 中的port改成 9009
<proxy balancer://cluster>
#与 tomcat6-a 对应,route与<Engine jvmRoute="jvm1">对应。
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
#与 tomcat6-b 对应,route与<Engine jvmRoute="jvm2">对应。
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>

中的端口对应,
tomcat6-a 的ajp端口port:8009
tomcat6-b 的ajp端口port:9009
一定要与上面的一致。

2.5.配置Cluster(两个tomcat中都要修改)
原来的配置。
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
修改为以下的代码:<Receiver port=”XX”/>port也要保证唯一性。

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"? channelSendOptions="6">
 <Manager className="org.apache.catalina.ha.session.BackupManager"
  expireSessionsOnShutdown="false"
  notifyListenersOnReplication="true"
  mapSendOptions="6"/>
 <!--
 <Manager className="org.apache.catalina.ha.session.DeltaManager"
  expireSessionsOnShutdown="false"
  notifyListenersOnReplication="true"/>
 -->
 <Channel className="org.apache.catalina.tribes.group.GroupChannel">
  <Membership className="org.apache.catalina.tribes.membership.McastService"
   address="228.0.0.4"
   port="45564"
   frequency="500"
   dropTime="3000"/>
  <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
   address="auto"
   port="5001"
   selectorTimeout="100"
   maxThreads="6"/>
  <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
   <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
  </Sender>
  <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
  <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
  <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
 </Channel>
 <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
  filter=".*/.gif;.*/.js;.*/.jpg;.*/.png;.*/.htm;.*/.html;.*/.css;.*/.txt;"/>
 <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
  tempDir="/tmp/war-temp/"
  deployDir="/tmp/war-deploy/"
  watchDir="/tmp/war-listen/"
  watchEnabled="false"/>
 <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

这个设置是主要用以tomcat的集群。
tomcat集群各节点通过建立tcp链接来完成Session的拷贝,拷贝有同步和异步两种模式。
在同步模式下,对客户端的响应必须在Session拷贝到其他节点完成后进行;异步模式无需等待Session拷贝完成就可响应。
异步模式更高效,但是同步模式可靠性更高。同步异步模式由channelSendOptions参数控制,默认值是8,为异步模式,4是同步模式。
在异步模式下,可以通过加上拷贝确认(Acknowledge)来提高可靠性,此时channelSendOptions设为10。

Manager用来在节点间拷贝Session,默认使用DeltaManager,DeltaManager采用的一种all-to-all的工作方式,
即集群中的节点会把Session数据向所有其他节点拷贝,而不管其他节点是否部署了当前应用。
当集群中的节点数量很多并且部署着不同应用时,可以使用BackupManager,BackManager仅向部署了当前应用的节点拷贝Session。
但是到目前为止BackupManager并未经过大规模测试,可靠性不及DeltaManager。

四、启动服务,测试tomcat自带的例子
1、测试apache和tomcat协作。
先在每个tomcat中的/webapps/ROOT下的index.jsp下面加上以下的测试代码部分:
(X代表不同的tomcat的输出不同的信息),把index.html删除,以免影响测试效果。
在最后面的加上.即</table></body>之间。
<%
 System.out.println("tomcat6 A|B deal with request");
%>
然后再通过http://127.0.0.1来访问一下,就会出现大家熟悉的猫猫。
然后再通过分别访问
http://127.0.0.1:8080
http://127.0.0.1:8081


它们访问的内容和上面的http:// 127.0.0.1是一样的。
这样就说明apache和TOMCAT整合成功!
2、测试均衡器
如果在 extra/httpd-vhosts.conf 中配置 没有设置 lbmethod=bytraffic,将使用默认的 byrequests ,控制分配的一共有三种方式,还有一种是 bybusyness 。
通过http://127.0.0.1多次访问,
如 果使用的是 byrequests 的分配方式,要想看到真正的效果,必须用一些压力测试工具,可用微软Microsoft Web Application Stress Tool进行简单压力测试,不然你靠不停刷新是体现不出来的,你只会在一个tomcat的控制台有输出结果。
只用用压力测试工具模拟大量用户同时访问,你会发现四个tomcat控制台均有打出控制信息,说明均衡器工作正常。
而如果配置为 bytraffic 并且tomcat6-a 和 tomcat6-b 设置了 loadfactor=1,则请求会均匀的分配给不同的tomcat,很容易测试出来。
如果想对此感兴趣,请查看apache 的文档并尝试修改
httpd.conf
----------------------
ProxyRequests Off
<proxy balancer://cluster>
BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>
----------------------
 中的 loadfactor  参数和
extra/httpd-vhosts.conf
----------------------
<VirtualHost *:80>
 ServerAdmin adminname
 ServerName localhost
 ServerAlias localhost
 ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On lbmethod=bytraffic
 ProxyPassReverse / balancer://cluster/
</VirtualHost>
----------------------
中的 lbmethod 参数


注意:如果apache 中出现如下错误
Encountered too many errors accepting client connections. Possible causes: dynamic address renewal, or incompatible VPN or firewall software. Try using the Win32DisableAcceptEx directive.

编辑httpd.conf 加入
Win32DisableAcceptEx ##加入这行
重启apache就解决了。

如果修改后还是不行,任然有错误记录,
cmd下
netsh winsock reset

因为这个错误可能与winsock有关,有网友也出现了这个问题,他认为是金山毒霸或者升级精灵修改了WINSOCK导致的。我没有安装但是系统经常自动更新,别的软件也有,可能会有冲突。
使用此条命令恢复Winsock后,重启电脑后这个问题就会解决了。

posted @ 2012-06-02 08:55 gdufo| 编辑 收藏

Tomcat6.0负载均衡策略 _ 1

http://www.cnblogs.com/shiyangxt/archive/2009/02/26/1398902.html

               开学以后,连续几天休息不好,总是犯困,也许这就是“春困秋乏”的症状吧。最近老师提出了负载均衡功能的需求,以减轻

网站的高峰期的服务器负担,现在学校的硬件设施还是蛮好的,有三,四台服务器可以提供使用,也很大程度的上方便了我做一些测试。

因为这个子项目,假期三个同学已经基本完工,所以我也只能出点微薄之力,把这个负载均衡搞定,具体用不用我不管,起码是我的一个

小功能。

 

               其实无论是分布式,数据缓存,还是负载均衡,无非就是改善网站的性能瓶颈,在网站源码不做优化的情况下,负载均衡可以说

是最直接的手段了。其实抛开这个名词,放开了说,就是希望用户能够分流,也就是说把所有用户的访问压力分散到多台服务器上,也可以

分散到多个tomcat里,如果一台服务器装多个tomcat,那么即使是负载均衡,性能也提高不了太多,不过可以提高稳定性,即容错性。

当其中一个主tomcat当掉,其他的tomcat也可以补上,因为tomcat之间实现了Session共享。待tomcat服务器修复后再次启动,就会

自动拷贝所有session数据,然后加入集群。这样就可以不间断的提供服务。如果要真正从本质上提升性能,必须要分布到多台服务器。

同样tomcat也可以做到。网上相关资料比较多,可以很方便的查到,但是质量不算高。我希望可以通过这篇随笔,系统的总结。本文的

例子是同一台服务器上运行两个tomcat,做两个tomcat之间的负载均衡。其实多台服务器各配置一个tomcat也可以,而且那样的话,可以使用

安装版的tomcat,而不用是下文中的免安装的tomcat,而且tomcat端口配置也就不用修改了。下文也会提到。

 

               tomcat的负载均衡需要apache服务器的加入来实现。在进行配置之前请先卸载调已安装的tomcat,然后检查apache的版本。

我这次配置使用的是apache-tomcat-6.0.18免安装版本,我亲自测试后推断安装版的tomcat在同一台机子上会不能启动两个以上,可能是

因为安装版的tomcat侵入了系统,导致即使在server.xml里修改了配置,还是会引起冲突。所以我使用tomcat免安装版。

apache使用的是apache_2.2.11-win32-x86-no_ssl.msi。如果版本低于2.2负载均衡的配置要有所不同,因为这个2.2.11和2.2.8版本

集成了jk2等负载均衡工具,所以配置要简单许多。别的版本我没有具体测试,有待考究。这两个软件可以到官方网站下载。

 

                 把Apache安装为运行在80端口的Windows服务,安装成功后在系统服务列表中可以看到Apache2.2服务。服务启动后在浏览器中

输入http://localhost进行测试,如果能看到一个"It works!"的页面就代表Apache已经正常工作了。把tomcat解压到任意目录,赋值一个另命名。

起名和路径对配置没有影响。但要保证端口不要冲突,如果装有Oracle或IIS的用户需要修改或关闭相关接口的服务。当然jdk的配置也是

必须的,这个不再过多叙述。

     

                 首先,在Apache安装目录下找到conf/httpd.conf文件,去掉以下文本前的注释符(#)以便让Apache在启动时自动加载代理(proxy)

模块。

 

    LoadModule proxy_module modules/mod_proxy.so
     LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
     LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
     LoadModule proxy_connect_module modules/mod_proxy_connect.so
     LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
     LoadModule proxy_http_module modules/mod_proxy_http.so

 

向下拉动文档找到<IfModule dir_module>节点,在DirectoryIndex index.html后加上index.jsp,这一步只是为了待会配置完tomcat后能看到小

猫首页,可以不做。继续下拉文档找到Include conf/extra/httpd-vhosts.conf,去掉前面的注释符。

 

然后打开conf/extra/httpd-vhosts.conf,配置虚拟站点,在最下面加上

 

复制代码
<VirtualHost *:80> 
         ServerAdmin 管理员邮箱
          ServerName localhost
         ServerAlias localhost 
         ProxyPass / balancer://sy/ stickysession=jsessionid nofailover=On 
         ProxyPassReverse / balancer://sy/ 
         ErrorLog "logs/sy-error.log"
         CustomLog "logs/sy-access.log" common
</VirtualHost>

复制代码

 

然后回到httpd.conf,在文档最下面加上

 

ProxyRequests Off 
<proxy balancer://sy> 
       BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1
       BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2
</proxy>

 

ProxyRequests Off 是告诉Apache需要使用反向代理,ip地址和端口唯一确定了tomcat节点和配置的ajp接受端口。loadfactor是负载因子,

Apache会按负载因子的比例向后端tomcat节点转发请求,负载因子越大,对应的tomcat服务器就会处理越多的请求,如两个tomcat都

是1,Apache就按1:1的比例转发,如果是2和1就按2:1的比例转发。这样就可以使配置更灵活,例如可以给性能好的服务器增加处理

工作的比例,如果采取多台服务器,只需要修改ip地址和端口就可以了。route参数对应后续tomcat配置中的引擎路径(jvmRoute)。

                 如果仅仅为了配置一个可用的集群,Tomcat的配置将会非常简单。分别打开两个tomcat的server.xml配置文件,其中一台可以采用默认

的设置,只需要修改两个地方,而另一个要有较大改动以避免与前一台冲突。如果两台不在同一台服务器上运行,对于端口就不需做改动。首先是

配置关闭端口,找到<Server port="8005" shutdown="SHUTDOWN">,第一台不变,把第二台改为9005。

                下面配置Connector的端口,找到non-SSL HTTP/1.1 Connector,即tomcat单独工作时的默认Connector,保留第一台默认配置,在8080端

口侦听,而把第二台设置为在9080端口侦听。往下找到AJP 1.3 Connector,<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />,这是

tomcat接收从Apache过来的ajp连接请求时使用的端口,保留第一台默认设置,把第二台端口改为9009。第一台tomcat的server.xml中找到

<Engine name="Catalina" defaultHost="localhost">,去掉这段或改为注释,把上方紧挨的<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">

注释符去掉,对于第二台,去掉注释符并把jvm1改为jvm2。

               向下找到<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>,去掉注释,这里的配置是为了可以在集群中的所有tomcat节点

间共享会话(Session)。如果仅仅为了获得一个可用的tomcat集群,Cluster只需要这么配置就可以了。

               只需要简单的几步就配置完成,然后可以测试一下是否配置成功。引用网上的一个测试方法,就是在webapps目录下新建test目录,在test目

录下新建test.jsp文件,代码我稍作改动如下:

 

复制代码
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>shiyang</title></head>
<body>
服务信息:
<%
out.println(request.getLocalAddr() 
+ " : " + request.getLocalPort()+"<br/>");%>
<%
out.println(
"<br> ID " + session.getId()+"<br/>"); 
String dataName = request.getParameter("dataName");

if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}

out.print(
"<b>Session 列表</b><br/>");
Enumeration e 
= session.getAttributeNames();

while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name 
+ " = " + value+"<br/>");
System.out.println( name 
+ " = " + value);
}
%>
<form action="test.jsp" method="POST">
名称:
<input type=text size=20 name="dataName">
<br/>
值:
<input type=text size=20 name="dataValue">
<br/>
<input type=submit value="提交">
</form>
</body>
</html>
复制代码

 

在test目录下继续新建WEB-INF目录和web.xml,在<web-app>节点下加入<distributable />,这一步非常重要,是为了通知tomcat服务器,

当前应用需要在集群中的所有节点间实现Session共享。如果tomcat中的所有应用都需要Session共享,也可以把conf/context.xml中的

<Context>改为<Context distributable="true">,这样就不需对所有应用的web.xml再进行单独配置。测试代码完成!

 

先启动Apache服务,在先后启动两台tomcat,分别点startup.bat批处理。如果一切顺利的话,就会启动成功。再次访问http://localhost

可以看到小猫页面。访问http://localhost/test/test.jsp。可以看到包括服务器地址,端口,session等信息在内的页面。

                然后你可以测试一下容错功能,关闭一个tomcat,看看服务是否正常,然后重启tomcat,关掉另一台tomcat,看看

是否也可以继续提供服务。当然你也可以配置多台tomcat,但是原理都一样。

 OK,讲到这里。

posted @ 2012-06-02 08:54 gdufo| 编辑 收藏

让开发自动化

http://www.ibm.com/developerworks/cn/java/j-ap/

posted @ 2012-06-01 22:25 gdufo 阅读(509) | 评论 (0)编辑 收藏

jmeter测试zkoss

http://books.zkoss.org/wiki/Small_Talks/2012/May/Perform_stress_test_on_ZK_using_JMeter-take_Shopping_Cart_as_an_example

Contents

[hide]

Preface

Dennis Chen has shared a small talk illustrating how you can execute a loading test with ZK applications using JMeter. Now, in this small talk we will take a real application as an example to demonstrate in detail how you can actually apply the ideas illustrated in Dennis’ article to perform a stress test.

Test plan

We will be using the "shopping cart" example from ZK Essentials as the template application to perform the stress test.

Setup

  • ZK 5.0.11
  • zk testing demo ( a demo based on the shopping cart sample)
  • Jmeter 2.5.1

Test Scenario

  1. User enters his user name and password for authentication
  2. Login successfully to the shopping site, redirect to index.zul
  3. User selects an item and drag to the shopping cart
  4. User checks out

Since this is a stress test, we can apply 50, 100, 150,... concurrent users to perform the test scenario simultaneously. In our example we have created a max of 300 accounts, which allows you to perform the test with as many as 300 concurrent users.

Before we start

As mentioned above we will be using the "shopping cart" example from ZK Essentials as the template application. However there is only one set of login/password in the current shopping cart implementation which is not sufficient for multiple users. To support multiple users, we have modified the shopping cart example to generate multiple accounts, so that each user will be logged in using a different account. This is done as follows, and it will be triggered as you click "createUserBtn" in login.zul:

1. prepare a CSV file that includes a list of user names and passwords:

Csv.png

2. Add the following code to LoginViewCtrl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void onClick$createUserBtn() {
        Map map = userinfo();
        Session session = StoreHibernateUtil.openSession();
        Transaction t = session.beginTransaction();
         
        Iterator entries = map.entrySet().iterator();
        int i = 0;
        while (entries.hasNext()) {
            i ++;
            Map.Entry entry = (Map.Entry) entries.next();
            String name = (String)entry.getKey();
            String pwd = (String)entry.getValue();
            User user = new User(i, name, pwd, "user");
            session.save(user);
            if (i % 20 == 0) {
                session.flush();
                session.clear();
            }
        }
        t.commit();
        session.close();
    }

Configuring ZK

As illustrated in Dennis’ small talk, you need to define IdGenerator to fix the desktop IDs and component IDs so that we can record and play the testing script. The IdGenerator is implemented as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MyIdgenerator implements IdGenerator {
    private static ThreadLocal<HttpServletResponse> response = new ThreadLocal<HttpServletResponse>();
    private static AtomicInteger ai = new AtomicInteger();
 
    public String nextComponentUuid(Desktop desktop, Component comp) {
        String number;
        if ((number = (String) desktop.getAttribute("Id_Num")) == null) {
            number = "0";
            desktop.setAttribute("Id_Num", number);
        }
        int i = Integer.parseInt(number);
        i++;// Start from 1
        desktop.setAttribute("Id_Num", String.valueOf(i));
        return "t_" + i;
    }
 
    public String nextDesktopId(Desktop desktop) {
        HttpServletRequest req = (HttpServletRequest)Executions.getCurrent().getNativeRequest();
        String dtid = req.getParameter("tdtid");
        if(dtid!=null){
        }
        return dtid==null?null:dtid;
    }
 
    public String nextPageUuid(Page page) {
        return null;
    }
}
  • Define your IdGenerator in zk.xml

Then, define your IdGenerator in zk.xml, for example,

1
2
3
<system-config>
        <id-generator-class>foo.MyIdgenerator</id-generator-class>
</system-config>

Preparing Testing Scripts

Now we are ready to record the scripts. We will be recording 6 HTTP requests as illustrated in the image below. What we need to do is to configure the parameters of these 6 requests based on the application that we wish to test.

All.png

Load CSV file as the variable of the user name and password

  • Add a CSV Data Set Config

First we need to add a CSV Data Set Config here. The element will iterate the csv data set to simulate muti-users login into the application. Please specify a fully qualified name to the Filename field (ex: C:\mycsv\users.csv ), and specify the variable name to the Variable Names field for later use.

Csv data set.png

  • Add BSF PostProcessor

Then we need to ask jmeter to generate the accounts and passwords automatically based on our CSV file. What we need to do is to add a BSF PostProcessor element, set the language to beanshell, and define:


var username = vars.get("username");

var password = vars.get("password");

vars.put("user","{\"value\":\""+username+"\",\"start\":2}");

vars.put("pwd","{\"value\":\""+password+"\",\"start\":2}");


This script will get the username and password variables generated by CSV Data Set Config element, and combine the result and some text as a parameter which will be used as user names and passwords later.

BSF PostProcessor.png

Set account & password as variables

With these settings ready, we can now set the parameter dtid as ${dtid} and use EL to replace a fixed account and password in the first ajax request (i.e. the login request). For example if we send zk/zk as user name and password, then we will be seeing

data_3: {"value":"zk","start":2} //for username

data_4: {"value":"zk","start":2} //for password

in the recorded jmeter’s request. Then, we use ${user} and ${pwd} to replace {"value":"zk","start":2} for handling the accounts and passwords dynamically.

Submit.png

Generate new desktop ID for redirecting to a new page

After an user logged into the system, he will be redirected to index.zul. Since the URL is changed, the desktop and it’s id will also be changed, we need to retrieve the desktop id again using ${__intSum(${dtid},1,dtid)}.

Specify parameter

The last 3 http requests are for adding products to the shopping cart, check out, and close the browser tab. What we need to do is just to modify their tdtid to ${__intSum(${dtid},1,dtid).

DTID.png

Add the listeners for creating reports

There are many different elements that allows you to generate different kinds of reports, such as Aggregate Report and Graph Results. You can add these listeners to Thread Group or HTTP request depending on the report you wish to generate.

Listener1.png

Now we have completed all the settings and have saved these configurations as test.jmx.

Running the test

Now we are ready to start the application and to run the test.

  1. Generate accounts
  2. Start your web server, and access login.zul. Click createUserBtn for creating multiple accounts.

    CreateAccounts.png

  3. Run the testing script
    1. Open jmeter’s menu, File > Open , and load test.jmx.
    2. Specify your IP and port, for example we use localhost/8080 as ip and port number
    3. Http request default.png

    4. In Thread Group ( the root element), set the number of concurrent users to test.
    5. Set number of Users .png

    6. Perform Run > Start to run the test.
    7. You can then observe the average response time, 90% line response time, median response time and other results by accessing the Aggregate Report .

      Aggregate report.png

Trouble-shooting & Tips

  1. Tips: Performing repeating tests
  2. If you have finished a round of test (for example 0~50) you should restart your server before performing another round of test. This is because after you finish a round of test, there will be an extra item listed in each user’s page because they all ordered an item. This extra item is displayed at the bottom of the page (see the image on the right). As there is a DOM change due to this extra item, components’ IDs and orders are also changed thus different from the script you recorded earlier. To solve this problem, just restart your server before performing another round of test.

    Without order.png One order.png

  3. Trouble-shooting: Erred response
  4. Nothing response.png

    If you encounter the Response data error shown as the image above, it is most likely that you did not implement IdGenerator correctly. Please refer to Configuring ZK section to implement UUID.

  5. Trouble-shooting: Timeout error
  6. Timeout.png

    Timeout errors occur when the desktop id in the Ajax request is no longer available at the server side. This normally happens when the URL is changed. If this happens, you need to retrieve desktop ID again. Please refer to Testing Scripts section to implement Desktop ID.

    Timeout may also relate to the max allowed desktops. In ZK there is a setting called “max-desktops-per-session” which defines the max concurrent desktops for each session. The more browser tabs an user opens the more desktops will be saved on the session. If the number exceeds the max allowed desktops then some desktops will be dropped with the timeout error.

    By default the number is 15 which means an user can open as many as 15 tabs in a same browser at the same time. If you have configured it to a smaller number for saving the memory, and in your use case the users will be opening up multiple tabs then you should double check whether this is the reason causing the timeout error. To change this setting, use:

    1
    2
    3
    <session-config>
        <max-desktops-per-session>1</max-desktops-per-session>
    </session-config>
  7. Tips: close browser tab for saving memory
  8. ZK stores desktops in sessions, when user closes the browser tab ZK will send the rmDesktop command to remove the desktop. We can simulate this behavior to save memory when performing a stress test. This is done in the last http request defined in test.jmx. You can refer to the image below:

    RmDesktop.png

Downloads

users.csv - users.csv (Please place the csv file under C:/mycsv/)

zk testing demo – the modified shopping cart application used in this small talk

jmeter 2.5.1 – http://jmeter.apache.org/download_jmeter.cgi

test.jmx – test.jmx


posted @ 2012-05-31 23:35 gdufo| 编辑 收藏

SQL2008的数据更新跟踪测试 (监控数据表变化,可用于同步)

http://blog.csdn.net/jinjazz/article/details/5495955

最近一个项目中需要监测SQLServer数据库中某些表的数据更新情况,于是做了一番POC测试和简单性能的评估.这里使用的是 SQLServer2008的更改跟踪.因为需求原因,没有考虑使用进一步的变更数据捕获.

 

POC过程如下:


这里我们建立一个测试环境,模拟数据在 Insert , Update 和 Delete 情况下的跟踪效果。

1 、测试脚本的准备,下面脚本建立一个新的数据库环境,并作相应的跟踪配置后向表中添加删除更改数据。




Use master

go

/***

1 、建立测试环境:生成一个带主键的测试表 T_Trace

*/

if ( DB_ID ( 'db_Trace_test' ) is not null ) drop database db_Trace_test

go

Create DataBase db_Trace_test

go

use db_Trace_test

go

Create Table T_Trace ( id int not null , name varchar ( 100 )

CONSTRAINT [ PK_T_Trace ] PRIMARY KEY CLUSTERED ( [ id ] ASC )

)

go

/***

2 、配置数据库和表的更改跟踪参数

*/

ALTER DATABASE db_Trace_test SET

    CHANGE_TRACKING = ON (

            AUTO_CLEANUP = ON ,            -- 打开自动清理选项

            CHANGE_RETENTION = 1 HOURS    -- 数据保存期为时

    );



ALTER TABLE dbo . T_Trace ENABLE CHANGE_TRACKING

go

/***

3 、向表中增加修改删除数据

*/

insert into T_Trace values ( 1 , ' 上海 ' ),( 2 , ' 北京 ' ),( 3 , ' 广州 ' )

delete from T_Trace where id = 3


update T_Trace set name = ' 天津 ' where id = 1

2 、跟踪分析,测试脚本和效果如下


/***

4 、获取更改过的数据

*/

SELECT

    CHG . Sys_Change_Version as 序 列 , id as 主键 , Sys_change_Operation as 操 作

FROM CHANGETABLE ( CHANGES dbo . T_Trace , 0 ) CHG

order by CHG . Sys_Change_Version

/*

其中,测试脚本中函数 CHANGETABLE 的第二个参数 0 代表查询开始的事物操作序列,这三条数据分别表示两个插入( I )和一个删除( D )操作并且用主键 ID 标识出来。

* 这里主键为 1 的数据标志为插入,是因为 Insert 和 Update 是在同一个跟踪事务中查询出来的。

3 、调整跟踪范围参数,我们从序列为 2 的操作开始跟踪,这样可以跟踪到测试数据的 Update 语句:

SELECT

    CHG . Sys_Change_Version as 序列 , id as 主键 , Sys_change_Operation as 操作

FROM CHANGETABLE ( CHANGES dbo . T_Trace , 2) CHG


order by CHG . Sys_Change_Version


这个结果则表示,主键为 1 的数据数据执行过更新操作 (U)


1、硬件测试环境:


2 、软件测试环境:

Windows 2008Server SQLServer2008

3 、样本数据:

       /--**--/

4 、测试结果:其中判断和提取更新表示查询时间,包含了返回到 SQLServer 客户端的传输时间。

序列

源表数据

操作

判断更新

提取更新

1

1000

Delete 语句删除 1000

0

2

0

Insert 语句插入 100

0

0

3

100

Insert 语句插入 1000

0

0

4

1100

Insert 语句插入 10000

0

0

5

11100

Insert 语句插入 100000

3

4

6

111100

Insert 语句插入 100000

6

7

7

211100

Insert 语句插入 100000

7

11

8

311100

Delete 语句删除 100

0

9

311100

Update 语句更新 100

0

0

10

311100

Update 语句更新 1000

0

0

11

311100

Update 语句更新 10000

0

0

5 、测试评估:

       在变更数据量万级的情况下,可以很快地响应跟踪结果并提取出所需要的数据。

posted @ 2012-05-27 22:31 gdufo| 编辑 收藏

ad 删除一个实体的SQL语句

DECLARE
    /**
     * Please change this one to any client id you want to delete
     **/
    v_Client_ID                                                 NUMBER      := 1000014;
    
    v_SQL1                               VARCHAR2(1024);
    
    CURSOR Cur_Contraints  IS
                select  table_name,constraint_name
               from user_constraints  
                where  status='ENABLED'  AND constraint_type='R' ;
        
     CURSOR Cur_Contraints2  IS
                select table_name,constraint_name
                from user_constraints
                where status='DISABLED' AND constraint_type='R';
                
        CURSOR Cur_Triggers  IS
                select TRIGGER_NAME
                from user_triggers
                where status='ENABLED';
                        
   CURSOR Cur_RemoveData  IS
            select 'delete from '|| TABLENAME ||' where AD_Client_ID=' || v_Client_ID
            AS v_SQL
                from AD_Table a where a.ISVIEW='N'
                AND exists ( select AD_Column_ID from AD_Column c where

a.AD_Table_ID=c.AD_Table_ID
                and upper(c.COLUMNNAME)= upper('AD_Client_ID') );
            
                
BEGIN
    
    DBMS_OUTPUT.PUT_LINE('  Delete Client Where AD_Client_ID=' || v_Client_ID);
    
    /****************************************************************
     *  Disable all the constraints one by one
     ****************************************************************/
     DBMS_OUTPUT.PUT_LINE(' Disable the contraints ');
     FOR p IN Cur_Contraints  LOOP
       BEGIN
       v_SQL1 := 'alter table '|| p.table_name ||' disable constraint '|| p.constraint_name;
        EXECUTE IMMEDIATE v_SQL1;        
       END;  
     END LOOP;        --        Disable contraints
     
     
     DBMS_OUTPUT.PUT_LINE(' Disable the triggers ');
     FOR p IN Cur_Triggers  LOOP
       v_SQL1 := 'alter trigger '|| p.TRIGGER_NAME ||' disable ';
        EXECUTE IMMEDIATE v_SQL1;
     END LOOP;        --        Disable contraints
     
     /****************************************************************
     *  Remove all the records belongs to that client
     ****************************************************************/
    FOR p IN Cur_RemoveData LOOP
        v_SQL1 := p.v_SQL;
        EXECUTE IMMEDIATE v_SQL1;
        
     END LOOP;        --        Remove data
     
     
     /****************************************************************
     *  Disable all the constraints one by one
     ****************************************************************/
     DBMS_OUTPUT.PUT_LINE(' Enable the contraints ');
    FOR p IN Cur_Contraints2  LOOP
        BEGIN
        v_SQL1 := 'alter table '|| p.table_name ||' enable constraint '|| p.constraint_name;
        EXECUTE IMMEDIATE v_SQL1;        
        END;
     END LOOP;        --        Enable contraints
     
     DBMS_OUTPUT.PUT_LINE(' Enable the triggers ');
     FOR p IN Cur_Triggers  LOOP
       v_SQL1 := 'alter trigger '|| p.TRIGGER_NAME ||' enabled ';
        EXECUTE IMMEDIATE v_SQL1;
     END LOOP;        --        Enable contraints
     
     COMMIT;


END;

posted @ 2012-05-26 16:57 gdufo 阅读(575) | 评论 (0)编辑 收藏

id登录窗口与生成主界面的序列图



posted @ 2012-05-25 17:01 gdufo 阅读(448) | 评论 (0)编辑 收藏

SQL 2005配置发邮件


http://www.sqlstudy.com/sql_article.php?id=2008072403

SQL Server:在 SQL Server 2005 中配置数据库邮件,发送邮件

[作/译者]:鹏城万里    [日期]:2008-07-24    [来源]:本站原创    [查看]: 6343

【鹏城万里】 发表于 www.sqlstudy.com

SQL Server:在 SQL Server 2005 中配置数据库邮件。

对于真正的 DBA 来说,数据库邮件是必不可少的。 例如,数据库发生了警报(alert), DBA 希望得到邮件通知,以便即时排除故障。 或者是监控数据库作业(SQL Server Job)的运行状况,当检查到失败的作业时, 就发送数据库邮件报告给 DBA。

在 SQL Server 2000 中 配置 “SQL Mail”,需要安装 Outlook,配置过程比较麻烦。 在 SQL Server 2005 中配置 “Database Mail” 就相对容易多了。 主要是理清思路。

SQL Server 并没有内置邮件服务器(Mail Server), 它跟我们发送邮件一样,需要用户名和密码通过 SMTP(Simple Message Transfer Protocol) 去连接邮件服务器。我们想让 SQL Server 来发送邮件,首先要告诉它用户名称,密码, 服务器地址,网络传送协议,邮件服务器的端口。。。等信息。这是通过 SQL Server 系统 存储过程 sysmail_add_account_sp 来实现的。

exec sysmail_add_account_sp 

这样,在 SQL Server 2005 中就添加了一个发送邮件的帐户。 道理上讲,有了这个邮件帐户,SQL Server 就可以发送邮件了。 如:

sp_send_dbmail @account_name = 'mail_account' 

但是,SQL Server 考虑的更周全。试想:如果这个邮件帐户发生故障 (比如:用户密码过期,或者邮件服务器宕机)那岂不是发送不了邮件了? 为了应对这种情况,SQL Server 2005 引入了 mail profile 这个东东。 一个 profile 中可以包含多个 account (邮件帐户),这样,SQL Server 发邮件的时候会依次尝试 profile 中的多个邮件帐户,如果发送成功,则退出, 否则,利用下一个邮件帐户发送邮件。其中,添加 profile 和 在 account 和 profile 建立映射是通过下面两个系统存储过程实现的:

sysmail_add_profile_sp sysmail_add_profileaccount_sp 

这时候,SQL Server 发送邮件,就采用下面的方法了:

sp_send_dbmail @profile_name = 'profile_name' 

下面是具体的配置邮件步骤

在 sa 系统帐户下运行。

1. 启用 SQL Server 2005 邮件功能。

use master go  exec sp_configure 'show advanced options',1 go  reconfigure go  exec sp_configure 'Database mail XPs',1 go  reconfigure go 

2. 在 SQL Server 2005 中添加邮件帐户(account)

exec msdb..sysmail_add_account_sp         @account_name            = 'p.c.w.l'                 -- 邮件帐户名称(SQL Server 使用)        ,@email_address           = 'webmaster@sqlstudy.com'  -- 发件人邮件地址        ,@display_name            = null                      -- 发件人姓名        ,@replyto_address         = null        ,@description             = null        ,@mailserver_name         = '58.215.64.159'           -- 邮件服务器地址        ,@mailserver_type         = 'SMTP'                    -- 邮件协议(SQL 2005 只支持 SMTP)        ,@port                    = 25                        -- 邮件服务器端口        ,@username                = 'webmaster@sqlstudy.com'  -- 用户名        ,@password                = 'xxxxxxxxx'               -- 密码        ,@use_default_credentials = 0        ,@enable_ssl              = 0        ,@account_id              = null 

3. 在 SQL Server 2005 中添加 profile

exec msdb..sysmail_add_profile_sp @profile_name = 'dba_profile'      -- profile 名称                                   ,@description  = 'dba mail profile' -- profile 描述                                   ,@profile_id   = null 

4. 在 SQL Server 2005 中映射 account 和 profile

exec msdb..sysmail_add_profileaccount_sp  @profile_name    = 'dba_profile' -- profile 名称                                           ,@account_name    = 'p.c.w.l'     -- account 名称                                           ,@sequence_number = 1             -- account 在 profile 中顺序  

5. 利用 SQL Server 2005 Database Mail 功能发送邮件。

exec msdb..sp_send_dbmail @profile_name =  'dba_profile'               -- profile 名称                           ,@recipients   =  'sqlstudy@163.com'          -- 收件人邮箱                           ,@subject      =  'SQL Server 2005 Mail Test' -- 邮件标题                           ,@body         =  'Hello Mail!'               -- 邮件内容                           ,@body_format  =  'TEXT'                      -- 邮件格式  

6. 查看邮件发送情况:

use msdb go  select * from sysmail_allitems select * from sysmail_mailitems select * from sysmail_event_log 

如果不是以 sa 帐户发送邮件,则可能会出现错误:

Msg 229, Level 14, State 5, Procedure sp_send_dbmail, Line 1 EXECUTE permission denied on object 'sp_send_dbmail', database 'msdb', schema 'dbo'. 

这是因为,当前 SQL Server 登陆帐户(login),在 msdb 数据库中没有发送数据库邮件的权限, 需要加入 msdb 数据库用户,并通过加入 sp_addrolemember 角色赋予权限。假设该SQL Server 登陆帐户 名字为 “dba”

use msdb go  create user dba for login dba go  exec dbo.sp_addrolemember @rolename   = 'DatabaseMailUserRole',                           @membername = 'dba' go 

此时,再次发送数据库邮件,仍可能有错误:

Msg 14607, Level 16, State 1, Procedure sp_send_dbmail, Line 119 profile name is not valid 

虽然,数据库用户 “dba” 已经在 msdb 中拥有发送邮件的权限了, 但这还不够,他还需要有使用 profile:“dba_profile” 的权限。

use msdb go  exec sysmail_add_principalprofile_sp  @principal_name = 'dba'                                      ,@profile_name   = 'dba_profile'                                      ,@is_default     = 1 

从上面的参数 @is_default=1 可以看出,一个数据库用户可以在多个 mail profile 拥有发送权限。

现在,可以利用 SQL Server 2005 发送数据库邮件了吧。如仍有问题,请留言。

 

posted @ 2012-05-24 16:38 gdufo 阅读(1131) | 评论 (0)编辑 收藏

仅列出标题
共19页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last 

导航

统计

常用链接

留言簿(6)

随笔分类

随笔档案

文章分类

文章档案

收藏夹

Hibernate

友情链接

搜索

最新评论

阅读排行榜

评论排行榜