Просмотр сообщений
|
Страниц: [1] 2 3 ... 317
|
3
|
Главная категория / Модули NodenyPlus / Re: Модуль TurboSMS
|
: 30 Октября 2024, 20:20:53
|
Подивився, здається, в модулі не враховані "довги послуги". Дуже складно в модуль перенести весь доданий функціонал по послугам, щоб він все це враховував. Буде час я подивлюся, може зроблю
|
|
|
4
|
Главная категория / Модули NodenyPlus / Re: Liqpay с новым протоколом
|
: 13 Октября 2024, 17:17:05
|
Спробував з тестовим мерчем, але пише, що магазин заблокований. Можливо розчеплення не працює з тестовим мерчем. Зроби наступне: В файлі create.user.lpay.pl і такий фрагмент: my $form = url->new( -base => "$cfg::lpay_api_url/pay", public_key => $merchant_id, signature => $signature, server_url => $cfg::lpay_return_url, result_url => $result_url, amount => $amt, currency => $cfg::lpay_currency, order_id => $pay_id, description => $description, ); заміни його на: eval "use JSON;"; my $form = url->new( -base => "$cfg::lpay_api_url/pay", public_key => $merchant_id, signature => $signature, server_url => $cfg::lpay_return_url, result_url => $result_url, amount => $amt, currency => $cfg::lpay_currency, order_id => $pay_id, description => $description, type => $type, split_rules => to_json([ { "public_key"=> "публічний ключ мерчанта 1", "amount"=> int($amt/2), }, { "public_key"=> "публічний ключ мерчанта 2", "amount"=> $amt - int($amt/2), } ]) ); perl install.pl -x і спробуй оплатити. Платіж повинен бути розподілений між двома мерчами 50/50
|
|
|
5
|
Главная категория / Модули NodenyPlus / Re: Liqpay с новым протоколом
|
: 12 Октября 2024, 19:11:23
|
Давно не працював з Лікпей. Подивився на модуль, який я зробив у прошлому житті. Це якийсь стопіцотий варіант їхнього апі, не співпадає з тим що на сайті в доках. Можно спробувати додати параметр розщеплення в мій варіант, можливо і спрацює. Спробую якось. Якщо в них є демо-мерчант... хоча там жеж потрібні демо-мерчантИ, так що сумніваюсь, що вийде. Я можу сказати як прямо в файл вставити тестовий фрагмент коду, в який ви захардкодите ключи своїх мерчів. Якщо це спрацює, тоді на основі цього дороблю модуль
|
|
|
6
|
Главная категория / Модули NodenyPlus / Гугл карти версія 2
|
: 12 Октября 2024, 15:58:55
|
Нещодавно виявив, що гугл-карти в консоль кидають месадж, що метод створення маркерів (об'єкти які ви бачите на карті) застарілий і треба використовувати новий тип маркерів. Це поки не є проблемою і я думаю вони ще довго будуть підтримувати старий тип. Я вирішив не чекати коли підтримка буде припинена і переробив модуль. І щоб для вас був хоч якийсь профіт, додав фішку відображенні довжини кабелів (дивиться прікріплення). Є 2 режими: відстань від точки до точки і відстань кожного фрагменту від поворота до повороту. Відстань міряється по самій гугл карті, тобто буде міняться дінамічно коли ви будете щось міняти.
Оформив це як новий модуль. В архиві 2 папки: map і gmap - треба такі самі папки видалити (чи забекапити) в теці modules і записати на їх місце нові з архиву. Зверніть увагу, що в налаштуваннях тепер задається не урл гуглкарт з ключем, а тільки ключ. Просто візміть його з цього урла. Візьміть до інсталяції модуля)
Що до ціни. Я так зрозумів, що кому був потрібен модуль карт, той вже його давно купив, тому я прийняв, що цей новий модуль буде фактично апгрейдом, тому виставив на нього низьку ціну
p.s. ще я зробив модуль на двигуні leaflet. Поки я не виявив переваг, здається круги він малює швидше... якщо цікаво - виставлю на продаж. А може в ньому є якісь фічі, які можно додати?
|
|
|
7
|
Главная категория / Ревизии / rev 699. Фікс примусового завершення заморожених послуг
|
: 28 Июля 2024, 11:17:39
|
У посуги є параметр "Не активувати послугу поки не стане достатньо коштів" - це один з варіантів (їх декілько) заморозки послуг. Також у модуля ядра services є параметр "Якщо послуга не може завершитися більше доби, наприклад, через проблеми API провайдера ТВ послуг, запускається процедура примусового завершення". Цей параметр захищає від ситуації, коли послуга через якісь проблеми не може завершитися і в цьому випадку вона б залишалася б підключеною вічно, поки це хтось не помітив. Був баг, коли заморожена послуга завершалася через добу через цей механізм. А вона може вісити вічно, бо ні на що не впливає, просто чекає грошей. Пофіксив
|
|
|
9
|
Главная категория / Модули NodenyPlus / ipv6 розробка
|
: 26 Июня 2024, 20:08:20
|
Рано чи пізно всі там будемо, тому треба думати про ipv6. Нажаль я не маю мережі і тому я не впроважував цю фічу бо я завжди намагаюсь все перевіряти. Я можу робити фічи віддаленно, але ця фіча доволі серьйозна, а всі з ким я контактував (ну такий уж я) не переконали мене робити на їх мережах. В цій темі я хочу знайти правильний напрямок розвитку, таку реалізацію, щоб було як можна більше плюсів і як можна меньше мінусів. Поки я почну з міркувань) Я хочу зробити дуже нескладну реалізацію. Принаймні на початку. Можна сказати зараз це моя головна ціль - зробити саме нескладно. Тому що я бачу, що ipv6 це як раз спрощення. Дивно, але це так. Чому я це стверджую? ip v4 мають обмежану кількість адрес, тому нам постійно треба щось робити щоб обходити це обмеження. Один з варіантів - це пул ip адрес. В цьому і основна проблема - дедлокі та постійні затупи коли нам треба вибрати вільну адресу. В ip v6 по ідеї не повино цього бути. Що таке видача ip адреси? Це функція, яка отримує на вхід id абонента, а на виході видає його ip. Коли в ip v6 адрес настільки багато, то ми можемо вираховувати ip по формулі без всяких пулів. Давайте приклад в ip версії 4 (чотири) я покажу як це могло бути: user id = 10 ip = 10.0.0.10 user id = 25 ip = 10.0.0.25 user id = 54 ip = 10.0.0.54 user id = 119 ip = 10.0.1.19 Звичайно в ipv4 це не може працювати, бо якщо ми видалемо user-а з id = 25, то вільна адреса 10.0.0.25 нікому ніколи не буде видана. Тому придумали всякі прив'язки ip, пули і т.д. В ipv6 адрес настільки багато, що ці дирки можна ігнорувати. Більше! Я знаю, що є мережі, які не можуть ігнорувати ці дирки, тому що в них є дуже великі підмережі для великих клієнтів. Але навіть в цьому випадку у мене є простий алгоритм без дирок! Я це назвав "стратегією". Зараз приведу реалізацію, де використовується стратегія 0 (супер примитивна, супер швидка, но з "дирками") і стратегія 1 (трохи повільніша, але без дирок). Створив таблицю: select * from ipv6_nets; +----+-------------+------+----------+ | id | net | mask | strategy | +----+-------------+------+----------+ | 1 | FFFF:BBBB:: | 56 | 0 | | 2 | FFFF:CCCC:: | 48 | 1 | +----+-------------+------+----------+ якщо у клієнта в допданих буде прописано "видавати ip /56", то ми будемо видавати ip з мережи FFFF:BBBB::. При цьому використовувати стратегію 0. Наприклад, у нас 4 абона, id=2 ipv6_mask=56 id=3 ipv6_mask=56 id=4 ipv6_mask=48 id=5 ipv6_mask=48 забігаючи вперед покажу результат видачі ip: MySQL [nodeny]> select ipv6_by_uid(2); +------------------------+ | ipv6_by_uid(2) | +------------------------+ | ffff:bbbb:0:0:200::/56 | +------------------------+
MySQL [nodeny]> select ipv6_by_uid(3); +------------------------+ | ipv6_by_uid(3) | +------------------------+ | ffff:bbbb:0:0:300::/56 | +------------------------+
MySQL [nodeny]> select ipv6_by_uid(4); +----------------------+ | ipv6_by_uid(4) | +----------------------+ | ffff:cccc:0:0:1::/48 | +----------------------+
MySQL [nodeny]> select ipv6_by_uid(5); +----------------------+ | ipv6_by_uid(5) | +----------------------+ | ffff:cccc:0:0:2::/48 | +----------------------+
Тобто видно, що перші 2 адреси отримані по стратегії 0 - тобто id юзера просто вписується в ipv6 мережу. Я знаю деякі так і роблять. Id у юзера постійний, він буде постійно отримувати одну й ту саму адресу і ніколи ні з ким не перетинеться. Інші 2 адреси отримані по стратегії 1 - грубо кажучи, в момент розрахунку ip, вони нумеруються по-порядку з одиниці і цей номер йде в формулу. Наважливо наскільки великий id - він по ітогу буде маленьким (в залежності від загальної кількості абонетів в цієй стратегії). В одній мережі можна використовувати і одну стратегію і обидві. Тепер сама функція видачі ip: DROP FUNCTION IF EXISTS `ipv6_by_uid`; DELIMITER $$ CREATE FUNCTION ipv6_by_uid(user_id INT) RETURNS VARCHAR(32) DETERMINISTIC BEGIN DECLARE ipv6_net VARCHAR(32); DECLARE ipv6_mask INT; DECLARE ipv6_strategy TINYINT; DECLARE ipv6_num INT; SELECT net, mask, strategy INTO ipv6_net, ipv6_mask, ipv6_strategy FROM ipv6_nets WHERE mask = (SELECT _ipv6_mask FROM data0 WHERE uid=user_id);
SELECT user_id INTO ipv6_num; IF( ipv6_strategy = 1 ) THEN SELECT row_num INTO ipv6_num FROM ( SELECT uid, ROW_NUMBER() OVER(ORDER BY id) AS row_num FROM data0 WHERE _ipv6_mask=48 ) a WHERE uid=user_id; END IF; RETURN CONCAT(INET6_NTOA( INET6_ATON(ipv6_net) | ( INET6_ATON(CONCAT('::', HEX(MOD(ipv6_num, 65536)))) | (INET6_ATON(CONCAT('::', HEX(ROUND(ipv6_num / 65536)))) << 16) ) << ipv6_mask ), '/', ipv6_mask); END$$ DELIMITER ;
Вона реально дуже проста. Її можна ускладнити коли буде декілько мереж з однією маскою, но то вже інша задача. Чому все, що я написав, здається мені дуже простим? Тому що в білінгу не використовується ніяких пулів, ніяких прив'язок і т.д. Все що додається: 1) інтерфейс редагування ipv6 мереж 2) вивід ip адреси у абона 3) відредагувати ваши радіуси, ви же знаєте які там атрібути видавать залізякам Тобто можна запустити ipv6 для частини мережі, білінг і не помітить цього, ну тобто всі ipv4 процеси будть йти як і йшли до цього.
|
|
|
10
|
Главная категория / Nodeny Plus / Партіціювання даних в mysql
|
: 25 Июня 2024, 15:28:22
|
Створив гілку, але скоріше тільки для себе - щоб не забути які я робив дослідження. Ну якщо комусь є щось сказати, можете висловлюватись) Чим більше даних в базі даних, тім повільніше вона працює, це очевидно. Але в більшості випадків потрібні актуальні дані - ну, наприклад, платежи тільки за останній період. По дефолту при переході в розділ "платежі" там як раз і показуються платежі за останні декілька місяців. Для таких ситуацій в базах даних використовують фішку "партіціювання" - це коли дані однієї таблиці розділяються не декілька, умовно кажуючи таблиць. Наприклад, можна розділити по даті: за 2023рік в такий таблиці, за 2024й в іншій таблиці і так далі. Насправді для нас це виглядає як одна таблиця, а всю работу під капотом виконує субд. Що нам дає це: дікілька таблиць меньше ніж одна. Тому і запис і вибірка будуть швидше. Це і є основна ціль. Виникає питання: а як вибирати інформацію з великого діапазону, коли частина буде в одній, а частина в нішій "таблиці" (цях)? Величезний плюс в тому, що це робить сама СУБД! Вона знає коли звернутися до однієї таблиці, а коли до декількох. Все. Далі піде технічна інфа, скоріше за все тільки для мене) Я провів дослідження: * як зробити партіціювання * буде воно робити з реплікацією мастер-слейв Підняв 2 докера з mysql-8 і налаштував реплікацію. Щось додаю на мастері - і це з'являється на слейві. Ура мені і докеркомпоузу. Намагаюсь зробити партіціювання по полю time: ALTER TABLE pays PARTITION BY RANGE (time) ( PARTITION p2023 VALUES LESS THAN (UNIX_TIMESTAMP('2024-01-01')), PARTITION p2024 VALUES LESS THAN (UNIX_TIMESTAMP('2025-01-01')), PARTITION pmax VALUES LESS THAN MAXVALUE ); Ідея така: дані до 24 року зберігаю в партиції p2023, до 25го - в p2024, інші в pmax. Але це не працює: ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function (prefixed columns are not considered
На цьому можна було закінчити. Короче, у мускула (чи скрізь так) обмеженне партіціювання - неможна розділяти на часті, якщо поле, по якому йде розділення не входить в прімарі кі. Я не знаю чому, може логіка в цьому є. Але мені потрібне вирішення проблеми. Ладно, я використав більш простий варіант - розділяти по id. Нам потрібно буде просто вибрати який максимальний id в якому році: ALTER TABLE pays PARTITION BY RANGE (id) ( PARTITION p2023 VALUES LESS THAN (3), PARTITION p2024 VALUES LESS THAN (8), PARTITION pmax VALUES LESS THAN MAXVALUE ); 3 і 8 маленьки числа бо це все тестово. SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'pays'; показує що робить: +----------------+------------+ | PARTITION_NAME | TABLE_ROWS | +----------------+------------+ | p2023 | 2 | | p2024 | 3 | | pmax | 0 | +----------------+------------+
Виконав це на слейві - все робить так само. Як отримати доступ до ціх розділів напряму? В постгресі я міг, тут не можу. В принципі, це не потрібно, але є випадок коли нам би це знадобилося - коли ми хочемо бекапити тільки частину поточного року. В інших бекапах будуть данні за інші роки, тому нам не потрібно втрачати час і дисковий простір на бекап старих даних. mysqldump дампить всю таблицу. Ну ок, не фартануло по цьому питанню. Але ж з гуглежем в 5 хвилин я можу і помилятися, просто для мене це питання непринципово. Ітак. Як подивиться, що ми маємо якийсь профіт: explain select * from pays where id<3; +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | 1 | SIMPLE | pays | p2023 | range | PRIMARY | PRIMARY | 4 | NULL | 2 | 100.00 | Using where | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
тут бачимо, що профіт є - вибірка йде чисто з розділу p2023 Перевіряємо, що субд може шукати одразу по декількох розділів: explain select * from pays; +----+-------------+-------+------------------+------+---------------+------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------------+------+---------------+------+---------+------+------+----------+-------+ | 1 | SIMPLE | pays | p2023,p2024,pmax | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | NULL | +----+-------------+-------+------------------+------+---------------+------+---------+------+------+----------+-------+ Але в бою ми профіта не отримаємо, бо нам був би корисний такий запит: explain select * from pays where time<unix_timestamp('2020-01-01'); Але він, очиковано, ніякого профіту не дає: +----+-------------+-------+------------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | pays | p2023,p2024,pmax | range | time | time | 4 | NULL | 1 | 100.00 | Using index condition | +----+-------------+-------+------------------+-------+---------------+------+---------+------+------+----------+-----------------------+
Тобто на даном етапі я не бачу варіанту отримати плюси від партіціювання. Можливо ми щось виграємо на швидкості вставки даних в таблицю pays. Але це потрібно проводити дослідження на великіх даних. При цьому я не думаю, що зараз є у когось проблеми саме при створюванні даних в таблиці pays. Але. Все може бути не так як я думаю, бо я витратив на все 4 години, а це малова-то для експертної думки
|
|
|
14
|
Главная категория / Модули NodenyPlus / Оптимізація API для ТВ сервісів
|
: 01 Октября 2023, 18:03:53
|
Є дані, що API Трініті підтупляє іноді, через це запити стають в чергу, і через це тарифи закінчуються пізніше. Для деяких провів це є проблемою, бо в деяких тарифах змінюється ціна підключенного тарифу. Для Трініті і Мегого (для Мегого не такі проблеми, але я все рівно зробив, нехай буде запас міцності) зробив модулі, яки ставлять запити у чергу. Ця черга виконується в окремому потоці і ніяк не впливає на встановлення послуг в NoDeny. Другий плюс в тому, що є можливість спробувати повторити запит через деякий час, і ще через деякий більший час і т.д. коли спроб стане більше 5 - припиняємо і клієнту в хісторі пишемо червоний запис про помилку. Тобто ми ще будемо бачити що з деякими клієнтами не все ок в послугах ТВ. Доки: TrinitiTvMegogo
|
|
|
|