Разработана простая и эффективная система заграждения! Босс напрямую повышает зарплату
Разработана простая и эффективная система заграждения! Босс напрямую повышает зарплату

Сначала, а затем прочитайте, Брат Нэн поможет вам получить более половины ваших навыков Java.

Заградительный огоньСистема зародилась в Японии.,Популярно на видеосайтахniconico。Хацунэ Мику, которую мы знаем(Hatsune Miku)Просто тамniconicoПопулярно на платформе!!

Я брат Нэн, лидер в области изучения и развития Java. Я верю, что вам будет полезно пройти собеседование и получить предложение поступить в компанию, о которой вы мечтали.

⭐⭐⭐Эта статья включена в《Javaизучать/Передовой/Руководство по собеседованию》:https://github..JavaSouth

1. Конструкция живого заграждения

1.1 Поддержка базовой структуры данных

Южные друзья, обратите внимание на Заградительный в правом нижнем углу. список огней,Этот список Заградительный огонь — это то, что мы хотим покорить сегодня.,至于中间视频直播的走马灯Заградительный огонь,На самом деле оно основано на Заградительный данные списка огня для прокрутки.

Брат Нэн наблюдал за этой комнатой прямой трансляции.,Теперь есть415 000люди смотрят!

Компьютерный мир на самом деле является абстракцией реального мира, так какую структуру данных нам следует использовать для поддержки заграждающего списка?

Я надеюсь использовать Redis. Официальный слоган Redis имеет такой властный лозунг.

Get the world’s fastest in-memory database from the ones who built it

Получите самую быструю в мире базу данных в памяти от конструктора

Что касается базовой структуры данных, мы используем один из пяти основных типов данных Redis: Zset. Zset — это тип упорядоченного набора. Он имеет значение оценки. Значение оценки используется для хранения отметки времени комментария пользователя. Затем весь список будет отсортирован в соответствии с отметкой времени.

Значение элемента Zset используется пользователем Заградительный огонь,Например, тот, что на фото выше:Сценарий воспроизводится снова и снова

Учитывая поддержку базовой структуры данных, давайте поговорим о функциональных ограничениях этого заградительного списка. Вы заметили, что когда мы входим в комнату прямой трансляции, в комнате прямой трансляции не будет отображаться весь контент заграждения?

Часто отображаются только первые 10 элементов.

Затем мы также добавляем эту функцию в список блокировки и сохраняем атрибуты только первых 10 элементов в структуре Zset Redis.

Язык кода:java
копировать
// Создайте структуру данных Zset и установите ограничение в 10 элементов.
public class DanmakuService {

    private Jedis jedis = new Jedis("localhost");

    public void addDanmaku(String roomId, String danmaku, long timestamp) {
        String key = "room:" + roomId + ":danmaku";
        jedis.zadd(key, timestamp, danmaku);
        // Сохраняйте только последние 10 Заградительный огонь
        jedis.zremrangeByRank(key, 0, -(11));
    }
}

1.2 Запрос списка заграждений

Когда пользователь входит в комнату прямой трансляции, как запрашивается список заграждений?

Мы придерживаемся самого простого и эффективного подхода. Когда пользователь входит в комнату прямой трансляции, клиент вызывает интерфейс API для запроса списка заграждений в Redis.

Некоторые друзья могут спросить: это только первые 10 последних записей чата, а что насчет остальных?

Не волнуйтесь, есть два варианта.

(1) Опросный запрос

Клиент опрашивает интерфейс API и постоянно фиксирует новые сообщения, отправленные пользователями. огонь. Для получения более подробной информации клиент сначала спросил о Заградительный. список огней的数据结构是:[(Временная метка1: Заградительный огонь 1), (Отметка времени 2: Заградительный огонь2)]

Последующий клиент запроса продолжает опрашивать и вызывать интерфейс API, передавая текущий Заградительный список огней的Максимальный входной параметр временной метки。而后端服务就会根据该Временная метка返回比该Временная метка大的数据,Новый Заградительный, присланный пользователями Также будет отображаться огонь.

Язык кода:java
копировать
// API-интерфейс опроса
public class DanmakuService {

    private Jedis jedis = new Jedis("localhost");

    public Set<String> getRecentDanmaku(String roomId, long lastTimestamp) {
        String key = "room:" + roomId + ":danmaku";
        return jedis.zrangeByScore(key, lastTimestamp + 1, Long.MAX_VALUE);
    }
}

Как часто нам нужно устанавливать время опроса для API опроса? Давайте сначала настроим 3 секундыПроголосуйте за обновления один раз Заградительный список огней, который позже будет оптимизирован и скорректирован на основе отзывов пользователей и ресурсов сервера.

(2) Технология WebSocket

Особенностью комнаты прямой видеотрансляции является то, что ведущий и зрители постоянно взаимодействуют и общаются, что требует синхронизации аудио и видео в реальном времени. Тогда прямая трансляция должна осуществляться в режиме реального времени. Используя первый метод API опроса, это может быть. 3 секунды延迟的情况发生。

