Ham API ile k6 yük testlerinde CAPTCHA nasıl çözülür

Bir k6 captcha adımı, ham HTTP API üzerinden geçmek zorundadır; çünkü k6 Node değildir ve SDK içine kurulamaz. Kolay kısım budur: iki çağrı, gönderme ve yoklama. Testinizin bir işe yarayıp yaramadığını belirleyen kısım ise çözümün nerede çalıştığıdır. Onu default fonksiyonuna koyarsanız her sanal kullanıcı her iterasyonda çözer; bu da uygulamanız yerine çözücüyü ölçer ve bunu hiç kaldırmak için tasarlanmamış bir makineyi boğar. Onu setup aşamasına koyarsanız temiz sayılar elde edersiniz, ama bilmeniz gereken dürüst bir sınırla birlikte.
Neye ihtiyacınız var
- k6, herhangi bir güncel sürüm. Kurulacak paket yoktur, çünkü içine kurulacak bir şey yoktur.
- Test ettiğiniz korumalı uç noktanın sitekey'i ve sayfa URL'si.
- k6, çözücüyle aynı makinede çalışıyorsa CapSkip Local modda, bir yük üreticide veya CI'da çalışıyorsa Server modda çalışır. Ayrıntılı bilgi için bkz: bağlantı ayarları.
Çözmenin doğru tercih olduğu durumlar
Herhangi bir kod yazmadan önce bunu açıkça söyleyelim. Test edilen site sizinse, genellikle daha iyi hamle yük üreticinin doğrulamayı geçmesine izin vermektir: adresini allowlist'e ekleyin veya staging ortamınızın tanıdığı bir header gönderin ve widget'ı tamamen atlayın. Siz uygulamanızı ölçmeye çalışıyorsunuz ve çözülen her doğrulama başkasına ait bir gecikme ekler.
Çözmek iki durumda doğru tercihtir. Vurmanız gereken uç nokta korumalıdır ve o korumayı kontrol etmezsiniz, ya da korumalı yolun kendisi test edilen şeydir ve onu atlamak gerçek trafiğin hiç kullanmadığı bir rotayı test etmek olur. İkisi de gerçektir ve bu yazının geri kalanı tam olarak bunun içindir.
SDK burada neden işe yaramaz
k6 betikleri JavaScript'e benzer ama Node üzerinde çalışmaz. require uygulaması k6’nın kendisine aittir; dokümantasyon ise bu sınır konusunda oldukça açıktır: yerleşik k6 modüllerini, yerel dosyaları ve uzak betikleri yükler, ancak Node modül çözümleme algoritmasını desteklemez. npm yok, node_modules yok, fs yok ve crypto yok. Dolayısıyla CapSkip paketi import edilemez, uzanabileceğiniz başka hiçbir şey de edilemez.
Bu, kulağa geldiğinden daha az maliyetlidir. API, 2captcha uyumludur ve iki uç noktaya sahiptir; bu yüzden k6’nın kendi http modülü bunu yaklaşık on beş satırda karşılar. Yük üreticiniz sonuçta sıradan bir Node süreci çıkarsa, Node.js CAPTCHA çözücü sayfası SDK'sı olan istemciyi kapsar.
Adım 1: çözümü sade bir fonksiyon olarak yazın
in.php'ye gönderin, bir ID alın, ardından yanıt gelene kadar res.php'yi yoklayın. JSON isteyin ki metinleri pipe karakterinden bölmek yerine alanları okuyasınız.
// No install step. Both modules are built into k6.
import http from 'k6/http';
import { sleep } from 'k6';
const SOLVER = 'http://127.0.0.1:8080';
const KEY = 'YOUR_API_KEY';
function solve(sitekey, pageurl) {
const submitted = http.post(SOLVER + '/in.php', {
key: KEY,
method: 'userrecaptcha',
googlekey: sitekey,
pageurl: pageurl,
json: '1',
});
return poll(submitted.json('request')); // the captcha ID
}Parametre adına dikkat edin. reCAPTCHA googlekey ister, Turnstile ise turnstile metoduyla sitekey ister. Yanlışını göndermek genellikle bir ERROR_GOOGLEKEY yanıtının nedenidir.
function poll(id) {
const url = SOLVER + '/res.php?key=' + KEY +
'&action=get&json=1&id=' + id;
// Roughly three minutes of headroom at five seconds a try.
for (let i = 0; i < 36; i++) {
sleep(5);
const res = http.get(url);
if (res.json('status') === 1) {
return res.json('request'); // the token
}
}
throw new Error('solve did not finish in time');
}Bekleyen bir yanıt, sıfır durumuyla CAPCHA_NOT_READY olarak döner; bu yüzden döngü, herhangi bir yanıtı tamamlanmış saymak yerine status alanını kontrol eder. Sonuçlar yalnızca bir kez okunabilir; dolayısıyla token'ı aldığınızda saklayın.
Adım 2: setup aşamasında çözün
k6, setup'ı herhangi bir sanal kullanıcı başlamadan önce bir kez çalıştırır ve döndürdüğü her şeyi default fonksiyonuna geçirir. Bunun tam olarak ihtiyaç duyduğu şekil budur. Orada çözün, token'ları dağıtın ve hiçbir VU kendi iterasyonu içinde bir çözüm için bedel ödemesin.
const PAGE = 'https://example.com/page-with-recaptcha';
const SITEKEY = 'YOUR_SITEKEY';
export const options = {
vus: 10,
duration: '90s',
setupTimeout: '5m', // the 60s default expires mid solve
};
export function setup() {
// One token per VU. They are single use.
const tokens = [];
for (let i = 0; i < 10; i++) {
tokens.push(solve(SITEKEY, PAGE));
}
return { tokens };
}setupTimeout satırı göründüğünden daha önemlidir. k6, setup'a varsayılan olarak 60 saniye verir ve tek bir reCAPTCHA çözümü bunun büyük kısmını tek başına kullanabilir. Bunlardan on tanesi sığmaz, aşama öldürülür ve hata, bakacağınızı düşüneceğiniz herhangi bir şey yerine setup'ı suçlar.
Bunun üzerine inşa etmeden önce bilmeye değer sınır
Token'lar tek kullanımlıktır ve yaklaşık iki dakika geçerli kalır. Her iki yarısı da burada ısırır. Tek kullanımlık olması, korunan istekler kadar çok token'a ihtiyacınız olduğu anlamına gelir; dolayısıyla korumalı uç noktayı bin kez vuran bir test bin çözüm gerektirir ve artık bir yük testine benzemez. İki dakika ise, setup'ta çözdüğünüz token'ların ilk VU başladığında zaten yaşlanmakta olduğu anlamına gelir; dolayısıyla uzun bir soak testi, çalışmasının çoğunu süresi dolmuş olanları göndererek geçirir.
Yani bu desen, korumalı bir uç noktaya karşı kısa süreli bir yük patlamasına uyar, otuz dakikalık sürdürülebilir bir yüke değil. Bir reCAPTCHA token'ının ne kadar süre geçerli kaldığına dair yazı zamanlamaları içerir. Widget üzerinden sürdürülebilir yük gerekiyorsa, daha önceki allowlist yöntemi bunu elde etmenin tek dürüst yoludur.
Adım 3: çözücüyü metriklerinizin dışında tutun
k6’nın http modülüyle gönderdiğiniz her şey, çözücü çağrıları dahil, http_req_duration'a düşer. Sessizce on beş saniyelik bir yoklamayı içeren bir p95, üzerine hareket edebileceğiniz bir sayı değildir. Önemsediğiniz istekleri etiketleyin ve eşikleri o etikete yöneltin.
export const options = {
vus: 10,
duration: '90s',
setupTimeout: '5m',
thresholds: {
// Measure the app, not the solve.
'http_req_duration{target:app}': ['p(95)<500'],
},
};
export default function (data) {
const token = data.tokens[__VU - 1];
http.post(PAGE, { 'g-recaptcha-response': token }, {
tags: { target: 'app' },
});
}__VU değişkeni sanal kullanıcıları birden başlayarak numaralandırır; dolayısıyla token dizisini onunla indekslemek her VU'ya kendi token'ını verir. Etiketleme, çözümü k6'nın göremeyeceği bir yere taşımaktan daha temiz bir çözümdür; çünkü ne kadar sürdüklerini bilmek istediğinizde çözüm istekleri hâlâ çıktıda görünür.
Çözücü nerede durmalı
Yük üreticileri nadiren masaüstünüzdür. k6, CI'da, özel bir makinede veya yönetilen bir serviste çalışır; bunların hiçbirinde loopback adresi çözücünüzün bulunduğu makine değildir.
| Mod | Dinlediği adres | Ne zaman kullanılır |
|---|---|---|
| Yerel | 127.0.0.1, yalnızca o cihaz | k6 ve çözücü tek bir makinede |
| Sunucu | Ağ adresiniz veya genel IP'niz | CI, bir yük üretici filosu, yönetilen bir runner |
Server modu, ikinci satırdaki her şeyin cevabıdır: uygulamadaki dinleme adresini değiştirin, betiği o host'a yönlendirin ve her üretici tek bir çözücüyü paylaşsın. Çağıranlar ağınızın dışındaysa sabit bir genel IP önerilir. Hâlâ sizin donanımınızdır ve hâlâ ölçüm bazlı ücretlendirilmez; dolayısıyla bu yalnızca çözücünün çalıştığı yeri değiştirir, başka bir şeyi değil. CapSkip bir Windows uygulamasıdır; yani bu, üreticilerin çağırdığı tek bir Windows makinesidir. Pratik bir not: onu test ettiğiniz aynı yük dengeleyicinin arkasına koymayın, yoksa kendi darboğazınızı iki kez ölçmüş olursunuz.
Yaygın hatalar
| Gördüğünüz | Neden | Düzeltme |
|---|---|---|
| ‘capskip’ modülü bulunamıyor | k6 npm paketlerini çözümlemez | Bunun yerine API'yi k6’nın http modülüyle çağırın |
| setup() çalıştırması zaman aşımına uğradı | Çözümler 60 saniyelik varsayılandan daha uzun sürdü | Her çözümü kapsayacak şekilde setupTimeout'u yükseltin |
| p95 devasa ama hiçbir şey yavaş değil | Çözücü çağrıları http_req_duration'a dahil edildi | Uygulama isteklerini etiketleyin ve eşiği filtreleyin |
| Sonraki iterasyonlar reddediliyor, ilkler sorunsuz | Token'lar ömürlerinin ötesinde yaşlandı | Çalıştırmayı kısaltın ya da daha az, daha geç çözün |
| Her VU aynı reddi alıyor | VU'lar arasında yeniden kullanılan tek bir token | VU başına bir tane çözün ve __VU ile indeksleyin |
Kodların tam listesi ve her metodun aldığı parametreler şurada yer alır: CapSkip API dokümantasyonu.
FAQ
CapSkip SDK'sını k6'ya kurabilir miyim?
Hayır. k6, yerleşik modülleri, yerel dosyaları ve uzak betikleri işleyen kendi modül yükleyicisini uygular ve kasıtlı olarak Node’un çözümleme algoritmasını izlemez; dolayısıyla npm paketleri devre dışıdır. API 2captcha uyumludur; bu yüzden iki uç nokta, SDK'nın sizin için yapacağı her şeyi k6’nın kendi http modülünün yaklaşık on beş satırında karşılar.
Bunun yerine default fonksiyonunun içinde mi çözmeliyim?
Yalnızca test ettiğiniz şey çözümün kendisiyse. default fonksiyonu VU başına iterasyon başına bir kez çalışır; dolayısıyla iki dakika boyunca yirmi VU, yüzlerce çözüm demektir ve gecikme sayılarınız bir yoklama ölçümüne dönüşür. setup'ta çözün, token'ları dağıtın ve iterasyonu gerçekten önemsediğiniz isteğe ayırın.
k6'm yönetilen bir serviste çalışıyor. Çözücüye ulaşabilir mi?
Evet, Server modunda. Çözücü, loopback adresi yerine bir ağ adresinde dinler ve üreticiler onu diğer herhangi bir dahili servis gibi API üzerinden çağırır. Runner'lar ağınızın dışındaysa sabit bir genel IP bunu istikrarlı hale getirir. Anahtar doğrulamasını açın ve her ortama kendi anahtarını verin; böylece biri diğerlerine dokunmadan iptal edilebilir.
Bir widget üzerinden bir saat boyunca nasıl yük testi yaparım?
Yapmazsınız, en azından gerçek token'lar üzerinden değil. Tek kullanımlık olma artı iki dakikalık ömür, bir saatlik sürdürülebilir yükün kesintisiz bir çözüm akışına ihtiyaç duyduğu anlamına gelir; bu noktada test edilen sistem çözücünün kendisi olur. Kendi uygulamanız üzerinde uzun bir çalıştırma için, yük üreticisini doğrulamadan muaf tutun ve arkasındaki yolu test edin.
Kısa özet
k6’nın http modülünü in.php ve res.php'ye karşı kullanın, setupTimeout'u yükselterek setup aşamasında çözün, eşiklerin anlamlı kalması için uygulama isteklerinizi etiketleyin ve token'ların hâlâ canlı olacağı kadar kısa bir çalıştırma süresi tutun. Bunun crawl tarafı için bkz: web scraping için CAPTCHA çözücü sayfası. Yük testi, çözüm başına fiyatlandırmanın en hızlı saçmalaştığı yerdir, çünkü tek bir patlama, hiçbir iş değeri üretmeyen yüzlerce token gerektirebilir. Fiyatlandırma modeli işte tam farkı yaratan şeydir: captcha atlatma çalışması, zaten sahip olduğunuz donanımda, bir testi de kırk testi de çalıştırsanız aynı maliyete sahiptir.
