Node.JS + MongoDB
Посоветуйте пожалуйста чтиво по этому поводу.
Из основных вопросов: Пока не понял как правильно работать с открытием соединения к базе, хочу использовать модуль mongodb и думаю никакие mongoose не надо. Цель - создать REST API для начала. |
Ответ: Node.JS + MongoDB
Не нужно книжек и чтивы. Если работал с mongo то там всё проактически идентично официальным докам (в случае с mongoose это не так).
Я юзал mongoose и потом перешёл на mongo-native от самих 10gen - и не жалею вовсе. Мне эти schemas - нафиг не сдались. Суть mongo - в её динамике, и нефиг пытаться прикручивать правила и структуру к collection'ам подобно это SQL бд. Офф дока - очень полезна, т.к. как уже говорил почти идентична к mongo-native в использовании. По факту - коммандная строка для mongo тоже на JavaScript'е ;) Про соединение, сперва тебе нужно создать объект куда коннектиться: PHP код:
PHP код:
PHP код:
https://github.com/mongodb/node-mong...aster/examples Есть пару тонкостей:
Если есть конкретные вопросы - задавай. Я пишу по работе RESTful API с mongo-native и express'ом ну и другими всякими плюшками. |
Ответ: Node.JS + MongoDB
Правильно ли я понимаю, что для каждого REST запроса надо создавать свое подключение? Мне сначала подумалось создать одно подключение к базе на старте приложения и потом его использовать. Потом я посмотрел некоторые рест библиотеки для монго и там для каждого запроса создается свой экземпляр Db. Такой подход верный?
Еще один вопрос - есть у nodejs возможность запускаться в многопроцессном режиме, это не стоит использовать для REST API? |
Ответ: Node.JS + MongoDB
Не нужно для каждого запроса свой db хэндлер - это оверкил.
Там блокировка на уровне бд будет а не на уровне node, следственно иметь более одного хэндла - смысла нету, только замедляет процесс. Возможно mongo-native кеширует коннекты и будет выдавать уже подконекченный - но это снова лишние телодвижения. Относительно мультипоточности - ты говоришь о cluster? Мы используем - 4 worker'а. Всё работает как полагается, естественно если у тебя есть сессия, то её нужно хранить вне процесса, мы используем connect-mongo, тем самым не важно в какой worker идёт запрос. По опыту пришёл к такому выводу - если у тебя есть CMS и write'ы очень редкие, и обслуживаются определённой группой людей, следственно таскать с собой функционал для CMS в основном API не оправдано. Для этого я сделал отдельные запросы для PUSH'ей, это немного идёт против логики REST'а, т.к. /url будет отличаться (я сделал субдомейн для этого, а руты были те же), но зато когда нужно обновить основной API, не нужно было перегружать CMS и т.п. Но это зависит от ситуации. cluster'ы - реально помогают, их количество обычно параллельно количеству ядер. Мы на ec2 xlarge (4 CPU) 4 worker'а запускаем - и всё ок. |
Ответ: Node.JS + MongoDB
Еще пара вопросов:
1. Как правильно обрабатывать ошибки, чтобы при их происхождении не падал весь процесс. Можно конкретно для express и mongodb. 2. Я так понимаю что кластер можно использовать как защиту от падения процесса, т.е. кластер при падении одного воркера может запустить нового воркера? И если надо будет перезапустить сервер, то просто необходимо будет перезапустить кластер да? 3. Какой модуль лучше использовать для логирования? Особенно если используется кластер и несколько воркеров. |
Ответ: Node.JS + MongoDB
Цитата:
Важно понимать что ошибки - это важно, и их не должно быть. Если в тестировании ошибок в запросах к бд небыло, а потом есть, значит твой query слишком динамичен и нужно его немного нормализировать (это 90% случаев). Я у себя в коде так делаю: Ранее при настройке express'а: PHP код:
PHP код:
PHP код:
Цитата:
Вообще есть "защито" от падения процесса. Есть event который ловит не словленные exception'ы. Но естественно если что-то жесть как пошло не так, то нужно и реагировать соответственно, а не тупо игнорировать. Но всё равно: PHP код:
Цитата:
Суть у него в том что он имеет основу для логгирования, но логит в транспорты, которые могут быть что угодно: консоль, файл, бд, MQ, redis, socket, amazon alerts, email, и т.п. Есть стандартный набор транспортов которых обычно хватает с головой. Я лично юзать буду файл + бд (с индексом просрочивания неделю), и ZeroMQ в мелкий процесс который через socket.io будет слать логи от разных процессов мне на мелкую страничку мониторинга. Таким образом если что-то случиться, я сразу могу вычислить с кем, где и т.п. |
Ответ: Node.JS + MongoDB
Хочу часть логики сделать на хранимом js в MongoDB, это лучше чем делать логику в NodeJS?
Upd: кстати как правильно вызывать хранимые функции? Upd2: Получилось примерно так: PHP код:
Это нормально или я что-то не так делаю? |
Ответ: Node.JS + MongoDB
Я предпочитаю ничего не хранить в DB. Можно лишь мелкие туулзы или функции утилит, но не относящиеся к логике твоего приложения - это ответственность твоего API.
Да и сразу по твоей функции - ты доверяешь назначение user_id кому? БД, или логике приложения? Я пытался сделать подобное - вставлять если нету, но потом пришёл к выводу - нефиг! Есть куча сценариев где тебе нужно получить юзверя - но он может и не быть там, следственно и вставлять его не нужно. Так что лучше разделить эту логику. Да и если ты 100% вставляешь, то не используй 'save', а используй 'insert'. save - весьма опасен, тем что если будешь обновлять что-то (ожидая update), а документа такого не будет, а обновление будет partial (только пару полей), то вставиться "не полный" документ, что твоя логика приложения не будет ожидать. И мелкая заметка, в node, для даты проще писать так: Date.now() - получает timestamp. |
Ответ: Node.JS + MongoDB
У меня это авторегистрация такая. id это id пользователя в соц сети. На счет insert спасибо, буду иметь ввиду. И я уже решил делать логику в ноде, а не в БД, а то получается какая-то фигня (не нравится мне такой код) с вызовами.
|
Ответ: Node.JS + MongoDB
Я тут щас aggregation и mapReduce изучаю. Заодно открыл для себя $where.
$where - позволяет стрингой передать сроку кода, например: Пример player'а: PHP код:
PHP код:
PHP код:
Следственно например для collection'а с 2800 записями, у меня затрачивается 72мс (на простом Mac'е), что ужасно долго для таких запросов. Следственно в реальном мире лучше кешировать длину массива рядом с массивом. Но всё же, если у тебя например запрос на 32 записи (например), то такой код - вполне приемлем. Нужно исследовать как там с блоком всего процесса (блокирует ли другие запросы и т.п.). aggregation - это интерестный монстрик, по получению всяких данные и более сложных манипуляций над документами. Например у меня есть записи игроков, и у каждого игрока есть любимая команда. Мне нужно получить список всех команд и сколько игроков её указали как любимую: PHP код:
Всего там 20 команд. В результате получу массив с до 20 записями такого вида: PHP код:
mapReduce - это ещё следующий шаг. Когда aggregation предоставляет операторы, и там важна их поочерёдность и т.п., то mapReduce принимает лишь 2 функции и query фильтр. Первая функция обрабатывает каждый документ (удовлетворяющий query) и если нужно вызывает emit, что передаёт уже обработанные данные (можно и не обработанные) в reduce функцию, где уже дальше мы имеем дело с групированными данными. Примеров много можно привезти, в моём случае, нужно было узнать сколько призов в среднем выйграл каждый игрок. Есть 2800 записей. И нужно получить общее арифметическое колличества призов: PHP код:
Снова, для тысячей записей - это не шустро, но для статистики - самое то. |
Ответ: Node.JS + MongoDB
Заметил что таймштамп в ноде в миллисекундах, а не в секундах как это в php. Поделил все на 1000)
|
Ответ: Node.JS + MongoDB
Цитата:
Тем более что если захочешь перевезти timestamp в дату то: PHP код:
|
Ответ: Node.JS + MongoDB
Бенефит: в базе либо Int32 если секунды, либо double если миллисекунды.
PS: начинаю втягиваться, на первый взгляд сложнее чем на php, потому что надо писать асинхронный код, с другой стороны вроде как и интереснее получается. |
Ответ: Node.JS + MongoDB
Цитата:
http://stackoverflow.com/questions/6...tes-in-mongodb Цитата:
Правда появяться некоторые "трудности", например запустить сразу 3 асинхронных функции, и потом финальную функцию, или сделать очередь асинхронных функций. Есть promise и async.js, но я как обычно юзаю свой вариант решения простой задачи: PHP код:
Вторая запускает все асинхронно и финальную когда все закончили. Пользоваться так: PHP код:
PHP код:
Как видишь он даже не начинает выполнение следующей функции до выполнения прошлой. PHP код:
И тут видно что он запускает все сразу, но финальную только когда каждая функция запустит next() по завершению (асинхронно или нет). |
Ответ: Node.JS + MongoDB
В тему асинхронного кода, юмор:
var result = fs.readFile(‘data.json’, function () {}) |
Ответ: Node.JS + MongoDB
А ты для задержки всегда setTimeout используешь? Я сейчас пользуюсь setImmediate для создания асинхронности. Она вроде откладывает выполнение до следующего цикла.
И еще вопрос: как правильно запускать/останавливать/перезапускать node js на сервере? Я пока только на windows его запускал. |
Ответ: Node.JS + MongoDB
Цитата:
Но имхо, если у тебя операция на столь тяжёлая и уже потребовала слишком много времени, тогда я советую пересмотреть либо операцию, либо выдвинуть её в отдельный node процесс и общаться с ним через ZeroMQ, тем самым - это будет точно асинхронно (главный процесс не будет выполнять задачу, и сможет паралельно заниматься своими вещами). Цитата:
На win, при разработки в Sublime Text 2, есть аддон для настроек компиляции. Тупо - билдишь, и в консоль будет выдаваться консоль. Но нужно дополнительно скрипт для остановки процесса (а то если ты сокет биндишь и не остановишь прошлый процесс, новый не сможет сокет создать на том же порту). А для деплоймента использовал NSSM ( http://nssm.cc/ ) - Non-Sucking Service Manager - очень понравился. В win редко когда есть хорошие туулзы и минималистичные как в unix. В общем он создаёт сервис в системе, и следит за ним. Можно настроить разные сценарии если процесс сервиса падает - перезапускать например сразу. Не для всех конечно случаев, но для многих я тупо сделал сервис на текущий разрабатываемый проект, и всё что нужно было, это останавливать процесс, и сервис перезапускал его автоматически так что заместо - остановить > запустить, я только один клик остановки - и уже мог идти тестировать. Единственное что логи нужно тогда придумать как слать, для этого я winston сделал и отдельный монитор с дашбоардом консоля :) На linux, есть два способа, первый проще и быстрее - screen. Делаешь отдельный screen и запускаешь там, затем детачишься из скрина если не нужно там быть. Но лучше конечно написать скрипт для сервиса, плюсов много - логи можно в файл по стандарту выводить. Автозапуск при рестарте компа. Удобно рестартовать: service api restart Вот файл для скрипта, кладём в /etc/init.d/ я назвал его "api". Работает на RedHat системах и Ubuntu. Естественно замени пути к твоим файлам сам. service api start service api stop service api restart Логи по стандарту тут: /var/log/api.log PHP код:
|
Ответ: Node.JS + MongoDB
Я так понял что нельзя обновить несколько членов массива за один запрос?
|
Ответ: Node.JS + MongoDB
Почему нет?
Под обновить - что ты имеешь ввиду конкретно? Тест - обновляет: PHP код:
|
Ответ: Node.JS + MongoDB
Мне надо у каждого объекта в массиве обновить поле или несколько полей. А не каждый итем обновлять по индексам.
Я пробовал такой запрос: PHP код:
в итоге наткнулся на это: https://jira.mongodb.org/browse/SERVER-1243 |
Ответ: Node.JS + MongoDB
А оператор $ да, обновит только первый найденный элемент в твоём случае..
Выход будет - подгрузить, выбрать в JS то что нужно, и обновить уже с новым списком. Будь осторожен если есть возможность делать эту операцию одновременно, т.к. тогда нужно будет лочить запись - чтобы предотвратить перекрёщивание двух операций с другими запросами на этот же документ. |
Ответ: Node.JS + MongoDB
Получил вот такое:
Как с этим бороться? |
Ответ: Node.JS + MongoDB
ETIMEDOUT это системная ошибка, а не самого node.js, видимо что-то на уровне TCP происходит, а node.js просто продвигает её.
Нужно знать как ты добиваешься такой ошибки, т.к. я на практике её не встречал. Если хочешь избежать падения процесса, можешь попробовать её поймать, возможно есть event для сокета (т.к. возможно ты с сокетами это ловишь): PHP код:
В продакшане очень не рекомендуется - т.к. это будет ловить не пойманные ошибки, но при этом оставлять процесс жить, когда последствия ошибки могут быть "не желательными". |
Ответ: Node.JS + MongoDB
Поставил обработчик пока на unhandledException.
Как оно получается я пока не знаю. У меня сейчас два процесса, т.к. я использую кластер на одном ядре виртуального сервера. REST API на основе express (http и https) в воркере. В мастере я запустил модуль cron, по которому я подсчитываю и обновляю статистику (это только подключение к MongoDB и асинхронное обновление). Других операций с сокетами я не делаю... |
Ответ: Node.JS + MongoDB
Запустил у себя на сервере наконец по дефолту вместо апача node js и думаю сейчас... а есть ли какой-то миддлваре для express, который может переадресовать для определенных хостов запрос на другой порт сервера, где запущен апач...? Если я вдруг захочу для дочернего домена сделать сайтик на php и использовать его на дефолтном порту...
|
Ответ: Node.JS + MongoDB
Есть, только его лучше использовать до главного API приложения.
http-proxy - проксит всё, вплоть до вебсокетов. Шустрый и используется nodejistu (хостинг node). https://github.com/nodejitsu/node-http-proxy Там всё по сути просто. Пишешь мелкий proxy app на ноде, указываешь разные прокси куда и как раскидывать, там есть куча вариантов проксить, вплоть до ручного определения. Получается запускаем proxy на 80 порту, далее API на другом, и проксим к API по дефолту. Apache запускаем тоже на другом порту, и проксим на него тоже по субдомену (например), а можно и по субдиректории. Если юзаешь AWS советую заюзать Route53 - домен менеджер, создание субдомена и обновление DNS записей занимает пару минут а не сутки. |
Ответ: Node.JS + MongoDB
Что-то не могу составить запрос на удаление поля HandR UPD: получилось PHP код:
|
Ответ: Node.JS + MongoDB
moka А не можешь ли привести пример простенького реалтаймового сервера, передающего координаты игроков. Я бы хотел node js и Unity связать через TCP.
|
Ответ: Node.JS + MongoDB
Примеры есть, только они на socket.io, следственно там только игровая логика и никакой сетевой, т.к. всё уже сделано используя socket.io. Но, естественно можно и сделать сериализацию и десериализацию на обоих сторонах. Проще будет начать с JSON'а, а потом что-то придумать дельнее.
Вот немного говнокода, писалось 24 часа, потом чуток приводилось в порядок но совсем чуток. https://github.com/Maksims/beat-em-up Играть тут: http://moka.co:88/ UPD: Я не советую, но есть socket.io клиент для unity: https://github.com/NetEase/UnitySocketIO |
Ответ: Node.JS + MongoDB
Не пойму как выполнить поиск с использованием регулярных выражений и символов юникода (русский текст).
Получилось, PHP код:
|
Ответ: Node.JS + MongoDB
Учти что поиск по тексту как у тебя не будет использовать никакой индексации, и на больших таблицах может быть очень дорогим, тем более что ты не ограничиваешь число результатов.
Для регулярок, тебе нужно использовать `new RegExp()`. А чтобы использовать индексацию по полю, то можешь сделать так: PHP код:
|
Ответ: Node.JS + MongoDB
Мне с индексами не судьба, хочу имена кланов сделать с именами типа -=М.О.Й.К.Л.А.Н=-
|
Ответ: Node.JS + MongoDB
И что мешает это всё равно заиндексировать?
Можно сделать массив `search` который будет содержать 2 вида строк: в нижнем регистре и в нижнем регистре без знаков. Далее простой индекс по этому полю `search`, и затем поиск будет весьма продуктивен. Главное это escape'ить регулярные знаки в прописные, например . в \. и т.п. Далее поиск будет работать по таким запросам: Код:
-=м.О.Й.к.л |
Ответ: Node.JS + MongoDB
Ближайший вопрос, который хотелось бы решить - это резервное копирование базы. Как это правильно сделать?
|
Ответ: Node.JS + MongoDB
Backup?
Есть трои принятых способа бэкапить бд, первый будет используя mongoexport/mongoimport второй mongodump/mongorestore, и снапшот системы (это для облаков). mongoexport/mongoimport Оперирует JSON данными, и предусмотрен к бэкапу только данных и не содержит никаких мета данных. Также т.к. данные в JSON формате, а он ненмого будет побольше чем BSON, нужно больше места для его хранения. Плюс при импорте, подразумевается что у тебя уже есть сама база данных с коллекциями и всеми индексами. Думаю это удобно для быстрого копирования блока данных между базами, но не совсем для бэкапов. mongodump/mongorestore Этот способ реально хорошо справляется с бэкапами, делает полную копию данных самих коллекций и всей базы (если на всю делаешь), хранит данные в BSON (что оптимальнее), а также хранит мета данные о коллекциях, индексах и других плюшках для полной копии восстановления. Snapshot of System Этот подход используется в облаках, когда ты можешь создать полную копию текущей системы. Такие снапшоты обычно весьма весомы, т.к. бэкапят всё что есть на системе а не только бд. Если у тебя большая бд и много ресурсов на системе - тебе такой вариант не подойдёт. Я использую mongodump/mongorestore, с ним можно дампить как всю бд, так и отдельные базы данных, так и более детально - отдельные коллекции. Учти что при mongorestore, если есть уже бд и коллекция - то данные добавяться паралельно к прошлым, так что если ресторишь, то удаляй коллекцию или всю бд (если всю бд ресторишь). Я написал скрипт который запускается каждый день в 3 ночи, используя node.js, он используя child_process вызывает command line для mongodump, который в свою очередь создаёт папку. Далее я это дело tar'ю, и заливаю там же скриптом на S3 Bucket, где стоит правило - автономно удалять файлы старее 1го месяца. Всё автономно, и никакой парки, плюс бэкапяться у меня две базы данных за один подход как два разные tar'а. |
Ответ: Node.JS + MongoDB
Все еще не очень понимаю вот это: http://nodejs.org/api/buffer.html
Цитата:
|
Ответ: Node.JS + MongoDB
Что конкретно тебе нужно с бинарными данными?
|
Ответ: Node.JS + MongoDB
Хочу научиться работать с бинарными данными как с MemoryStream в C#. Хочу свой протокол сериализации реализовать в будущем для клиентсервера.
|
Ответ: Node.JS + MongoDB
Ну ты как бы можешь да юзать то что тут есть, но для работы с бинарными данными я очень рекомендую поступить одним из способов:
1. Писать Addon на С++ для парсинга бинарных данных в JSON объект. 2. Заюзать готовые решения для этого, например protobuf. 3. Взять готовое решение на С++, и написать враппер/addon для него, например Cap'n Proto отличный выбор будет. Для начала и JSON'а хватает с головой. Если качественно написать логику сбора данных, то заменить сборку и разборку данных сможешь потом без проблем. |
Ответ: Node.JS + MongoDB
Больше всего в ноде не нравится то, что приходится делать вот такие "елки":
Особенно в те моменты когда есть асинхронные ветвления (иногда необходимо сделать лишний запрос в базу, а иногда нет). Я тогда справляюсь с использованием функций, которые вызываю несколько раз в ветвлении. К примеру (функция addRequest): |
Ответ: Node.JS + MongoDB
Угу, эта проблема популярна. Один из хороших вариантов "решения" её будут promise. Можно chain'ить асинхронные запросы как угодно, и отлавливать ошибки лучше.
И на err ты не проверяешь нигде :).. |
Ответ: Node.JS + MongoDB
Цитата:
|
Ответ: Node.JS + MongoDB
Цитата:
А ошибка указывает на ошибку в запросе, что порой ведёт к неприятным последствиям. Суть ловли ошибок, приводит к отслеживанию где запросы были не хорошие, и заставляет разраба валидить данные в запрос лучше. Например если ты где-то забыл убрать "неприятные" символы в стринге, что приводит к регулярке, а это очень неприятно для бд.. Или объект для фильтров собрал нехороший :) А порой претендуешь что есть переменная в документе, а её нету, тоже бывает такие дела.. |
Ответ: Node.JS + MongoDB
ну наличие переменных в документе я проверяю там где надо, да и обработки ошибок я когда-нибудь впишу, когда появится на это время)
|
Ответ: Node.JS + MongoDB
Вот поковырялся, я писал для себя сам мелкие функции для chain'ов асинхронных функций, но можешь заюзать async https://github.com/caolan/async там етсь например series - запускает функции поочереди. Думаю там можно также вставлять по пути до функции (task injection), и т.п.
|
Ответ: Node.JS + MongoDB
И я подобное писал для обработки массива и секвенции, но в примерах выше оно не помогает
PHP код:
|
Ответ: Node.JS + MongoDB
Потому что тебе нужен не статичный chain, что потребует модификации в твой - возможность вставлять job'ы по пути выполнения.
|
Ответ: Node.JS + MongoDB
Хм, а я не подумал что можно вставлять джобы в цепочку... Спасибо, навел на мысль...
|
Ответ: Node.JS + MongoDB
Я это сделал!
PHP код:
PHP код:
|
Ответ: Node.JS + MongoDB
|
Ответ: Node.JS + MongoDB
Цитата:
1) Клиент создает слишком большую нагрузку на CPU https://github.com/NetEase/UnitySocketIO/issues/13 http://forum.unity3d.com/threads/204...-UnitySocketIO 2) Нельзя принимать и посылать ивенты (socket.emit). Работают только месаги (socket.send) https://github.com/NetEase/UnitySocketIO/issues/16 |
Ответ: Node.JS + MongoDB
Я уже написал бинарную сериализацию пакетов и связал Unity и node js по tcp с использованием net модуля. Сейчас хочется сделать некую архитетуру для создания ММО решений.
|
Ответ: Node.JS + MongoDB
Не думаешь зарефакторить код, и выложить github проект? Т.к. думаю на него спрос будет весьма большой.
Если с точки зрения пользователя это работает как socket.io то вообще сказка и у тебя есть возможность менеджить популярный модуль на npm. В общем, на такой модуль будет спрос если его maintain'ить нормально. |
Ответ: Node.JS + MongoDB
Цитата:
|
Ответ: Node.JS + MongoDB
На данный момент чат сервер "все со всеми" можно сделать вот так:
PHP код:
|
Ответ: Node.JS + MongoDB
Прикольно.
Как понимаю нужен обмен Policy чтобы сделать нормальное общение? (также как в flash'е?). packetProcesors - как понимаю ты пушаешь функцию потом которая будет вызываться для каждого пакета. Как тебе подход как в socket.io? В плане имён пакетов и подпиской на них? Например: PHP код:
Например использовать EventEmitter'ы для использования event-driven парадигмы - очень збсь штука. Также можно предоставить promises как альтернативная парадигма, это уже зависит от разраба что и как юзать. Я сейчас promises юзаю, и порой очень просто и элегантно выходят решения (никаких пирамид). Можно выложить на github и там уже по пути менеджить и т.п. |
Ответ: Node.JS + MongoDB
Цитата:
Цитата:
Цитата:
Node js PHP код:
PHP код:
|
Часовой пояс GMT +4, время: 08:49. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot