• Есть ли какая то статья, где будет соотношение кол-ва одновременных юзеров на сайте и рекомендуемой конфигурации сервера?

    @dimuska139
    Backend developer
    Нет, потому что 500 человек, грузящие на сервер видео для обработки, и 500 человек, просто читающие на сайте статьи - это совершенно разные вещи, которые требуют совершенно разные конфигурации сервера.
    Ответ написан
    Комментировать
  • Имеет ли смысл использовать в проектах свою реализацию аутентификации и авторизации с использованием JWT, когда есть OAuth2?

    @dimuska139
    Backend developer
    Во всех моих проектах используется и авторизация через соц. сети, и авторизация через email-пароль. Я не очень понял, как OAuth2 противоречит использованию JWT-токенов. Вы залогинились через VK, допустим, и бэкенд вашего сайта после этого сформировал пару токенов (access - jwt и refresh - обычный токен). То есть OAuth2 - это по сути делегирование выполнения аутентификации стороннему сервису, где юзер уже зарегистрирован ранее. А после этого (при успешной аутентификации) вы формируете токены (у себя на сервере) и крутите (я про ротацию) сами их как хотите (это к OAuth2 уже не относится). То есть ответ такой: одно не исключает другое.

    Или вы спрашиваете о том, есть ли смысл в 2022 году оставлять возможность регистрироваться через email+пароль? Если да, то это зависит от бизнес-требований. Как стоит задача - так и делайте. Во всех моих проектах есть регистрация в том числе и через email+пароль (и это решал не я).

    Может ли это мне как-то навредить в будущем

    Это решают менеджеры, которые формируют бизнес-требования, а не исполнитель.

    P.s. продублирую на всякий ещё и тут: https://gist.github.com/zmts/802dc9c3510d79fd40f9d...
    Ответ написан
    1 комментарий
  • Как обезопасить генерируемый PHP скрипт?

    @dimuska139
    Backend developer
    Вот что вам нужно - https://stackoverflow.com/a/15064283. В переменной $str должен быть генерируемый php-код. Я бы это php-код с помощью Twig рендерил и записывал в переменную $str. Название переменной, конечно, надо нормальное дать вместо $str. Это пример просто.
    Ответ написан
  • Выделяется ли память на аргумент функции переданного указателем?

    @dimuska139
    Backend developer
    pprof Вам в помощь. Потому использование указателей не всегда оправдано и зависит от конкретной ситуации.

    нужно ли стараться по максимуму работать именно через указатели

    Нет
    Ответ написан
    Комментировать
  • Golang. Как поставить внешний пакет на компьютер без интернета?

    @dimuska139
    Backend developer
    Как вариант, указать replace в go.mod на локальную папку. Ещё можно сделать кастомный GOPROXY и ставить пакеты через него. А сами пакеты хранить на компе без интернета (см. Athens).
    Ответ написан
    Комментировать
  • Можно ли передать индекс структуры указателем в функцию?

    @dimuska139
    Backend developer
    func isPasswordValid(password string) bool {
      if len(password) < 8 || len(password) > 128 {
        return false
      }
      return true
    }
    Ответ написан
    Комментировать
  • Какой стек выбрать для бэкэнда?

    @dimuska139
    Backend developer
    Важна производительность, поэтому и стал вопрос о переходе от PHP/Laravel

    Тут вообще нет связи. Узким горлышком в таких проектах является не язык, на котором приложение написано, а база данных. Если медленно выполняются запросы, то хоть на ассемблере бэкенд напиши - быстрее сервер отвечать не будет. Ну может пару миллисекунд выиграете, но на фоне времени выполнения запроса в БД и сетевых издержек это смешные цифры - даже не заметите разницу. А если речь идёт о Django, то это вообще не про производительность, потому что этот фреймворк довольно тяжёлый сам по себе, да и Python - это далеко не самый производительный язык даже среди скриптовых.

    Если речь идёт про большие нагрузки, то тоже язык тут не особо при делах, потому что обеспечиваются они масштабированием, кешированием и оптимизацией запросов к БД. Язык приложения тут вообще не при чём - разве что памяти какой-то больше жрёт, какой-то меньше. 200к в сутки - это в среднем всего лишь 2-3 запроса в секунду - то есть вообще ни о чём. Понятно, что распределение посещаемости вряд ли непрерывное равномерное, но тем не менее 200к даже если за один час - это всего лишь 140 запросов в секунду. С такой нагрузкой справится любой современный язык и фреймворк даже без масштабирования, кстати.
    Ответ написан
    1 комментарий
  • Парсинг скаченных сайтов?

    @dimuska139
    Backend developer
    Для решения этой задачи вам потребуется запускать go-сервер для каждого сайта. Нужно сделать так, чтобы можно было открыть index.html в браузере и подключить JS-файлы, после чего нужно подключаться к нему с помощью Selenium (чтобы выполнялся JS) и доставать оттуда данные. Скорее всего, пригодится вот эта библиотека. Возможно, кстати, сервить файлы и не потребуется, и можно их как-то сразу в Selenium подсунуть - там надо уже по факту смотреть.
    Ответ написан
    Комментировать
  • Как организовать хранение фотографий для сайта?

    @dimuska139
    Backend developer
    Загружайте файлы не в папку, а в s3-совместимое хранилище (чтобы при желании можно было без страданий и изменений в коде перейти на Amazon или в Linode какой-нибудь) - MinIO. Т.е. генерируете некий id, превращаете его в хеш, формируете ключ и по нему льёте в MinIO. Причём храните только оригиналы.

    Что касается миниатюр, то их нарезать и хранить не нужно. Представьте, если размеры в дизайне поменялись - что тогда? А если для каждой миниатюры webp-версия потребовалась - все картинки опять обрабатывать? Есть решение - imgproxy. Это специальный прокси-сервис (можно на свой сервер поставить, как и MinIO), который нарезает картинки "на лету" в момент обращения (по параметрам в url). Кроме нарезки, есть ещё куча разных возможностей. Кеша внутреннего нет, т.е. перед imgproxy есть смысл поставить Nginx для кеширования миниатюр (чтобы при каждом обращении не нарезало).
    Ответ написан
    7 комментариев
  • Почему такое большое время между запросами?

    @dimuska139
    Backend developer
    Как вариант, заканчиваются коннекты. Попробуйте увеличить параметр max_connections
    Ответ написан
    Комментировать
  • Микросервисная архитектура: насколько микро? и почему не возникает проблем с долгим ожиданием?

    @dimuska139
    Backend developer
    для расписала нашего монолита из-за проблем с масштабируемостью

    Не очень понял связь между монолитом и масштабируемостью. Если следовать вот этим правилам, то любой монолит будет отлично масштабироваться. Я бы на вашем месте проект привёл именно к соответствию этим правилам, а не спешил перелезть на микросервисы, т.к. и у них проблем хватает.
    Проблема 1:

    Почему только 3? У вашего магазина нет авторизации? Есть - это отдельный микросервис. Рассылка элетронной почты есть? Есть - ещё один микросервис. Смски шлёте? Ещё один. Другое дело, что писать это всё, понятное, дело должен не один человек, и, скорее всего, не всё на php.
    Проблема 2:

    Последовательно (синхронно) в кучу сервисов никто запросы не делает. В Guzzle (библиотека для http-запросов) есть асинхронный режим, кстати. То есть можно сразу сделать обращение к нескольким сервисам и собрать результаты (время будет равно времени выполнения самого медленного запроса). Но вы и с фронтенда можете сделать обращение к нескольким сервисам сразу асинхронно ведь. Если вопрос в авторизации, то для этого можно использовать jwt-токены - их каждый сервис может сам валидировать. Также можно кешировать данные в определённых ситуациях и даже дублировать в разных сервисах (в микросервисной архитектуре это допустимо).
    Проблема 3:

    Обычно никак не решается, как ни странно. Распределённые транзакции - это боль. А общую базу для нескольких микросервисов использовать нельзя - это антипаттерн.

    P.s. возможно, в вашем случае не нужно всё дробить на кучи микросервисов. Это долго, дорого, трудоёмко - и сложно сделать так, чтобы было удобно, особенно когда опыта нет. Попробуйте что-то одно отделить по мере надобности, потом другое. А дробить бездумно точно никакого смысла не имеет.
    Ответ написан
    Комментировать
  • Как установить декоратор на метод, который не является эндпоинтом?

    @dimuska139
    Backend developer
    Вот так сделайте декоратор - заработает:
    const CustomDecorator = () => (target: Object, propertyKey: string, descriptor: PropertyDescriptor) => {
      let sourceMethod = descriptor.value;
      descriptor.value = function (...args: any[]) {
        console.log("before");
        let result = sourceMethod.apply(this, args);
        console.log("after");
        return result;
      }
    }

    P.s. вот тут можете почитать более детально
    Ответ написан
    5 комментариев
  • Почему не работает метод delete?

    @dimuska139
    Backend developer
    Может быть, в сервисе надо так?

    async remove(userId: number) {
            return await this.UserRepository.destroy({
                where : {id : userId},
                force : true
            });
        }
    Ответ написан
  • Как динамически передавать параметр в функцию getServerSideProps?

    @dimuska139
    Backend developer
    Вы переменную не из тела компонента должны брать. В getServerSideProps сделайте const { query } = context; - и в query будут все query-параметры из url. Вот небольшой пример:
    export async function getServerSideProps(context: any) {
        const { query } = context;
        let f: PostsListFilters = {
            limit: 24,
            offset: 0,
            order: '-publishedAt'
        };
    
        if (query.page) {
            f.offset = f.limit * (query.page - 1);
        }
    
        const posts = await postsActions.fetchPosts(f);
    
        return {
            props: {
                posts: posts.data,
                total: posts.meta.total,
            }
        }
    }
    Ответ написан
    Комментировать
  • Как развернуть бд PostgreSQL на локальном компьютере для разработки?

    @dimuska139
    Backend developer
    Установите Docker и docker-compose. Создайте файл docker-compose.yml со следующим содержимым (см. ниже) и выполните команду sudo docker-compose up -d в директории с этим файлом.
    version: '2'
    services:
        db:
            image: postgres:13
            volumes:
                - ./db:/var/lib/postgresql/data/pgdata
            ports:
                - 5428:5432
            environment:
                - POSTGRES_USER=user
                - POSTGRES_DB=mydatabase
                - POSTGRES_PASSWORD=12345
                - PGDATA=/var/lib/postgresql/data/pgdata

    База будет доступна по следующим данным:
    • Хост: 127.0.0.1
    • Порт: 5428
    • Название базы: mydatabase
    • Пользователь: user
    • Пароль: 12345

    P.s. после рестарта контейнера содержимое базы очищаться не будет, т.к. указан volumes.
    Ответ написан
    Комментировать
  • Как добавить в логгер место, откуда вызван код?

    @dimuska139
    Backend developer
    Вот такой способ вы рассматривали? Тогда в самом верху будет стек вызовов сформирован
    Ответ написан
    Комментировать
  • Где можно посмотреть все типпы аннотаций для swagger php?

    @dimuska139
    Backend developer
    Прямо списка доступных аннотаций я тоже не нашёл, но там есть вообще папка с примерами, где есть многие вещи.

    По поводу генерации: вам нужно сделать эндпоинт, в котором будет выполняться следующий код:
    $openapi = \OpenApi\Generator::scan(['/path/to/project']);
    header('Content-Type: application/x-yaml');
    echo $openapi->toYaml();

    При обращении к этому эндпоинту библиотека просканирует ваш проект, ища в нём аннотации и сформирует yaml. Если что-то не так - увидите ошибку.
    Ответ написан
  • Как правильно парсить сайты, чтобы не словить капчу?

    @dimuska139
    Backend developer
    В любом случае каптча периодически, скорее всего, будет появляться. Но это не беда, ведь есть кучи сервисов, которые за копейки их разгадывают. Например, вот. Обычно именно так и делают.
    Ответ написан