Биллинговая система Nodeny
16 Сентября 2024, 22:06:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Прекращена поддержка версии Nodeny 49
 
   Начало   Помощь Поиск Войти Регистрация  
Страниц: [1] 2 3 ... 10
 1 
 : 28 Июля 2024, 17:33:02 
Автор Efendy - Последний ответ от SerjioMati
ще є таке підключена послуга інет + мегого оптимальна, підключили послугу інет + максимальна, а потім просто інет. і послуга інет + оптимальна і інет + максимальна залишаються заморожені) а потім якщо абонент оплатить декілька місяців, вони розморожуються і підключені вже 3 послуги)

 2 
 : 28 Июля 2024, 11:17:39 
Автор Efendy - Последний ответ от Efendy
У посуги є параметр "Не активувати послугу поки не стане достатньо коштів" - це один з варіантів (їх декілько) заморозки послуг. Також у модуля ядра services є параметр "Якщо послуга не може завершитися більше доби, наприклад, через проблеми API провайдера ТВ послуг, запускається процедура примусового завершення". Цей параметр захищає від ситуації, коли послуга через якісь проблеми не може завершитися і в цьому випадку вона б залишалася б підключеною вічно, поки це хтось не помітив. Був баг, коли заморожена послуга завершалася через добу через цей механізм. А вона може вісити вічно, бо ні на що не впливає, просто чекає грошей. Пофіксив

 3 
 : 29 Июня 2024, 09:05:50 
Автор Efendy - Последний ответ от Efendy

https://wiki.nodeny.com.ua/index.php?title=Binotel_%D1%82%D0%B5%D0%BB%D0%B5%D1%84%D0%BE%D0%BD%D0%B8%D1%8F

 4 
 : 26 Июня 2024, 20:08:20 
Автор Efendy - Последний ответ от Efendy
Рано чи пізно всі там будемо, тому треба думати про 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 процеси будть йти як і йшли до цього.





 5 
 : 25 Июня 2024, 15:28:22 
Автор Efendy - Последний ответ от Efendy
Створив гілку, але скоріше тільки для себе - щоб не забути які я робив дослідження. Ну якщо комусь є щось сказати, можете висловлюватись)

Чим більше даних в базі даних, тім повільніше вона працює, це очевидно. Але в більшості випадків потрібні актуальні дані - ну, наприклад, платежи тільки за останній період. По дефолту при переході в розділ "платежі" там як раз і показуються платежі за останні декілька місяців. Для таких ситуацій в базах даних використовують фішку "партіціювання" - це коли дані однієї таблиці розділяються не декілька, умовно кажуючи таблиць. Наприклад, можна розділити по даті: за 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 години, а це малова-то для експертної думки

 6 
 : 19 Июня 2024, 14:50:45 
Автор Maks - Последний ответ от Belos
Добрый день всем! А есть возможность подсказать тут по восстановлению базы? симтомы похожи
Цитировать

ERROR at line 1: Unknown command '\"'.



решил

 7 
 : 19 Июня 2024, 13:35:14 
Автор Maks - Последний ответ от Belos
Добрый день всем! А есть возможность подсказать тут по восстановлению базы? симтомы похожи
Цитировать

ERROR at line 1: Unknown command '\"'.

 8 
 : 19 Мая 2024, 15:57:23 
Автор Efendy - Последний ответ от Efendy
https://wiki.nodeny.com.ua/index.php?title=%D0%A2%D0%B5%D0%B3%D0%B8_%D0%B2_%D1%83%D1%81%D0%BB%D1%83%D0%B3%D0%B0%D1%85

 9 
 : 02 Мая 2024, 12:30:22 
Автор Efendy - Последний ответ от k291
в модуле Portmone v1, какой url для обмена данными?

 10 
 : 11 Апреля 2024, 11:34:00 
Автор Efendy - Последний ответ от SerjioMati
так їх там нема)

угу. у мене платинова карта від моно, то за кожну тисячу 11 миль) але сука йдеш до нас у магазин і там навіть 1500 грн умудряються розділити на 2 чеки) і я хер отримаю, а не кешбек...

Страниц: [1] 2 3 ... 10
Powered by MySQL Powered by PHP Powered by SMF 1.1.20 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!