使用Redisのは、UAのプールを達成します

前提

最近、ビジネス開発、移転やゲームで忙しく、プラス生ずる時から躊躇し、混乱の舞台をヒット、いくつかの時間のために学業を放棄しました。研究の次の段階をピックアップして寒さは、始まりました。抗登るに基づいて要求のシミュレーションを含むデータ検索プロジェクトのいくつかに先立ち暴露は、ランダムを使用する必要がありますUser Agent使用はので、Redis非常に単純な実装UAプールを。

背景

最近需要、要求論理シミュレーションは、各リクエストのリクエストヘッダに必要とされるUser Agent以下の点を満足します。

  • すべての買収はUser Agentランダムです。
  • すべての買収User Agent(ショート)を繰り返すことはできません。
  • すべての取得User Agent情報必見の主流とオペレーティングシステムは(することができUinuxWindowsIOSなど、とAndroid)。

ここから3ポイントであるUAデータの解決ソースは、実際には、我々は特定の実装に焦点を当てるべきです。次のように単純な分析は、プロセスは次のとおりです。

設計ではUA、プール際にそのデータ構造と循環キューは非常に似ています。

異なる色を想定し、上記の図は、UA完全に異なっているUA、それらは循環キューでシャッフルアルゴリズムプットによって分割されている、という事実は、一つは取り出すことUAの後だけにカーソルを置くcursorセルに前方または後方(あるいはカーソルキュー内の任意の要素)に設定。最終的な実現はこれです:ミドルウェア(ちょうどキューではなく、メッセージキュー)を介して分散キューを実現する必要があります。

特定の実装

ミドルウェアの種類を格納するための分散データベースの必要性が準備されていることは間違いありませんUA、あなたが感じる第一印象はRedis、より適切であろうが。次は選択する必要がありRedis、データの種類、主な考慮事項いくつかの側面を:

  • これは、キューのプロパティを含んでいます。
  • ランダムアクセスをサポートする最高。
  • チーム内の要素、チームとランダムアクセス時の複雑さを取得するには、すべての後に、低いUAトラフィックインターフェイスが比較的大きくなります。

これらの側面サポートRedisのデータ型ですListが、注意List自体が重い、重い作業は、コード・ロジックで実装されるように行くことができません。その後、クライアントが取得想像しUA、次のようなプロセスは次のとおりです。

以前の分析を組み合わせて、符号化プロセスは、以下のステップがあります。

  1. インポートする準備ができてUAデータがデータソースから読み取ることができ、あなたはまた、ファイルを直接読み込むことができます。
  2. インポートする必要のため、UA多くのではない一般的な意志でデータの収集を、場合、ランダムに散在のこの最初のデータセットを考えるJava開発直接使用することができるCollections#shuffle()アルゴリズムをシャッフルもちろん、このアルゴリズムは、ランダムデータ自体を分散することができ、このステップは、いくつかのためでありますアナログ側は厳密に検討するUAシーン正当性が必要です
  3. インポートUAにデータRedisリスト。
  4. 書く分散循環キューを達成するために、スクリプトを。RPOP + LPUSHLua

例のコーディングとテスト

導入RedisアドバンストクライアントがLettuce依存しています:

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>

書くスクリプトを、暫定的に呼ばれるスクリプト名に、ディレクトリ:RPOP + LPUSHLuaLuaL_RPOP_LPUSH.luaresources/scripts/lua

local key = KEYS[1]
local value = redis.call('RPOP', key)
redis.call('LPUSH', key, value)
return value

このスクリプトは非常にシンプルですが、循環キューの機能を実現しています。残りのテストコード次のように

public class UaPoolTest {

    private static RedisCommands<String, String> COMMANDS;

    private static AtomicReference<String> LUA_SHA = new AtomicReference<>();
    private static final String KEY = "UA_POOL";

    @BeforeClass
    public static void beforeClass() throws Exception {
        // 初始化Redis客户端
        RedisURI uri = RedisURI.builder().withHost("localhost").withPort(6379).build();
        RedisClient redisClient = RedisClient.create(uri);
        StatefulRedisConnection<String, String> connect = redisClient.connect();
        COMMANDS = connect.sync();
        // 模拟构建UA池的原始数据,假设有10个UA,分别是UA-0 ... UA-9
        List<String> uaList = Lists.newArrayList();
        IntStream.range(0, 10).forEach(e -> uaList.add(String.format("UA-%d", e)));
        // 洗牌
        Collections.shuffle(uaList);
        // 加载Lua脚本
        ClassPathResource resource = new ClassPathResource("/scripts/lua/L_RPOP_LPUSH.lua");
        String content = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
        String sha = COMMANDS.scriptLoad(content);
        LUA_SHA.compareAndSet(null, sha);
        // Redis队列中写入UA数据,数据量多的时候可以考虑分批写入防止长时间阻塞Redis服务
        COMMANDS.lpush(KEY, uaList.toArray(new String[0]));
    }

    @AfterClass
    public static void afterClass() throws Exception {
        COMMANDS.del(KEY);
    }

    @Test
    public void testUaPool() {
        IntStream.range(1, 21).forEach(e -> {
            String result = COMMANDS.evalsha(LUA_SHA.get(), ScriptOutputType.VALUE, KEY);
            System.out.println(String.format("第%d次获取到的UA是:%s", e, result));
        });
    }
}

次のような結果の実行は、次のとおりです。

第1次获取到的UA是:UA-0
第2次获取到的UA是:UA-8
第3次获取到的UA是:UA-2
第4次获取到的UA是:UA-4
第5次获取到的UA是:UA-7
第6次获取到的UA是:UA-5
第7次获取到的UA是:UA-1
第8次获取到的UA是:UA-3
第9次获取到的UA是:UA-6
第10次获取到的UA是:UA-9
第11次获取到的UA是:UA-0
第12次获取到的UA是:UA-8
第13次获取到的UA是:UA-2
第14次获取到的UA是:UA-4
第15次获取到的UA是:UA-7
第16次获取到的UA是:UA-5
第17次获取到的UA是:UA-1
第18次获取到的UA是:UA-3
第19次获取到的UA是:UA-6
第20次获取到的UA是:UA-9

効果の可視違いは、アルゴリズム、分散に関するデータをシャッフルされていません。

概要

実際には、UAプールの設計難易度は大きくありません、我々はいくつかの点に注意を払う必要があります。

  • システムのバージョン、一般的に主流のモバイルデバイスやデスクトップがあまりありませんが、ソースので、UAデータがあまりありませんが、最も簡単な実装では、ファイルストレージを使用することができ、直接書き込み、読み取り一度Redisインチ
  • ランダム分割する必要性に注意UA機器システムの同じタイプのを避けるためにデータをUAシミュレート特定のリスク管理ルール要求時間をトリガーする避けるために、あまりにも密なデータを。
  • あなたは知っておく必要がありLua、すべての後に、構文Redis原子は、コマンドなければならないLuaスクリプトを。

(本明細書で終わり、C-2-D EA-20191114)

説明リンク

  • Githubのページ:のhttp://throwable.club/2019/11/14/redis-in-action-ua-pool/
  • ページをコーディングします。http://throwable.coding.me/2019/11/14/redis-in-action-ua-pool/

おすすめ

転載: www.cnblogs.com/throwable/p/11955162.html