<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    Jmeter《Java請求》使用總結

    1. 線程組,在我們測試方案里面,每個線程模擬一個用戶,執行用戶的登錄、等等等一系列的操作。由于我們的項目是長連接的,如何能實現多個sample公用一個長連接客戶端,考慮了很久,最后實現方法如下:
    1 package tea.client.network;
    2 /**
    3  * @author Teaey
    4  * @creation 2012-8-25
    5  */
    6 public class NetworkClientHolder
    7 {
    8     /**
    9      * 這里使用ThradLocal存儲BaseClient
    10      * 方便一輪測試的每個sample都是由同一個socketChannel發送
    11      * 更真實的模擬用戶
    12      */
    13     private static ThreadLocal<BaseClient> clientHolder = new ThreadLocal<BaseClient>();
    14     public static BaseClient getClient(String ip, String port)
    15     {
    16         BaseClient client = clientHolder.get();
    17         if (null == client)
    18         {
    19             client = new BaseClient(ip, port);
    20             client.connect();
    21             clientHolder.set(client);
    22         }
    23         return client;
    24     }
    25 }
      代碼中使用thread_local保存Socket客戶端,這樣每個sample中發送數據的客戶端都是從這里拿的,就可以保證長連接的情況下,socket不會重復創建,很好的模擬了用戶。
      當然不單單是鏈接可以保存,所有需要在線程中共享的數據都可以通過這種方法來實現。


      2. 接下來是如何封裝發送請求的客戶端,這里用的netty,具體可以根據項目情況使用mina或者nio都可以。代碼直接明了^_^:
    1 package tea.client.network;
    2
    3 import java.net.InetSocketAddress;
    4 import java.util.concurrent.Executors;
    5 import org.jboss.netty.bootstrap.ClientBootstrap;
    6 import org.jboss.netty.channel.Channel;
    7 import org.jboss.netty.channel.ChannelFuture;
    8 import org.jboss.netty.channel.ChannelHandlerContext;
    9 import org.jboss.netty.channel.ChannelPipeline;
    10 import org.jboss.netty.channel.ChannelPipelineFactory;
    11 import org.jboss.netty.channel.ChannelStateEvent;
    12 import org.jboss.netty.channel.Channels;
    13 import org.jboss.netty.channel.ExceptionEvent;
    14 import org.jboss.netty.channel.MessageEvent;
    15 import org.jboss.netty.channel.SimpleChannelHandler;
    16 import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
    17 import tea.common.network.ClientDecoder;
    18 import tea.common.network.ClientEncoder;
    19 import tea.common.network.ClientMessage;
    20
    21 /**
    22  * @author Teaey
    23  * @creation 2012-8-25
    24  */
    25 public class BaseClient
    26 {
    27     public BaseClient(String ip, String port)
    28     {
    29         this.ip = ip;
    30         this.port = port;
    31     }
    32     private String           ip;
    33     private String           port;
    34     private Channel          channel;
    35     private ClientBootstrap  bootstrap;
    36     private Object           syn             = new Object();
    37     private static final int Receive_Timeout = 10000;       //ms
    38     private ClientMessage    response        = null;
    39     public void connect()
    40     {
    41         bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
    42         bootstrap.setOption("tcpNoDelay", true);
    43         bootstrap.setPipelineFactory(new ClientPipelineFactory());
    44         while (true)
    45         {
    46             ChannelFuture future = bootstrap.connect(new InetSocketAddress(ip, Integer.parseInt(port)));
    47             future.awaitUninterruptibly(5000);
    48             if (future.isDone())
    49             {
    50                 channel = future.getChannel();
    51                 if (channel != null && channel.isConnected())
    52                 {
    53                     break;
    54                 }
    55             }
    56         }
    57     }
    58     public void disconnect()
    59     {
    60         if (channel.isConnected())
    61         {
    62             channel.disconnect();
    63         }
    64     }
    65     public boolean isConnected()
    66     {
    67         return channel.isConnected();
    68     }
    69     public void close()
    70     {
    71         if (this.channel.isOpen())
    72         {
    73             this.channel.close();
    74         }
    75         bootstrap.releaseExternalResources();
    76     }
    77     /**
    78      * 發送消息,無需返回
    79      */
    80     public void send(ClientMessage message)
    81     {
    82         channel.write(message);
    83     }
    84     /**
    85      * 發送消息,等待返回
    86      */
    87     public ClientMessage sendWaitBack(ClientMessage message)
    88     {
    89         response = null;
    90         try
    91         {
    92             channel.write(message);
    93             synchronized (syn)
    94             {
    95                 try
    96                 {
    97                     syn.wait(Receive_Timeout);
    98                 } catch (InterruptedException e)
    99                 {
    100                     e.printStackTrace();
    101                 }
    102             }
    103             if (null == response)
    104             {
    105                 System.err.println("Receive response timeout");
    106             }
    107         } catch (Exception e)
    108         {
    109             e.printStackTrace();
    110         }
    111         return response;
    112     }
    113     class ClientPipelineFactory implements ChannelPipelineFactory
    114     {
    115         public ChannelPipeline getPipeline() throws Exception
    116         {
    117             ChannelPipeline p = Channels.pipeline();
    118             p.addLast("frameDecoder", new ClientDecoder());
    119             p.addLast("fremeEncoder", new ClientEncoder());
    120             p.addLast("logicHandler", new ClientMsgHandler());
    121             return p;
    122         }
    123     }
    124     class ClientMsgHandler extends SimpleChannelHandler
    125     {
    126         public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
    127         {
    128             Object obj = e.getMessage();
    129             if (obj instanceof ClientMessage)
    130             {
    131                 ClientMessage msg = (ClientMessage) obj;
    132                 response = msg;
    133                 synchronized (syn)
    134                 {
    135                     syn.notifyAll();
    136                 }
    137             }
    138         }
    139         public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception
    140         {
    141             System.out.println("connected server:" + ctx.getChannel());
    142         }
    143         public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception
    144         {
    145             System.out.println("disconnected server:" + ctx.getChannel());
    146         }
    147         public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception
    148         {
    149             System.out.println("Error in exceptionCaught:" + e.getCause());
    150         }
    151     }
    152 }
      這段代碼展示了我們的客戶端,這里所有的請求有兩種發送模式,一種是發送并阻塞等待返回(sendWaitBack),第二種就是直接發送(send)。

      3. 有了發送請求的客戶端,那如何能夠更簡單的實現一個協議好讓客戶端發送,再貼一段代碼^_^:
    1 package tea.client.network;
    2
    3 import org.apache.jmeter.config.Arguments;
    4 import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
    5 import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
    6 import org.apache.jmeter.samplers.SampleResult;
    7 import com.google.protobuf.InvalidProtocolBufferException;
    8 import com.google.protobuf.MessageLite;
    9
    10 /**
    11  * @author Teaey
    12  * @creation 2012-8-25
    13  */
    14 public abstract class BaseSample extends AbstractJavaSamplerClient
    15 {
    16     public static final String PARAM_IP   = "ip";
    17     public static final String PARAM_PORT = "port";
    18     public static final String VAR_IP     = "${ip}";
    19     public static final String VAR_PORT   = "${port}";
    20     protected BaseClient       client;
    21     public void addParameter(Arguments params)
    22     {
    23     }
    24     /**
    25      * Jmeter獲取消息參數,默認配置ip和port兩個參數
    26      * 如果子類有更多參數,調用super.getDefaultParameters()獲取Arguments后,繼續設置其他方法
    27      */
    28     @Override
    29     public Arguments getDefaultParameters()
    30     {
    31         System.out.println("1.getDefaultParameters");
    32         Arguments params = new Arguments();
    33         params.addArgument(PARAM_IP, VAR_IP);
    34         params.addArgument(PARAM_PORT, VAR_PORT);
    35         addParameter(params);
    36         return params;
    37     }
    38     /**
    39      * runTest的前置方法
    40      */
    41     @Override
    42     public void setupTest(JavaSamplerContext context)
    43     {
    44         System.out.println("2.setupTest:" + context.containsParameter(PARAM_IP));
    45         String ip = context.getParameter(PARAM_IP);
    46         String port = context.getParameter(PARAM_PORT);
    47         this.client = NetworkClientHolder.getClient(ip, port);
    48         System.out.println("thread--->" + Thread.currentThread().getId() + " client--->" + client);
    49     }
    50     /**
    51      * Jmeter調用,用于實際的測試
    52      */
    53     @Override
    54     public SampleResult runTest(JavaSamplerContext context)
    55     {
    56         SampleResult sample = getSample();
    57         sample.sampleStart();
    58         try
    59         {
    60             MessageLite response = doTest();
    61             String msg = response == null ? "" : response.toString();
    62             sample.setResponseMessage(msg);
    63             sample.setSuccessful(true);
    64         } catch (Exception e)
    65         {
    66             sample.setSuccessful(false);
    67             e.printStackTrace();
    68         } finally
    69         {
    70             sample.sampleEnd();
    71         }
    72         return sample;
    73     }
    74     /**
    75      * 獲取本Sample的標簽,子類實現
    76      */
    77     public abstract String getLabel();
    78     /**
    79      * 獲取一個帶標簽的Sample
    80      */
    81     public SampleResult getSample()
    82     {
    83         SampleResult sample = new SampleResult();
    84         sample.setSampleLabel(getLabel());
    85         return sample;
    86     }
    87     /**
    88      * Jmeter調用,用于
    89      */
    90     @Override
    91     public void teardownTest(JavaSamplerContext context)
    92     {
    93         System.out.println("4.teardownTest");
    94     }
    95     /**
    96      * 需實現,具體測試的方法,調用client的send/sendWithBack發送請求
    97      * 如無返回,放回null即可
    98      */
    99     public abstract MessageLite doTest() throws InvalidProtocolBufferException;
    100 }
      好的,這里封裝了下AbstractJavaSamplerClient,每個消息默認包含ip和port參數,這可以再jmeter的用戶變量中定義好。為了方便大家添加消息的參數,這里實現了空的
     addParameter(Arguments params)方法,這樣在具體消息中直接重寫這個方法,來添加具體的參數。是不是很方便?^_^,具體協議還需要實現的兩個方法分別是:getLabel和doTest。第一個方法時用于報告顯示的請求名字,一般定義為消息名字+“Label”就OKay。第二個方法就是我們重點重寫的方法,這里再貼段代碼,是一個具體消息的實現:
    1 package tea.client;
    2
    3 import com.google.protobuf.InvalidProtocolBufferException;
    4 import com.google.protobuf.MessageLite;
    5 import tea.client.network.BaseSample;
    6 import tea.common.network.ClientMessage;
    7 import tea.common.network.RPC.HeartBeat_C2S;
    8 import tea.common.network.RPC.HeartBeat_S2C;
    9
    10 /**
    11  * @author Teaey
    12  * @creation 2012-8-24
    13  */
    14 public class HeartBeatSample extends BaseSample
    15 {
    16     @Override
    17     public MessageLite doTest() throws InvalidProtocolBufferException
    18     {
    19         HeartBeat_C2S.Builder request = HeartBeat_C2S.newBuilder();
    20         request.setTimestamp(System.currentTimeMillis());
    21         ClientMessage cm = new ClientMessage();
    22         cm.setContent(request.build().toByteArray());
    23         cm.setName("HeartBeat");
    24         ClientMessage sm = client.sendWaitBack(cm);
    25         HeartBeat_S2C response = HeartBeat_S2C.parseFrom(sm.getContent());
    26         return response;
    27     }
    28     @Override
    29     public String getLabel()
    30     {
    31         return "HeartBeatSample";
    32     }
    33 }
      可以看到doTest的工作就是封裝請求,并拿到父類的client發送,然后返回響應(send方式返回null),Okay,大功告成。

    posted on 2013-11-04 13:17 順其自然EVO 閱讀(428) 評論(0)  編輯  收藏 所屬分類: jmeter and badboy

    <2013年11月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产大片免费观看中文字幕| 亚洲综合免费视频| 中国人免费观看高清在线观看二区| 亚洲中文字幕无码久久2017| 国产真人无码作爱视频免费| 亚洲AV无码一区二区三区人| 亚洲av高清在线观看一区二区| 久久精品一区二区免费看| 亚洲日韩一区二区一无码| 亚洲男人av香蕉爽爽爽爽| 最近新韩国日本免费观看| 苍井空亚洲精品AA片在线播放 | ww亚洲ww在线观看国产| 国产免费无遮挡精品视频| 久久精品成人免费看| 精品亚洲福利一区二区| 亚洲AV人无码综合在线观看| 日本v片免费一区二区三区| 久久国产精品免费观看| 疯狂做受xxxx高潮视频免费| 77777_亚洲午夜久久多人| 亚洲国产精品成人网址天堂 | 亚洲VA成无码人在线观看天堂| 成人免费午夜在线观看| 免费观看在线禁片| 立即播放免费毛片一级| 亚洲人成网站18禁止久久影院 | 99久久免费精品高清特色大片| 亚洲av永久无码精品秋霞电影秋| 婷婷久久久亚洲欧洲日产国码AV| 国产精品免费小视频| 国产精品色拉拉免费看| 在线观看免费播放av片| 一级女性全黄久久生活片免费 | 久久久久亚洲精品无码蜜桃| 亚洲精品麻豆av| 国产男女猛烈无遮挡免费视频| 1024免费福利永久观看网站| 国产V亚洲V天堂无码久久久| 亚洲国产天堂久久久久久| 国产大片免费观看中文字幕|