Sayfa: 1
Merhaba arkadaşlar,
Bir projemizde yoğun olarak kuyruk işlemi kullanmaktayız. Bir süre sonra hafıza yetersizliğinde dolayı kuyruğu restart etmemiz gerekiyor. Şu anda 30 dk da bir restart ettiğimizde sorun olmuyor ancak ilerleyen zamanlarda başımızı ağrıtacak gibi duruyor.
Dökümantasyonda aşağıdaki belirtilen durumu nasıl kullanacağımız konusunda yardıma ihtiyacımız var.
Resource Considerations
Daemon queue workers do not "reboot" the framework before processing each job. Therefore, you should free any heavy resources after each job completes. For example, if you are doing image manipulation with the GD library, you should free the memory with imagedestroy when you are done.
Kuyrukta yoğun olarak kullanılan örnek Class aşağıdadır.
class BankaWsdl implements IBankAccountChecker
{
protected $url;
protected $AllowTypes;
protected $bank_account;
protected $options;
public function __construct(BankAccount $bank_account)
{
$this->AllowTypes = ['1011', '3011', '1011', '7721']; // İzin verilen işlem Türleri
$this->bank_account = $bank_account;
$this->url = 'wsdl_url';
$this->options = array(
'login' => $this->bank_account->api_username,
'password' => $this->bank_account->api_password,
'keep_alive' => false,
'connection_timeout' => 25,
'cache_wsdl' => WSDL_CACHE_MEMORY,
'ssl_method' => SOAP_SSL_METHOD_TLS,
'stream_context' => stream_context_create(
[
'ssl' => [
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]
]
)
);
}
public function getTransactions(Carbon $start_date, Carbon $finish_date)
{
try {
$transactions = collect();
$data = [
'baslangicTarihi' => $start_date->startOfDay()->format('YmdHis000000'),
'bitisTarihi' => $finish_date->endOfDay()->format('YmdHis000000')
];
$client = new SoapClient($this->url, $this->options);
$result = $client->GetExtreWithParams($data);
$result = simplexml_load_string($result->GetExtreWithParamsResult->any);
// return (array)$result;
$this->bank_account->update(['balance' => str_replace(',', '.', @$result->Hesap->Bakiye)]);
$say = count(@$result->Hesap->Detay);
if ($say < 1) {
return ['success' => false, 'message' => 'Herhangi Bir Hareket Bulunmadı'];
} elseif ($say == 1) {
$detaylar = [$result->Hesap->Detay];
} else {
$detaylar = $result->Hesap->Detay;
}
foreach ($detaylar as $detay) {
if ((string)$detay->TutarBorcAlacak == "+") {
$old = ['-',':',' '];
$new = [' ',' ',' '];
$aciklama = str_replace($old,$new,(string)$detay->Aciklama);
$key = (string)$detay->FisNo . '' . (string)$detay->TimeStamp . '' . str_replace(',', '', (string)$detay->SonBakiye);
$data = [
'key' => $key,
'amount' => str_replace(',', '.', (string)$detay->Tutar),
'moment' => (string)$detay->TimeStamp,
'description' => mb_strtoupper($aciklama),
'transaction_type' => (string)$detay->FonksiyonKodu,
'code' => Hash::make($this->bank_account->id . ':' . $key . ':' . str_replace(',', '.', (string)$detay->Tutar))
];
$transactions->push($data);
}
}
// return 'OK';
if ($transactions->count() < 1) {
return ['success' => false, 'message' => 'Herhangi Bir Hareket Bulunmadı.'];
}
return ['success' => true, 'transactions' => $transactions];
} catch (\Exception $e) {
Log::debug($e);
return ['success' => false, 'message' => 'Bankadan Bilgiler alınamadı.'];
}finally {
unset($client);
}
}
}
__destruct() fonksiyonunda tüm değişkenleri unset etmek yararlı olabilir mi? Yada başka ne gibi bir çözüm aramalıyız. Teşekkürler.
Çevrimdışı
__destruct() fonksiyonunda tüm değişkenleri unset etmek yararlı olabilir mi?
Evet, duruma göre işe yarayabilir. PHP içerisindeki GC (garbage collector) genellikle bu işi sizin için yapıyor.
queue:work kullanıyorsanız;
Bu şekilde başlatılan kuyruk hızlıdır, az kaynak tüketir ama framework'ü bir kere başlattıktan sonra sıfırlamaz, biriktirme yapar. Kuyruktaki işler çok kaynak tüketiyorsa şimdi yaşadığınız sorunu yaşarsınız. Bir tane cron ile belli periyotlar ile queue:restart yapılarak boşlatma yapılabilir.
queue:listen ise;
Her iş için framewok'ü baştan başlatır. Kuyruktaki işlemler küçük ve az kaynak tüketiyorsa framework'ü sürekli baştan başlatmak gereksiz kaynak tüketimi olacaktır ama çok işlemci ve bellek kullanan işlemler için kullanmak yararlı olacaktır.
Bunun dışında SoapClient incelemem lazım. İşlemci ve bellek kullanımı ile ilgili bilgim yok. Etkisi var mı, yapılandırılabilir mi bakmak lazım.
Cache kullanabileceğiniz bir yer var mı göremedim ama paylaşmadığınız kodlarda varsa kullanabilirsiniz.
Çevrimdışı
__destruct() fonksiyonunda tüm değişkenleri unset etmek yararlı olabilir mi?
Evet, duruma göre işe yarayabilir. PHP içerisindeki GC (garbage collector) genellikle bu işi sizin için yapıyor.queue:work kullanıyorsanız;
Bu şekilde başlatılan kuyruk hızlıdır, az kaynak tüketir ama framework'ü bir kere başlattıktan sonra sıfırlamaz, biriktirme yapar. Kuyruktaki işler çok kaynak tüketiyorsa şimdi yaşadığınız sorunu yaşarsınız. Bir tane cron ile belli periyotlar ile queue:restart yapılarak boşlatma yapılabilir.queue:listen ise;
Her iş için framewok'ü baştan başlatır. Kuyruktaki işlemler küçük ve az kaynak tüketiyorsa framework'ü sürekli baştan başlatmak gereksiz kaynak tüketimi olacaktır ama çok işlemci ve bellek kullanan işlemler için kullanmak yararlı olacaktır.Bunun dışında SoapClient incelemem lazım. İşlemci ve bellek kullanımı ile ilgili bilgim yok. Etkisi var mı, yapılandırılabilir mi bakmak lazım.
Cache kullanabileceğiniz bir yer var mı göremedim ama paylaşmadığınız kodlarda varsa kullanabilirsiniz.
Hocam cevabınız için teşekkürler. Evet queue:work kullanıyorum. --memory değerini vererekte denedim ancak queue:restart etmeden yine sorunu yaşıyorum. Kodlar yukarıdaki gibi Cache kullanabileceğim biryer yok . queue:listen i denedim ancak gibi sunucu çökecek gibi hissediyorum. Kuyrukta günlük 100k işlem yapılıyor şu anda. 1 yıl içinde 500k yı göreceğini ön görüyoruz. Bunun mutlaka bir çözümü olmalı
Şu anda 10 dk da çalışan cronla restart ediyorum. ama dediğim gibi ilerde dk da bir restart ta işe yaramayacak galiba.
Çevrimdışı
Sunucu özellikleri nedir, ne kadar ram var bilmiyorum ama dediğiniz gibi iş ağırsa, sunucuyu yükseltemiyorsanız, günlük işlem o kadar yüksek ise ve artık bellek ile yapabileceğiniz bir şey kalmadıysa servisleri ayıracaksınız demektir.
Örneğin bu kuyruk işi ve oluşturduğu verinin tutulduğu veritabanı ayrı bir sunucuda olacak. Ana sunucu sadece API ile haberleşecek. Bu veriye otomatik ulaşmayıp sadece istek ile ulaşacaksınız.
Ayrıca bunu ayrı bir servis haline getirdiğinizde PHP/MySQL olmasına da gerek yok. İşe göre araç seçmeniz gerekir.
Çevrimdışı
Sunucu özellikleri nedir, ne kadar ram var bilmiyorum ama dediğiniz gibi iş ağırsa, sunucuyu yükseltemiyorsanız, günlük işlem o kadar yüksek ise ve artık bellek ile yapabileceğiniz bir şey kalmadıysa servisleri ayıracaksınız demektir.
Örneğin bu kuyruk işi ve oluşturduğu verinin tutulduğu veritabanı ayrı bir sunucuda olacak. Ana sunucu sadece API ile haberleşecek. Bu veriye otomatik ulaşmayıp sadece istek ile ulaşacaksınız.
Ayrıca bunu ayrı bir servis haline getirdiğinizde PHP/MySQL olmasına da gerek yok. İşe göre araç seçmeniz gerekir.
Hocam sunucumuzun şu aşamada yeterli olduğunu düşünüyorum. İlerleyen zamanlara dediğiniz gibi servisleri ayırmak planımızda var. Ancak Şu anda memory kullanımı max 3.00 GB gördüm, daha yukarısına çıkmıyor zaten. Muhtemelen conflarla alakalıdır bu durum. Aslında ben bu sorunu çözmede aşamalı bir şekilde ilermek istiyorum.
İlk Etapta kod tarafında yapabileceklerimi yapıp, ondan sonra nginx,php confları ile devam etmek istiyorum. Şu anda DB tarafında postgresql kullanıyorum. O sunucuda bundan daha iyi . Yakın zamanda rediside ayrı bir sunucuya alacağız.
Bu aşamada php, nginx conflarda özellikle şu ayarlamaları yapmalısın diyecebileceğiniz bir ayar varsa onlarıda deneyebilirim.
php pm ini dynamic ve ondemaond denedim pek birşey değişmedi
Desteğiniz için çok teşekkür ederim. İyi çalışmalar.
Son düzenleyen ferhatyesilmen (31.01.2019 22:03:00)
Çevrimdışı
Sayfa: 1