Чтобы отправлять новые заграждения в реальном времени, мы можем использовать технологию WebSocket. Клиент и сервер WebSocket сохраняют длительное соединение. Пока пользователь отправляет новое сообщение заграждения, сервер WebSocket будет отправлять его клиенту в реальном времени.

Хотя первый метод является грубым, если запрос опроса будет пустым, то этот запрос является пустой тратой ресурсов и небезопасен для ресурсов сервера. Но это просто и эффективно, с небольшим количеством ошибок.

Если ваш начальник хочет, чтобы вы за полмесяца запустили эту функцию списка заграждений, то первый способ — неплохая идея. В будущем мы будем разрабатывать стратегии обновления и настройки, основанные на реальных условиях, например, переход на технологию WebSocket.

1.3 Системный процесс

Брат Нэн нарисовал процесс всей системы.

Пользователи отправляют заграждения через клиент, а сообщения о заграждениях отправляются в Kafka через серверную службу. Используя сообщения Kafka, мы можем сократить пиковый трафик. Сообщения заграждения иногда исчисляются десятками тысяч в секунду. Задача хранения сообщений заграждения кэшируется в очереди сообщений и выполняется одно за другим, что снижает мгновенную высокую нагрузку на сервер.

После отправки в Kafka серверная служба, отвечающая за мониторинг заграждающих сообщений Kafka, записывает заграждающие сообщения в Redis.

Язык кода:java
копировать
// Монитор пишет в Redis
public class DanmakuListener {

    private Jedis jedis = new Jedis("localhost");

    @KafkaListener(topics = "danmaku", groupId = "group_id")
    public void listen(ConsumerRecord<String, String> record) {
        String roomId = record.key();
        String message = record.value();
        long timestamp = System.currentTimeMillis();
        
        String key = "room:" + roomId + ":danmaku";
        // Воля Заградительный Огонь Сообщение, отправленное в Redis Zset
        jedis.zadd(key, timestamp, message);
        // Сохраните последние 10 элементов
        jedis.zremrangeByRank(key, 0, -11);
    }
}

1.4 Проблема потери сообщений

Есть такая ситуация,пользовательAОтправил(1726406132, Заградительный огоньA),пользовательBОтправил(1726406150, Заградительный огоньB),Пользователь A первый отправил Заградительный огонь, затем пользователь Б отправляет Заградительный огонь。

Если заграждения пользователя B сначала записываются в список Zset Redis, другие пользователи входят в комнату прямой трансляции, чтобы запросить первый список заграждений. Даже если пользователь А успешно напишет блокировку позже, другие пользователи не получат блокировку пользователя А.

Потому что клиент будет обновлять только сообщения о заграждении с меткой времени, большей, чем заграждение B. Как с этим справиться?

Мы хотим решить проблему, заключающуюся в том, что блокировка B успешно записывается до блокировки A. Независимо от других особых обстоятельств, мы можем добавить функцию распределенной блокировки к методу записи в Redis, чтобы гарантировать, что блокировка будет получена первой, а сообщение о блокировке будет получено первым. Во время этого процесса не будет никаких помех от написания других сообщений.

Язык кода:java
копировать
// Письмо Заградительный Получить распределенную блокировку, когда огонь
public class DanmakuService {

    private RedisLockUtil redisLock = new RedisLockUtil();
    
    private Jedis jedis = new Jedis("localhost");

    public void addDanmakuWithLock(String roomId, String danmaku, long timestamp) {
        String lockKey = "lock:" + roomId;
        try {
            if (redisLock.acquireLock(lockKey)) {
                String key = "room:" + roomId + ":danmaku";
                jedis.zadd(key, timestamp, danmaku);
                jedis.zremrangeByRank(key, 0, -11);
            }
        } finally {
            redisLock.releaseLock(lockKey);
        }
    }
}
Язык кода:java
копировать
public class RedisLockUtil {

    private Jedis jedis = new Jedis("localhost");
    
    private static final int EXPIRE_TIME = 5000; // 5 секунд

    // Получить блокировку
    public boolean acquireLock(String lockKey) {
        long currentTime = System.currentTimeMillis();
        String result = jedis.set(lockKey, String.valueOf(currentTime), "NX", "PX", EXPIRE_TIME);
        return "OK".equals(result);
    }

    // разблокировать замок
    public void releaseLock(String lockKey) {
        jedis.del(lockKey);
    }
}

Нажмите здесь, «JavaSouth» — это «Расширенное руководство по изучению Java», которое охватывает основные знания, необходимые Java-программистам, и ключевые моменты собеседований.

Я Брат Нэн, Нэн — это Нэн. Я нашла ваши интересные комментарии на Get➕Like➕Follow.

Творить непросто, поэтому вы можете ставить лайки, собирать и подписываться, чтобы поддержать его. Ваша поддержка — самая большая мотивация для моего творчества.❤️

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose