スレッドセーフなクラスのアプリケーション・パフォーマンス・テスト

次のように最近成功した支払の後、圧力テストコールバックインタフェースをやって、シーンは、ユーザーの購入VIPであります:

テストシナリオ

成功した支払ユーザーの後、VIPの開口部と操作を更新するバックエンドの要求に終了します。

インタフェースの処理ロジック

まず、署名検証インタフェースパラメータが正しい場合、注文情報とステータスを判断するためにロックされ、ユーザーは、ロックが成功した後に解放され、VIPの処理時間のトランザクションを追加します。ロックは、ユーザーと注文のロックを配布され、スキームが使用されていますredis

ドキュメントインターフェイス

インタフェースの基本情報

  1. インタフェース名の購入会員または会員更新
  2. リクエストのURL / API /メンバー/ createOrRenewMember
  3. チェック、要求、参照用に検査工程へのダウンJSONリクエストパラメータ文字列裏書例

リクエストパラメータ

{
    "sign": "CGvmkLeGtDv/Om8RbY52pMKNMi/xdLYAgRhIxC3uPqJsEdOvHj+S6zFobN0fxA/vksmCKJHhN6hFQrFIa3C6oK6EH7/BnJEsUMmIRsXMra32lzE/Tq9nqjYIdy996qc6eJWsxshqquj9Tb78pN152ndCNgvujMYsUHT4v7QxUW4=",
    "orderNo": "E2341234",
    "systemId": 94848494
}复制代码

リクエストパラメータ説明

フィールド説明 フィールド名 フィールドタイプ リマーク
注文番号 注文番号 ストリング 注文番号
ユーザーアカウント システムID 合格します
署名 符号 ストリング 署名の文字列を生成するためのツールをご提供してください

リターン・パラメータ

{
    "code": 0,
    "message": "success",
    "data": {
        "memberId": 123123,
        "systemId": 86123123
    }
}复制代码

コードの成功は0に等しく、

テストプログラム

同様のプログラムが参照するメッセージキュー上のパフォーマンステストを行う方法

難しさ

  • ロックのユーザーが同時に処理順序を有することができるので、圧力は、各パラメータが異なります測定しなければなりません。
  • ユーザはユーザに存在する必要があり、必要な圧力の量を測定するために、ユーザが提案されています。

ソリューション

  • ユーザIDと順序番号を使用し、パラメータ化されたAtomicIntegerすべてのパラメータがユニークで互いに異なっていることを確実にするために、事前にスレッドセーフなクラスのロードおよび引数の良い配列。(リピート演奏の確率とは、より多くの消費ので、ランダムな方法が適用されません)
  • リザーブより多くのユーザーは、ユーザーが取得配列のインデックスの昇順を取得しているため、各要求は、ユーザーをバインドする必要はありません。2000人のユーザーを取得しようとする試みは、需要サイクルを満たすことができるようになります後。

Javaのスレッド安全性の問題リファレンスについて:アトミックとスレッドセーフの動作を簡単に見て、私は++本当に安全ではないスレッドセーフと組み合わせアトミック操作

テストスクリプト

デバッグ方法及び機能、約予約パフォーマンステストフレームワーク第三版は、コードリファレンスクラスがあります。

package com.okayqa.others.payyst

import com.fun.base.constaint.ThreadLimitTimesCount
import com.fun.frame.excute.Concurrent
import com.fun.frame.httpclient.FanLibrary
import com.fun.utils.ArgsUtil
import com.fun.utils.RString
import com.okayqa.common.RSAUtilLJT
import com.okayqa.common.Users
import com.alibaba.fastjson.JSONObject
import org.apache.http.client.methods.HttpPost
import org.slf4j.Logger

import java.util.concurrent.atomic.AtomicInteger

class T extends FanLibrary {

    static Logger logger = getLogger(T.class)


    static AtomicInteger i = new AtomicInteger(111000);

    public static void main(String[] args) {
        def argsUtil = new ArgsUtil(args)
        def thread = argsUtil.getIntOrdefault(0, 1)
        def times = argsUtil.getIntOrdefault(1, 100)
        def reqs = []

        thread.times {
//            def mark = new HeaderMark("requestid")
            reqs << new Thr(times)
        }

        new Concurrent(reqs, "会员支付和续费接口").start()
        testOver()
    }

    static class Thr extends ThreadLimitTimesCount {

        static Logger logger = getLogger(Thr.class)

        public Thr(int times) {
            super(null, times, null);
        }

        @Override
        protected void doing() throws Exception {
            String url = com.okayqa.studentapd.base.OkayBase.HOST+"/api/member/createOrRenewMember"
            Map<String, String> p = new HashMap<>();
            p.put("days", "1");
            p.put("memberId", "208");
            p.put("orderNo", "F" + RString.getString(4) + i.getAndAdd(1));
            p.put("orderPaySystemId", "85123213");
            p.put("orderPayTime", "2020-02-09 10:00:00");
            p.put("payMoney", "30");
            p.put("recordSources", "3");
            p.put("renewal", "false");
            def user = Users.getStuUser(i.getAndAdd(1) % 2000)
//            output(user)
            p.put("systemId", user);
            String sign = RSAUtilLJT.sign(p, RSAUtilLJT.getPrivateKey(RSAUtilLJT.RSA_PRIVATE_KEY));
            p.put("sign", sign);
            HttpPost post = getHttpPost(url, JSONObject.fromObject(p).toString());
            def s = "F" + getNanoMark()
            post.addHeader(getHeader("requestid", s));

            def simlple = FanLibrary.excuteSimlple(post)
            if (!simlple.contains("success")) {
                logger.warn(s + OR + user + simlple.toString())
                fail()
            }
        }

    }
}
复制代码

そこピット、あるAtomicIntegerクラスは、スレッドセーフなクラスが、すべてではない方法は、例えば、安全でありget()、Iは、2つの使用しているgetAndAdd()方法を、もののユーザのループスルー変速時間の量の増加が、精度又は使用するために最も重要な、実験的検証後の2000ユーザーは十分。

  • 厳粛に宣言:最初の公開番号「FunTester」に登場した記事、(テンセントクラウドを除く)第三者再生を禁止し、公開します。

技術関連記事

非技術的な選択された記事

おすすめ

転載: juejin.im/post/5e438e9c518825496e784222