Перейти к содержимому
Выбор современного форума и миграция с Discuz на NodeBB

Выбор современного форума и миграция с Discuz на NodeBB

2025-02-17 14:14

После прекращения поддержки Discuz потребовался выбор альтернативного форума. Протестировал несколько вариантов, кратко расскажу о впечатлениях и методах миграции.

Ниже перечислены в порядке рейтинга на Github.

discourse

Это форум номер один, но он основан на RoR. Производительность RoR оставляет желать лучшего, потребление памяти также велико, поэтому сразу отказался от него.

Приведу пример: наша старая система входа была сделана на RoR. Когда краулеры обходили наш форум Discuz, под каждым постом была ссылка для входа с разными параметрами from. Некоторые глупые краулеры обходили их все. Эта страница просто рендерила форму входа, но этого хватило, чтобы положить систему входа на RoR. При этом Discuz, который также обходили краулеры, не испытал никаких проблем. Тем, кто привык к скорости и экономичности Discuz, стоит подготовиться и подумать, сможете ли вы это вытерпеть.

flarum

У него отличный интерфейс. Основан на PHP+MySQL, в теории проблем с производительностью быть не должно. Однако запросы SQL на форуме не оптимизированы: доступ к первому посту на пустом форуме генерирует 100 SQL-запросов, время загрузки начинается от 100 мс. Если использовать маломощную облачную базу данных, то 200 мс — это норма. С такой скоростью и с учетом загрузки остального контента время ожидания приближается к 1 секунде.

nodebb

Сделан на NoSQL+NodeJS, обладает высокой производительностью, низкой нагрузкой на CPU. Кроме того, использует постоянное WebSocket-соединение, поэтому скорость отклика очень высокая. Потребление памяти начинается с 1 ГБ, но растет медленно. Плагины и API полные, поэтому выбрал его.

apache / answer

Тоже очень хороший, похож на Zhihu/StackOverflow. Но я не нашел способа отключить такие функции, как “задать вопрос”, “принять ответ”. Если бы это было возможно, получился бы форум, ориентированный на статьи (длинные основные посты). Подходит для форумов, не требующих множества коммуникационных функций, например, для гайдов.

flaskbb / flaskbb

Форум на Python, производительность отличная, но давно не обновлялся.

rafalp / Misago

С первого взгляда — форум для анимешников, тоже на Python. Автор начал разработку не так давно, но работает очень усердно. Посмотрел, он использует библиотеку SocialAuth для Python, которая позволяет легко интегрировать вход через QQ, Weixin, Google и другие способы, включая интеграцию с собственным сайтом.

Еще есть два китайских форума, которые выглядят неплохо: один — Casbin, очень похож на v2ex, а также bbs-go и symphony, похожие на блог CSDN, но я их не тестировал.

Миграция с Discuz на NodeBB

Если у вас есть собственный сайт, для миграции системы аутентификации в NodeBB можно использовать два официальных плагина: nodebb-plugin-session-sharing или nodebb-plugin-sso-oauth2-multiple.

Что касается импорта данных из Discuz, здесь придется писать код самостоятельно. Попросите ИИ на Python написать каркас, а остальное доработайте сами.

Если нужно импортировать только посты, пройдитесь циклом по таблице posts из Discuz, каждая строка — это пост. first=1 означает основную тему (топик).

Для топиков вызывайте API NodeBB api/v3/topics/, для ответов — api/v3/topics/{tid}. Для пользователей можно использовать API создания пользователя. Поскольку я использовал session-sharing, то применял интерфейс api/session-sharing/user, а для поиска пользователя — api/session-sharing/lookup?id={passport_id}.

Скорость обработки API — 5 запросов в секунду, будьте готовы к медленной миграции.

Пример вызова:

async def create_topic(title, body, timestamp, category, tags, uid):
    # Создание темы POST
    data = {
        "cid": category,  # ID категории (раздела)
        "title": title,
        "content": body,
        "timestamp": int(timestamp),  # Время в миллисекундах
        "tags": tags,
        "_uid": uid   # ID отправителя
    }
    # API-ключ администратора
    headers = {"Authorization": f"Bearer 1239383-3323-2323-2323-asd123123123"}
    # Вызов
    async with aiohttp.ClientSession() as session:
        async with session.post(
                'https://xxx.com/api/v3/topics/',
                headers=headers,
                json=data
        ) as response:
            if response.status != 200:
                # Если ошибка типа "Пожалуйста, добавьте содержимое сообщения, не менее 1 символа", значит content не экранирован
                response_text = await response.text()
                raise Exception(f"Error creating topic {title}: {response_text}")
            result = await response.json()
            topic_object = result['response']
            return topic_object['tid']

Обратите внимание, что логика публикации через API и публикации пользователем одинакова, применяются все ограничения форума на длину сообщения. Кроме того, по той же причине параметр timestamp игнорируется, и пост публикуется с текущим временем. Решение — отредактировать временную метку в строке 16 файла src/api/helpers.js, просто закомментировав строку data.timestamp = Date.now();. После миграции не забудьте вернуть все обратно, иначе пользователи тоже смогут менять время.

После этого изменения API для ответов api/v3/topics/{tid} также будет поддерживать передачу timestamp для указания времени.

Последнее изменение
hugo-builder
hugo-builder · · 自动翻译 about.md 2... · 248520b
Другие участники
...