FastComments.com Blog
Wed Sep 10 2025
...

FastComments је сада глобално дистрибуирано

Шта је ново

Претходно је FastComments имао веома традиционалну архитектуру за веб апликацију. Имали смо сервере апликација, базе података и неке друге сервисе. Ово је било дуплирано у две регије (us-west и eu). Ако сте били у Француској и желели да видите низ коментара за клијента хостованог у нашем глобалном датацентру, ваш захтев би морао да иде све до us-west за податке о коментарима.

Више не! Сада се подаци о коментарима и сви медијски ресурси реплицирају глобално за клијенте у нашој глобалној имплементацији, а за клијенте у нашој EU имплементацији имамо три тачке присуства у ЕУ где се подаци репликују. Ваши захтеви иду до најближе чворе у ЕУ.

Како је раније радило

Осим база података које су имале неколико живих реплика у различитим регијама и кодних провајдерима, сви сервисе су били распоређени по једној инстанци за сваки тип сервиса. То је значило да за сваку регију имамо један сервер апликације, један pubsub сервер и један медијски сервер. План је био вертикално скалирање док год је то било могуће, јер је тако било једноставније. Писање кода је било лако – увек сте знали да можете „читати своја уписана података“ када се повежете са базом. Инфраструктура је била једноставна, осим безбедносних ажурирања која су захтевала минут времена без рада.

Проблем

Проблем је очигледно почео када смо достигли капацитет. Тако смо оптимизовали, а затим на крају морали повећати величину инстанце за тај сервис.

Ово је почело да постаје прескупо на Linode-у, где је инстанца од $144 приближно еквивалентна, према нашим passmark тестовима, $20 OVH чвору, а чак и ако променимо хостинг провајдере, имали бисмо један по један тачке отказа широм - а провајдери попут OVH имају дуже време решавања проблема у односу на Linode за проблеме одржавања.

RiR :)

Током првих неколико година PubSub и Media сервиси у FastComments били су написани у Java-у. Java је изабрана због релативно високе перформансе за уложени напор, а након година подешавања GC-а, испробавања G1GC, Shenandoah и Z1, одлучили смо да више не користимо Java. Паметни трошак меморије је био превише велики и пошто су ови сервиси били веома статични након завршетка, предности Java су се исцрпеле. Поред тога, ови сервиси су се често суочавали са проблемом „thundering herd“, што је значило да JVM покушава да управља врхунским саобраћајем док JIT још увек није активиран. Ови сервиси су били идеални кандидати за прелазак на C++ или Rust.

Rust је изабран јер нисмо C++ стручњаци, а грешка у мрежном коду могла би изложити податке једног клијента другом. Rust нам помаже да спречимо овакве проблеме.

Ипак, желели смо да консолидујемо ове сервисе, па иако смо могли да направимо још један пролаз оптимизације, можда са GraalVM, одлучили смо да пређемо на Rust и завршимо с тим.

Миграција није била без проблема. Ови сервиси морају да заврше SSL, подржавају HTTP 1.1, HTTP/2 и сл. Они управљају многим токовима података истовремено, читају медије из edge on-disk LRU кеша, S3, база података и комуницирају у мрежи. Java екосистема, Vertx и Netty, били су врло добри за ово. Гуримо библиотечку екосистему до граница, а недовољно искуства са Rust библиотекама значило је да смо имали пробе и грешке. То је изазвало неко време без рада, и извињавамо се због тога.

Такође смо експериментисали са различитим управљачима меморије, на крају се одлучивши за mimalloc за наше прилагођене DNS сервере и libc за транспортни слој. Не користимо Nginx или Apache, већ користимо сопствену комбинацију прилагођеног DNS сервера који глобално рутира клијенте на основу индекса у меморији који се поново гради сваке недеље из Maxmind, и наш транспортни слој у Rust-у који одржава мрежу са другим транспортним инстанцама. Транспорт завршава SSL, обрађује pubsub послове и представља наш CDN. Предност је мањи трошак приликом премештања између сервиса, и мањи инфраструктурни трошак/апстракција. Недостатак је видљивост, па су добри метрике важни.

Што се тиче перформанси, Rust сервиси су користили око 10-30% меморије у односу на Java сервисе, упркос свим нашим напорима. Читам књиге попут Java Concurrency in Practice за забаву, па иако нисам стручњак знам бар нешто о писању брзих JVM сервиса, и било је много лакше остварити ово у Rust-у. Поред тога, врхунци порука ка великом броју претплатника готово да се не примете у искоришћењу процесора када су JVM сервиси троšили 40% времена у GC, упркос томе што смо наш код писали више као играчки мотор, а мање као типичан сервер. Не могу рећи да сам велики фан Rust-а, али за сервисе који обављају много посла и не мењају се много након почетног развоја, то је савршено. Наш главни пословни логика остаје у TypeScript-у.

Нова архитектура

Нова архитектура више нема „пет" чворове. Уместо тога, сваки сервер је потпуни клон са свим истим сервисима и готово идентичном конфигурацијом. Сваки од њих покреће транспорт, DNS, сервер апликације и копију базе података. Сви чворови одржавају Full Disk Encryption са аутоматским откључавањем помоћу Dropbear.

Сваки сервер покреће routing транспорт који завршава захтеве и обрађује их као websocket, http stream или cdn захтев. Ови сервери се повезују међусобно и сваки од њих пружа мапирање глобалне мреже ка свом локалном DNS серверу како би DNS у реалном времену знао где се налази сваки живи чвор глобално.

Једна предност нове архитектуре је редунданција. Ако клијент у једној регији нападе наш систем јако, друге регије остају онлајн.

Апликациони код сада мора бити врло свестан које упите могу да погоде најближи чвор, а које морају ићи до примарне базе, која може бити далеко. Грешка може драстично смањити перформансе. Ово такође значи да уписи из неких регија могу бити спори, што захтева пажљиво подешавање и оптимизацију. Сада следимо унутрашњи образац у коду где све методе које приступају бази података узимају аргумент readPreference, тако да позивачи до врха морају експлицитно одлучити како ће упитати.

Предност је врло добро хоризонтално скалирање за читање. FastComments је веома оријентисан ка читању, али не смемо заборавити наше модераторе! Модератори раде дан за даном широм света и желимо да њихово искуство остане добро. Као део овог увођења радили смо са неколико њих како би алати за модерацију остали брзи.

Такође можемо ручно одабрати хардвер, што је забавно и награђујуће. Нови сервери су мешавина i5-13500 и Ryzen 5 5600X кутија, а EU користи неке старије Xeon-е. У нашим тестирањима, сви су били много бржи од скупљих сервера које смо испитивали код других провајдера. Недостатак је више посла за подешавање, али смо то аутоматизовали, заједно са SMART мониторингом диска за отказе и сл.

Урадом оваквих ствари можемо наставити да понудимо конкурентне цене.

Увођење

Увођење у последњих неколико месеци док преиначавамо сервисе и прелазимо на нове хостинг провајдере било је неравномерно, захваљујемо вам се на стрпљењу.

Током првог увођења наши метрики су показали повећање захтева који трају > 100ms. Трудимо се да не имамо превише захтева који трају толико дуго.

Gradual Progress
Slow Requests

Још увек правимо постепени напредак у побољшању перформанси за неке регије. Хвала свима који су до сада дали повратне информације.

Разматрања приликом коришћења API-ја

API остаје снажно конзистентан – можете читати своје уписе – како би се одржала компатибилност уназад и олакшало рад за програмере. Да бисмо омогућили програмерима да изаберу перформансе уместо конзистентности, планирамо да изложимо параметар readPreference. Предност је да можемо понудити попуст у кредитима за ове API позиве.

Сви јавни крајњи тачке, као што је испорука јавног коментарског виџета, увек читају из најближе (локалне) базе података на том чвору.

Зашто не користити обичан CDN

Низ коментара није статичан, он је жив, и примена живог стрима преко застарелих статичких података такође не функционише, јер када гледате низ као анонимни корисник добијате „анонимну сесију“. У овој анонимној сесији можете блокирати и означавати друге кориснике, и морате приказати да ли је анонимни корисник лајкао одређени коментар, и сл. Низови коментара могу бити закључани иза SSO, аутентификације или корисничких група.

На крају, врста „прогресивног унапређења“ где се динамички подаци мапирају на статичке податке са CDN-а даје лоше искуство где се садржај премешта или мења након неколико секунди. Волећемо да то не радимо.

Ко има моје податке сада

Ваши подаци више нису складишти на Linode-у. Они се репликују живо између Hetzner и OVH са пуном шифровањем диска, а сва комуникација између бекенд сервера се обавља преко TLS-а. Одржавамо неколико наследних Linode инстанци за излазне вебхук проксије, али ниједан податак или медиј није сачуван на Linode-у.

У закључку

Као и код свих великих издања, радује нас што смо успели да одвојимо време за оптимизацију, тестирање и правилно пуштање ове промене. FastComments ће се боље скалирати и имати бољу доступност на дуги рок захваљујући овом раду. Јавите нам испод ако откријете било какве проблеме.