Контролен списък за архитектура на бекенда: Как да създадем продукт от нулата

Събуждате се една сутрин, за да изпиете чашата си с кафе и voilà, моментът Eureka е тук. Най-накрая разбрахте своя бизнес модел и всичко си дойде на мястото. Знаете, че инвеститорите ще го харесат и просто нямате търпение да започнете да изграждате продукта. Предимството на първия двигател е вашето, което трябва да вземете.

Тези моменти са рядкост, но когато се случат, трябва да започнете в точното време. Всичко, от което се нуждаете, е правилното ръководство, което да ви помогне да разберете какво трябва и какво не трябва да правите. Не е време за експерименти, а за изпълнение. Сега е ВАШОТО време!

ЗАБЕЛЕЖКА - Следното е свързано със създаването на софтуерни архитектури от нулата. Така че, ако се интересувате от познаването на нищожността на участващите технологии, продължете. В противен случай, моля, споделете с тези, които определено ще харесат това: P

Откъде идва това ръководство

Аз самият съм работил върху шепа продукти на ранен етап и, честно казано, направих грешки. Винаги съм искал да има контролен списък, който да следвам, докато създавам продукт от нулата.

Има толкова много неща, свързани с изграждането на архитектура от нулата, че напълно ще забравите определени парчета. И те ще се върнат, за да ви хапят в по-късните етапи от продуктовия цикъл.

Най-накрая реших да създам този контролен списък с неща, които трябва да имате предвид, преди да натиснете този бутон за разполагане за първи път.

Така че без допълнително изграждане, ето контролния списък, през който трябва да преминете, докато изграждате Backend архитектура за продукт от нулата.

Изберете ПРАВИЛНИЯ език и рамка (за вашия проект)

Изборът на правилния език и рамка за вашия продукт е сложен и за това няма конкретен сребърен куршум. Моят съвет е да изберете език, който ви е най-удобен и да знаете тънкостите на влизането и излизането.

Като казах това, това е рядкост, защото има много малко хора, които са Javascript нинджи, или Python Panthers, или каквито и да е фънки имена там.

Така че изберете език, който има наистина добра поддръжка в индустрията, като Javascript, Python, Java или Go, за да назовем само няколко. Можете да изберете всеки език, просто изберете кой е най-удобен за вас.

И не забравяйте - изграждате MVP (минимално жизнеспособен продукт) и ще бъдете в процес на създаване на POC (доказателство за концепция). Затова извадете продукта си възможно най-скоро. Не е нужно да зацикляте по въпроси, които може да произлизат от новия език в града. За да избегнете тези проблеми, изберете по-широко използван, добре документиран език.

И накрая, можете да мащабирате по-късно. Ако сте във фазата на правене на POC, просто изградете и го свършете. Но ако създавате нещо наистина специфично и има специално изграден език и рамка, тогава определено трябва да изберете тази технология.

Но през повечето време проблемите, които се опитваме да решим, могат лесно да бъдат решени с някой от гореспоменатите езици и съответните им рамки. Затова просто изберете един и стартирайте продукта си.

Добър ресурс, който да ви помогне да решите -

//content.techgig.com/top-5-programming-languages-for-backend-web-development/articleshow/67337449.cms

Внедрете микроуслуги за удостоверяване и оторизация

Има много начини за удостоверяване и упълномощаване на потребител. Можете да опитате Session Tokens, JWT (JSON Web Tokens) или OAuth, за да назовем само няколко. Всеки вариант има свои плюсове и минуси. Така че нека разгледаме някои от тях по-отблизо.

JSON уеб токени

JWT са бързи и лесни за изпълнение. Това е така, защото символите никога не се съхраняват никъде във вашата система. Те просто се кодират, кодират и изпращат на потребителя. Така че валидирането на JWT е по-бързо от всеки друг метод.

Но след това, тъй като те не се съхраняват в системата, всъщност не можете да накарате маркера да изтече преди действителното му време на изтичане и това може да е проблем в определени случаи.

Затова разберете плюсовете и минусите на всяка система за удостоверяване и изберете тази, която най-добре отговаря на вашите изисквания. Аз лично предпочитам JWT (но това е моят собствен избор).

Разрешение

Никога не забравяйте да приложите оторизация на потребителите. Не искате да влезете в User1, за да промените подробностите за User2. Това може да причини чист хаос във вашата система.

Идентифицирайте крайните точки, които се нуждаят от разрешение, и ги внедрете веднага. Не искате състоянието на вашата база данни да бъде повредено по този начин. Не забравяйте разликата между 401 и 403.

По-долу са определени крайни точки, които определено трябва да имате предвид, докато създавате вашата система за удостоверяване (създадох такава в Django с помощта на JWT). Възможно е да има някои допълнения / изтривания за вашия случай на употреба, но това са тези, които трябва да помислите за изграждане.

Много рамки ги предоставят нестандартно, но ги обмислете, преди да ги изградите сами. Проверете автентификационни_класове и разрешителни_класове в Django Rest Framework за допълнителни справки.

Погледнете този ресурс на Django REST Framework -

//www.django-rest-framework.org/tutorial/4-authentication-and-permissions/

Създайте абстрактен базов модел, който да се наследи от всеки друг модел във вашата база данни

Помнете принципа на СУХОТО - Не се повтаряйте? Трябва да се следва в основата на софтуерното инженерство.

Въз основа на горния мисловен процес, във вашата база данни ще има определени колони, които ще присъстват във всяка таблица. Затова е по-добре да създадете абстрактен клас за тях, за да могат други класове модели да наследят от тях.

Нека да разгледаме този код и какво означава:

  • id - Въпреки че не е написан тук, той се създава автоматично от рамката на Django. Но ако го няма във вашия, запишете го в този клас. Това е просто автоматично увеличено поле, което може да се използва като първичен ключ във вашата връзка с база данни.
  • created_at - Това предполага кога полето / редът е бил вмъкнат във вашата таблица и е попълнен от самата рамка. Не е необходимо да го задавате изрично.
  • updated_at - Това предполага кога полето / ред е последно модифициран / актуализиран във вашата таблица и отново се попълва от самата рамка.
  • delete_at + is_deleted - Значи това е противоречиво поле. Нямам точен отговор дали трябва да е там или не - защото, честно казано, нищо в интернет никога не се изтрива. Това поле, ако е попълнено, показва, че редът е изтрит от системата (въпреки че данните остават в системата за бъдещи препратки и могат да бъдат извадени от базата данни и съхранени в резервни копия)
  • uuid - Зависи дали искате да поставите това в таблицата си или не. Ако трябва да изложите първичния ключ на вашата таблица на външна система, по-добре е да изложите този, а не автоматично увеличеното цяло число. Може би се чудите защо ...? Е, защо бихте искали да кажете на външна система, че имате 10378 поръчки в таблицата си? Но отново това е личен избор.

Настройте микрослужба за уведомяване

Всеки продукт трябва да изпраща напомняния и известия до потребителя за ангажиране и транзакции. Така че всеки продукт ще се нуждае от това.

Определено трябва да помислите за изграждането на Microservice, която предоставя услуги за уведомяване (като Push Notification, Emails и SMS) на вашите крайни потребители.

Това изобщо трябва да бъде отделна Microservice. Не изграждайте това във вашата удостоверителна микроуслуга или вашата услуга за приложения (действителната бизнес логика).

Има много библиотеки / услуги на трети страни, които могат да се използват за създаването му за вашето приложение. Използвайте ги и ги изградете върху всичко това.

Не забравяйте да изградите всички 3 функционалности:

  • Push Notifications (APNS + FCM),
  • Имейли (просто интегрирайте SMTP клиент за стартиране)
  • и SMS

ЗАБЕЛЕЖКА - Имате два канала за изпращане на SMS, транзакционен и промоционален. Никога не изпращайте промоционален SMS по транзакционен канал, тъй като има шанс да бъдете съден от добре информиран и мотивиран потребител.

Лесен начин за конфигуриране на вашия SMTP клиент във вашето приложение е използването на това в настройките ви:

Направих това в Django, но вие можете да направите същото на избрания от вас език и рамка.

Настройте регистриране на грешки

Използвайте междинен софтуер, за да регистрирате грешки, които възникват във вашата производствена система. Вашата производствена система няма да бъде наблюдавана от хора, които седят там, за да виждат дневниците на приложенията 24/7 Така че ще ви трябва система, която ще регистрира тези вътрешни грешки на сървъра на централно място. След това можете да ги проверявате ежедневно или да създадете уеб кука, за да можете да бъдете предупредени в точното време и да се грижите за тях.

На пазара има много инструменти за регистриране на грешки на трети страни. Просто изберете всеки, който отговаря на вашите изисквания. Използвам най-вече Sentry / Airbrake.

Помислете за конфигуриране на уеб куки, както споменах по-горе. Те ще информират вашите потребители за грешки и, например, можете да публикувате тези грешки, когато и когато се появят в определени отпуснати канали. След това можете да проверявате тези канали редовно и да ги коригирате въз основа на тяхната тежест.

Официалната начална страница на Airbrake - //airbrake.io/

Официалната начална страница на Sentry - //sentry.io/welcome/

Искане за внедряване - отговор и регистриране на приложения

Сценарий - Потребител идва на вашата поддръжка и казва, че не е получил транзакционната разписка за покупката, направена от вашия уебсайт. Какво ще направиш?

Ако сте сложили Регистрация на приложения във вашата система, тогава не се притеснявайте. Сега какво искам да кажа с това? Винаги е по-добре да покажете пример, отколкото да се опитвате да обяснявате с думи. Ето го:

Записах, че ще изпратя имейла на споменатия email_id. Мога да проверя в регистрационните файлове на приложението, за да видя дали имейлът всъщност е изпратен на клиента, като проверя дали такъв регистър съществува в системата. Не забравяйте да поставите изчерпателни дневници във вашата система, така че да можете да проследите пътуването на заявката.

Освен това е добра идея да поставите асинхронна система, която да избере такива журнали за отговор на заявки и приложения от вашата система и да ги изхвърли на централно място. Там те могат да бъдат обработени, за да бъдат по-лесно интерпретируеми.

Стекът ELK е добър вариант за това: ElasticSearch - Logstash - Kibana.

Повече за стека ELK - //www.elastic.co/what-is/elk-stack

ЗАБЕЛЕЖКА - Докато регистрирате заявка и отговори, се погрижете за следното:

  • Не регистрирайте пароли.
  • Не регистрирайте маркери (маркерите за достъп, които се използват за удостоверяване)
  • Не регистрирайте OTP

Въведете дроселиране във вашите API и ограничаване на скоростта на вашите сървъри за приложения

Сценарий - Току-що стартирахте вашата услуга и пуснахте продукта на пазара в социалните медийни платформи. Хакер на черна шапка разбра и просто искаше да играе с вашата система. Така че те планираха DOS (Отказ от обслужване) атака срещу вашата система.

За да се борите с това, можете да зададете ограничение на скоростта въз основа на различни фактори върху вашите балансиращи натоварвания за вашите сървъри за приложения. Това ще се погрижи за DOS атаки и ще предотврати злонамерения потребител да атакува сървърите ви.

Сценарий - Крайната точка на API / otp / валидиране, която отнема 4 цифрени OTP за удостоверяване на потребителя и връща маркери, които да се използват за удостоверени API. Злонамерен потребител получава mobile_number за един от вашите клиенти и започва да удря крайната точка на API с груба сила, променяща IP адресите, DDOS (Distributed Denial of Service) атака. Ограничителят на скоростта не е в състояние да спре потребителя, тъй като IP продължава да се променя с всяка направена заявка.

За да спрете това, можете да поставите дроселиране и на API, базирани на потребителя. Можете да конфигурирате колко заявки могат да бъдат отправени от даден потребител към крайна точка на API. За валидиране на OTP добър брой е 5 заявки за 10 минути. Това ще спре зловредния потребител да извърши DDOS атака с груба сила върху горния API.

Ограничаване в REST Framework на Django -

//www.django-rest-framework.org/api-guide/throttling/

Установете и конфигурирайте асинхронна комуникация от първия ден

Сценарий - Трябва да изпратите приветствено имейл до потребителя, когато той се регистрира във вашето приложение. Предният клиент удря API за регистрация, вие създавате потребителя в бекенда след валидиране и това стартира процеса на изпращане на имейл за приветствие.

Изпращането на този приветствен имейл ще отнеме време, може би няколко секунди. Но защо бихте искали мобилният клиент да заседне за такъв процес? Това може да се случи във фонов режим, без потребителят да е заседнал без особена причина на страницата за регистрация. Всяка секунда е ценна и не искате потребителят да загуби тези ценни секунди.

Така че просто изпратете имейла чрез асинхронна задача. Използвайте работници, задачи, брокери на съобщения и крайни резултати, за да извършите това.

Един добър пример за това от света на Python е работникът на целина. Просто поставете задачата, която трябва да бъде изпълнена, в посредник за съобщения (Rabbit MQ / SQS и т.н.). Целина ще чуе това и ще изпрати задачата на определения работник. След това този работник ще обработи заявката и ще постави резултата в бекенда на резултата, който може да бъде система за кеш / система от бази данни. (Redis / PostgreSQL например).

Можете да наблюдавате тези задачи и опашки с много библиотеки на трети страни. Добър пример за това е Целина от целина, която следи всичко това.

Можете да прочетете повече за RabbitMQ тук - //www.rabbitmq.com/

И целина - //docs.celeryproject.org/en/stable/django/first-steps-with-django.html

И накрая, Целина от целина - //flower.readthedocs.io/en/latest/

Настройте cron задания

Сценарий - Току-що пуснахте продукта си и трябва да изпратите препоръки до потребителите си за нови продукти на вашата платформа. Ще ги изпращате въз основа на историята на покупките им всеки уикенд.

Горната задача може лесно да бъде изпълнена с помощта на cron задача. Лесно се конфигурира във всяка рамка. Важното нещо, което трябва да имате предвид, е, че не трябва да поставяте задачите cron директно във файла crontab на вашия сървър. Трябва да оставите рамката да се справи.

Това е така, защото инженерът за внедряване / Devops инженер трябва да бъде единственият човек, който има достъп до системата като тази от съображения за сигурност. Въпреки че не е нужно да го прилагате по този начин, добре е да имате нещо от самото начало.

В света на Django можете да използвате celerybeat, за да конфигурирате вашите крони, като използвате работници от целина.

Научете повече за Celery Beat тук - // docs.celeryproject.org/en/latest/userguide/periodic-tasks.html

Управлявайте правилно тайните си (файл с параметри)

Има много начини за управление на тайните на параметрите във вашите производствени сървъри. Някои от тях са:

  • Създаване на файл с тайни и съхраняването му в частна s3 кофа и изтеглянето му по време на разполагането на вашето приложение.
  • Задаване на параметрите в променливи на околната среда по време на разполагането на вашето приложение (съхраняване отново в s3)
  • Поставяне на тайните в някаква услуга за управление на тайни (например //aws.amazon.com/secrets-manager/) и използване на тях, за да получите тайните във вашето приложение.

Можете да изберете всеки от тези методи според вашия комфорт и случай на употреба. (Можете да изберете да съхранявате различни секретни файлове и за локална, сценична и производствена среда.)

Версия на вашите приложни програмни интерфейси (API) от първия ден

Това е нещо, което определено трябва да обмислите от Ден 1. Никога няма да разберете колко често могат да се променят вашите бизнес модели и трябва да имате съвместимост напред-назад във вашето приложение. Така че трябва да версия на своите API, за да се гарантира, че всичко работи гладко за всички.

Можете да имате различни приложения за различни версии и да оставите nginx да се справя с него за вашето приложение. Или можете да имате създаване на версии в самото приложение и да оставите маршрутите в сървъра на приложенията да се справят. Можете да изберете всеки метод, за да го приложите - основната точка е да се активира версирането от самото начало.

Вземете решение за твърди и меки проверки на версиите за актуализация за вашите клиенти от предния край

И така, каква е разликата между твърди и меки актуализации?

Твърдите актуализации се отнасят, когато потребителят е принуден да актуализира версията на клиента до по-висок номер на версия от този, който е инсталиран на неговия мобилен телефон.

Меките актуализации се отнасят, когато на потребителя се покаже подкана, че е налична нова версия и той може да актуализира приложението си до новата версия, ако желае.

Твърдите актуализации не се насърчават, но има моменти, когато трябва да ги наложите. Какъвто и да е случаят, определено трябва да помислите как ще приложите това за вашите приложения.

Можете да направите това, като го внедрите или конфигурирате в Play Store или App Store. Друг начин е да създадете API във вашето бекенд приложение, което ще бъде ударено всеки път, когато мобилното приложение се стартира. Това ще изпрати два ключа: hard_update -> true / false и soft_update -> true / false, в зависимост от версията на потребителя и версиите за твърда и мека актуализация, зададени във вашата бекенд система.

Добро място за съхранение на тези версии е във вашия кеш (Redis / Memcache), който можете да промените в движение, без да е необходимо да разгръщате приложението си.

Въведете непрекъсната интеграция (CI) от първия ден

Сценарий - един от стажантите, работещи във вашия проект, не е достатъчно опитен, за да напише код на производствено ниво. Възможно е да са променили нещо, което може да наруши някакъв критичен компонент във вашия проект. Как можете да се уверите, че всичко е наред в такива случаи?

Въведете непрекъсната интеграция. Той ще стартира линтери и тестови казуси при всеки коммит и ще се счупи, ако има нарушени правила. Това от своя страна ще блокира заявката за изтегляне от обединяване, докато преминат всички правила за свързване и тестови случаи. Хубаво е да имаш нещо и всъщност помага и в дългосрочен план, така че имай го предвид.

На пазара има много опции. Можете или да изберете да внедрите сами (Jenkins CI / CD), или можете да използвате TravisCI, CircleCI и т.н. за същото.

Прочетете за TravisCI тук - //travis-ci.org/

И CircleCI - //circleci.com/

Активиране на поддръжката на Docker (лични предпочитания)

Създайте Dockerfile и docker-compose.yml за вашето приложение, така че всички да стартират приложението, използвайки Docker от самото начало. Една от основните причини да използвате такъв подход е да имате последователност във вашата локална / сценична / производствена среда, така че никой разработчик да не може да каже това отново:

Но тя работи на моята машина.

Не е трудно да го използвате от първия ден. В началото просто използвайте Docker за вашата локална среда, така че настройката на вашето приложение може да бъде наистина гладка. Но имайте предвид как можете да го стартирате както с Docker, така и без него.

Ето още информация за Docker Hub - //hub.docker.com/

Използвайте APM инструмент

Инструментът за мониторинг на приложения е задължителен, ако искате да наблюдавате приложните програмни интерфейси (API) на вашето приложение, транзакции, връзки с база данни и т.н.

Сценарий - твърдият диск на вашия cron сървър е почти пълен и не може да изпълнява cron задания. Тъй като не може да намери място на диска, вашите кронове не се изпълняват. И така, как можете да получите известие, когато това се случи?

Има много APM инструменти, които можете да използвате, за да наблюдавате това. Можете да ги конфигурирате според това кога трябва да бъдете уведомени. Ще получите известия на избрания от вас носител, когато такъв хаос се случи във вашата система - и повярвайте ми, това се случва през цялото време. Така че по-добре се подгответе за това. New Relic е добър вариант.

Прочетете повече за New Relic тук - //newrelic.com/

Използвайте ElasticSearch, за да активирате търсенията в цялото приложение във вашите клиентски приложения

Според wikipedia,

Elasticsearch е търсачка, базирана на библиотеката Lucene. Той осигурява разпределена, с възможност за мултитенант пълна машина за търсене на текст с HTTP уеб интерфейс и JSON документи без схеми. Elasticsearch е разработен в Java.

В началото ще се изкушите да използвате традиционни заявки към база данни, за да получите резултати в тази лента за търсене на клиентското приложение. Защо? Защото е лесно.

Но традиционните бази данни не са предназначени за такива ефективни заявки. Открийте подходящо време за мигриране на вашето търсене към ElasticSearch и въвеждане на конвейер за данни във вашата система. Той захранва еластичното търсене с данни и след това свързва търсенето от ElasticSearch със сървъра на приложения.

Ето един добър преглед на Elasticsearch, за да започнете.

И ElasticSearch Docs - //www.elastic.co/guide/index.html

Поставете защитна стена във вашия производствен сървър

Определено трябва да направите това - това е задължително. Поставете защитна стена във вашия производствен сървър и затворете всички портове, с изключение на тези, които ще се използват за API (https връзки). Насочете крайните точки на API с помощта на обратен прокси уеб сървър, като NGiNX или Apache. Никой порт не трябва да е достъпен за външния свят, освен разрешените от NGiNX.

Защо трябва да използвате NGiNX:

  • //www.nginx.com/resources/wiki/community/why_use_it/
  • //blog.serverdensity.com/why-we-use-nginx/
  • //www.freecodecamp.org/news/an-introduction-to-nginx-for-developers-62179b6a458f/

Обобщавайки

Горните точки се основават на моите собствени предпочитания и съм ги развивал през годините. Тук-там ще има малки разлики, но концепциите остават същите.

И накрая правим всичко това, за да имаме гладка система, изградена от нулата, работеща възможно най-скоро, след като сте измислили идеята.

Опитах да запиша всичките си знания, които съм придобил през годините, и може би греша на няколко места .Аз е, че можеш да предложи по-добра информация , моля, чувствайте се свободни да коментар. И както винаги, моля споделете, ако смятате, че това е полезно.