<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 閱讀(429) 評論(0)  編輯  收藏 所屬分類: jmeter and badboy

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

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 精精国产www视频在线观看免费| 亚洲娇小性色xxxx| 国产精品免费久久久久电影网| 国产乱子伦精品免费无码专区| 亚洲成a人无码亚洲成www牛牛| 成人av免费电影| 亚洲第一街区偷拍街拍| 香蕉视频在线观看免费国产婷婷| 亚洲人成色77777在线观看| AV片在线观看免费| 亚洲日韩精品无码专区加勒比| 成人毛片免费播放| 男男gvh肉在线观看免费| 又粗又大又猛又爽免费视频 | 亚洲精品乱码久久久久蜜桃| 毛片免费全部播放一级| 亚洲av纯肉无码精品动漫| 免费国产在线观看| 999zyz**站免费毛片| 久久狠狠高潮亚洲精品| 美女被cao免费看在线看网站| 亚洲乱码国产乱码精华| 国产三级免费观看| 99精品视频免费| 亚洲第一精品在线视频| 永久免费av无码网站韩国毛片| 亚洲欧美黑人猛交群| 亚洲欧洲自拍拍偷精品 美利坚| 久久久国产精品福利免费| 亚洲人成人77777网站不卡| 午夜影视在线免费观看| a一级爱做片免费| 亚洲经典在线中文字幕| 国产精品免费_区二区三区观看| 一个人看的免费高清视频日本| 99亚洲精品高清一二区| 国产一卡二卡≡卡四卡免费乱码 | 9420免费高清在线视频| 亚洲爆乳少妇无码激情| 亚洲成AV人片一区二区| 女人张开腿给人桶免费视频|