Crediti: vettore tecnologico creato da pikisuperstar — www.freepik.com

Come sviluppatori, ci troveremmo spesso in situazioni in cui dobbiamo costruire qualcosa, ma non abbiamo tempo sufficiente per sviluppare nel modo che vorremmo. E non sempre possiamo anticipare i tempi, perché il “ time to market ” a volte gioca un ruolo cruciale nel successo del prodotto. Quindi cosa facciamo? Tagliamo scorciatoie, prendiamo rischi calcolati, lasciamo andare il purista che è in te (best practice, copertura dei test unitari e bla bla bla). Immagino che sarebbe terribilmente simile anche per la maggior parte di voi.

La storia di oggi parla di come abbiamo costruito un'alta scala , fault-tolerant , Distributed sistema Leaderboard / Segnare, in circa il tempo di una settimana in una squadra di tre persone.

Ci saranno principalmente questi secchi di apprendimento in questo blog

  1. Tecnico : come si costruisce effettivamente un tale sistema, devono essere trattati argomenti come la progettazione di sistemi distribuiti, la scalabilità, la resilienza, la disponibilità.
  2. Lavorare contro il tempo : come ottieni risultati in breve tempo, che tipo di compromesso fai, come prendere decisioni più velocemente.
  3. Ciclo di vita dello sviluppo : puoi anche dare una sbirciatina al ciclo di vita dello sviluppo del prodotto, che tipo di cose servono per creare un buon software.

Capitolo 1: I requisiti

Tutto è iniziato quando il nostro team di prodotto ha detto che era la stagione della Coppa del mondo T20 e volevamo creare un sistema di quiz per i nostri utenti, per la previsione a breve termine.

Il caso d'uso era che all'inizio di un over agli utenti sarebbe stato chiesto di prevedere uno scenario per il quale avrebbero avuto 20/30 secondi. E alla fine dell'over moderatore presenterà ciò che è realmente accaduto tra tutti gli scenari previsti. E il punteggio funzionerebbe in base a chi ha risposto correttamente e quanto tempo è stato impiegato per rispondere.

Quindi, subito dopo aver ottenuto il requisito, abbiamo fatto una stima dello sforzo e chiaramente non era adatto al nostro budget, quindi abbiamo tagliato le funzionalità che potevamo saltare sulla v0. Questo è importante perché in una scadenza ravvicinata potresti voler distribuire meno funzionalità rispetto a fornire funzionalità a metà.

Questo sarà principalmente un blog incentrato sul backend, mi dispiace non essere in grado di spiegare come sono state realizzate quelle bellissime interfacce utente.

Capitolo 2: Progettazione

Successivamente è stato ovviamente progettare il sistema, che è popolarmente noto come design di alto livello. Questa è stata la parte più impegnativa e anche la parte più divertente per me. Non abbiamo svolto un'estesa progettazione di basso livello e abbiamo preso tutte le chiamate di modellazione al volo durante l'implementazione.

Passaggio 1: stima della scala

Prima di iniziare qualsiasi cosa, abbiamo fatto una stima approssimativa del tipo di traffico che ci avrebbe colpito. Data la portata del nostro sistema, abbiamo stimato che forse 50k persone si impegneranno con il quiz. Quindi abbiamo deciso di creare per 100.000 utenti. Ma la maggior parte delle persone probabilmente risponderebbe nei primi 10 secondi in una finestra di 30 secondi. Il che ci dà all'incirca un qps target di 20k.

La mia regola empirica è per un nuovo sistema progettare sempre il sistema per il doppio del numero di utenti previsti. In modo che, nel caso in cui dovessi avere più utenti, il tuo sistema non mancherà di ridimensionarsi. E gli utenti generalmente crescono nel tempo, quindi non devi continuare a cambiare il sistema costantemente. Ma ciò non significa mettere il doppio dell'infrastruttura al posto di quella effettivamente richiesta. Per lo più avrei abilitato la scalabilità automatica nei miei sistemi, quindi ogni volta che ci sono picchi di traffico, il sistema si ridimensiona da solo.

(Abbiamo fatto anche altre stime sull'archiviazione nella cache, ma le abbiamo saltate per mantenere l'articolo breve)

Passaggio 2: identificazione di API su larga scala

Dopo la stima della scala abbiamo identificato rapidamente quali sono le API su larga scala e dove l'elaborazione potrebbe essere elevata in modo da poter eseguire selettivamente un progetto scalabile per quelle. Il resto delle API a bassa scala non ci interessava o su cui non passavamo molto tempo.

Quindi queste sono le API su larga scala che abbiamo identificato

  1. Ottieni punteggio utente e classifica
  2. Ottieni la classifica
  3. Calcola classifica (principalmente elaborazione dati non API)
  4. Pubblica la risposta dell'utente

Passaggio 3: considerazioni sulla progettazione

Subito dopo aver visto il requisito due cose mi sono state molto evidenti.

  1. Avremo bisogno di un'elaborazione asincrona e distribuita per il calcolo del punteggio e della classifica per i motivi più ovvi. Se hai intenzione di eseguire il calcolo del punteggio in modo sincrono su un singolo nodo per 1 milione di utenti o oltre, buona fortuna ??. L'idea è semplice, dividiamo una grande attività in attività più piccole e le eseguiamo su nodi diversi, lasciando che lo facciano al proprio ritmo. E vogliamo anche che questo processo sia tollerante ai guasti .
  2. Cache sarà nostro amico per la lettura dei ranghi di un utente e della classifica. Per due ragioni principalmente, velocità e facilità di ridimensionamento . Una cache è molto più veloce del DB per semplici operazioni di lettura e, in generale, è più facile ridimensionare il cluster Redis/ Memcached/ Hazelcast rispetto a Postgres .

Passaggio 4: progettare il sistema

Mentre prendevo le decisioni di progettazione questa volta, ho scelto di andare con le tecnologie che conoscevo e non volevo avventurarmi nella ricerca di quella che potrebbe essere la migliore tecnologia per questo caso d'uso. Ad esempio, avevo familiarità con Redis , quindi per la cache era la scelta più ovvia. Inoltre, ogni volta che sento la classifica, nella mia mente si traduce automaticamente in set ordinati Redis . E per l'elaborazione asincrona, Kafka rimane ancora la mia scelta numero uno. Dato il tempo giusto, probabilmente avrei fatto un po' più di esplorazione, ma per questa volta non mi sarei avventurato nelle terre selvagge per trovare la migliore tecnologia perché non avevo TEMPO!!!!

un. Pubblica l'API di risposta dell'utente

Quindi questa API avrebbe permesso ai nostri utenti di inviare le risposte per il quiz. La sfida principale qui era che questo avrebbe generato molte operazioni di scrittura simultanee , il che aumenterebbe molto il carico sul nostro database. Quindi abbiamo dovuto fare due cose

  1. Diminuisci il carico sul DB
  2. Genera una sorta di contropressione o lascia che gli operatori DB lavorino al proprio ritmo, in modo che il DB non sia sopraffatto

La mia soluzione goto per ridurre il carico di scrittura è eseguire il batch . Quindi, se dovessi eseguire 10 operazioni di scrittura, le farei in batch per ottenere una singola query e quindi eseguire 1 operazione di scrittura DB.

E la contropressione quasi grida messaggi in coda .

Quindi combinando entrambi, la soluzione che abbiamo trovato è questa...

Non impazzire, permettimi di spiegare cosa sta succedendo

  1. Le risposte dell'utente vengono ricevute dal destinatario della risposta e viene restituito un codice di stato HTTP 202. è come dire che ho ricevuto la tua richiesta e la elaborerò, ma tu vai avanti e fai quello che stavi facendo. Questo è il primo passo nell'elaborazione asincrona, che non blocchiamo il chiamante.
  2. Il destinatario della risposta inserisce la risposta dell'utente in una coda di messaggi, che viene nuovamente partizionata per scopi di scalabilità/disponibilità/ridondanza . Puoi capire il partizionamento abbastanza facilmente se conosci già Kafka. In caso contrario, consideralo un modo per distribuire i tuoi messaggi nella coda in più code isolate più piccole che tecnicamente possono risiedere su nodi diversi. Se conosci il DB sharding , è la stessa cosa, ma principalmente per le code di messaggi. Sentiti libero di leggere di più su Kafka qui .
  3. Ora, queste risposte non elaborate vengono ricevute dal batcher. E poi crea batch di 10 messaggi e li spinge alla fase di elaborazione successiva.
  4. Il DB writer preleva i batch ed effettua query di inserimento nel DB. La contropressione è introdotta principalmente dal writer DB, raccoglie i messaggi al proprio ritmo poiché il consumatore del messaggio era basato su pull . E quindi preveniamo il sovraccarico del DB. E poiché funziona su batch invece di eseguire 100 query DB, abbiamo eseguito solo 10 query DB.

Questo risolve il 30% del nostro problema, passiamo al prossimo.

B. Calcolo punteggio e classifica

Ora l'elefante nella stanza, il problema principale, il calcolo della classifica. Se vedi questo sistema, non è come un sistema di quiz tradizionale in cui conosciamo in anticipo la risposta corretta. Quindi non possiamo davvero calcolare i punteggi e la classifica non appena qualcuno risponde. Dobbiamo calcolare il punteggio e il grado di tutti gli utenti una volta che il moderatore ha inviato le risposte corrette. Quindi un'enorme mole di lavoro in un colpo solo. Abbastanza evidente che né i nostri nodi né il nostro server DB possono gestirlo correttamente in una sincronizzazionemoda. Quindi cosa facciamo? Torniamo al nostro amico Messages Queues per l'elaborazione asincrona di nuovo. Fantastico, così possiamo calcolare i punteggi in modo asincrono, ma per quanto riguarda la classifica? Deve essere sempre disponibile, giusto? E per quanto riguarda il rango? Fino a quando ea meno che non siano stati calcolati i punteggi per tutti gli utenti non puoi davvero mettere i ranghi, giusto? E calcolare il grado nello specifico potrebbe essere un problema difficile.

Ora, chi ci salverà da questo? Non preoccuparti amico mio, ricordi che ho menzionato brevemente Redis mentre parlavo di cache? Hanno una cosa bellissima chiamata set ordinato (che creazione straordinaria, grazie Redis Labs ??). In un set ordinato, puoi aggiungere chiavi con un punteggio e Redis lo ordinerà di conseguenza in O(log(N)) . Questo risolverà il nostro problema di classificazione ??. Ci consente anche di eseguire query di intervallo, come ad esempio dammi i primi 5 o ottieni il grado per una chiave specifica, e tutto ciò accade in O (log (N)). Questo è esattamente ciò di cui abbiamo bisogno qui.

Gli elementi vengono aggiunti a una tabella hash che associa gli oggetti Redis ai punteggi. Allo stesso tempo gli elementi vengono aggiunti a una lista di salto che mappa i punteggi agli oggetti Redis (quindi gli oggetti vengono ordinati per punteggio in questa "vista") — Interni del set ordinati

Bammmmmm anche il problema della classifica è risolto.

Va bene, non è facile, ero solo felice di essere riuscito a ottenere rapidamente una soluzione praticabile. Ora torniamo al nostro tavolo da disegno.

Sembra un po' intimidatorio no? Mi permetta di spiegare

  1. Non appena il moderatore invia la risposta corretta, viene inviato un messaggio di attivazione del calcolo del punteggio, che dà il via all'intera pipeline di elaborazione .
  2. Il batcher riceve il messaggio di trigger e genera una coppia di oggetti DB offset e limit a seconda di quante persone hanno risposto correttamente. Ad esempio, se 10 persone hanno risposto correttamente e la dimensione del batch è 5, verranno generati due oggetti (batch). Lotto 1 {scostamento: 0, limite: 5}, lotto 2 {scostamento: 5, limite 5}. Perché lo facciamo? In modo che possiamo eseguire l'elaborazione batch o eseguire query DB impaginate e non finiamo per chiamare il DB senza alcun limite. Quindi, se dovessi ottenere 1 milione di record dal DB, e lo facessi in un colpo solo, introdurrei molti problemi in molti punti. Quindi lo scomponiamo in parti più piccole ed eseguiamo query più piccole ma multiple, che restituirebbero un numero inferiore di righe.
  3. Il processore batch dell'utente ora riceverà questi messaggi batch ed eseguirà query DB di conseguenza. Il processore che riceve il messaggio {offset: 0, limit: 5}, otterrà i primi 5 ID utente dal DB (farà anche un'altra operazione batch ma è un po' difficile da spiegare qui, quindi saltare). E dopo questo è dove diciamo addio all'elaborazione batch e passiamo all'elaborazione in streaming . Perché il processore batch ora inserirà 5 ID utente nella coda che verrà elaborata dal processore successivo.
  4. Ora il calcolatore del punteggio utente riceve gli ID utente individuali, esegue la logica di punteggio per calcolare i punteggi utente individuali. Quindi eseguire 1 aggiornamento DB per modificare il punteggio utente. Quindi aggiorna il punteggio per quel particolare utente nel set ordinato e Redis assegna o aggiorna internamente il grado. E una volta terminata l'elaborazione di questa fase avremo i punteggi di tutti gli utenti nel nostro DB e il grado + punteggio di tutti gli utenti nel nostro Redis. E poiché abbiamo il grado di tutti nel set ordinato, potremmo semplicemente eseguire una query di intervallo su di esso per ottenere la classifica con una velocità incredibile .

La maggior parte del nostro problema è stato risolto ora poiché per ottenere il punteggio e il ranking dell'utente potremmo semplicemente fare una query Redis e non raggiungere il DB. E questo velocizza anche i nostri tempi di risposta .

Questo conclude la fase di progettazione primaria. C'erano anche DB, progettazione API e altre cose che sto saltando qui.

Capitolo 4: Attuazione

Il completamento della progettazione ha risolto il 70% dei nostri problemi e sapevamo di poterlo risolvere, quindi saremmo passati rapidamente allo sviluppo.

In un mondo ideale, vorrei creare un nuovo servizio, provare un nuovo linguaggio come Go , per un'elaborazione parallela migliore e più veloce e altre cose. Ma data la tempistica, non era la cosa giusta da fare. Siamo rimasti fedeli al nostro servizio NodeJS di base e abbiamo messo tutto lì. I puristi dei microservizi potrebbero perderlo dopo aver visto questa affermazione, ma in una corsa contro il tempo, i tuoi dirigenti a volte devono passare in secondo piano. Tra i tanti compromessi , questa è stata una delle maggiori chiamate che abbiamo preso.

A parte questo, abbiamo anche dovuto ridurre i test unitari e di integrazione , la cui colpa ci perseguita ancora. Ma stiamo riempiendo gradualmente i test dopo il rilascio.

Immagino che dopo aver visto il design dettagliato pubblicato sopra dovresti essere in grado di implementare il tuo, quindi questa volta non farò un'immersione profonda del codice ??

Capitolo 5: Distribuzione e monitoraggio

Dopo alcune correzioni di bug e l'approvazione del QA, eravamo a posto. Lavoro fatto bene? No, amico mio, abbiamo ancora dovuto impostare un monitoraggio pesante per questo pezzo. Dal momento che è stato sviluppato in un tempo molto breve, almeno ero un po' poco sicuro di me. Per impostazione predefinita, la traccia era abilitata su questo servizio tramite LightStep . Quindi, a parte le tracce, avevo impostato un monitoraggio dedicato del traffico, tassi di errore, dashboard di latenza, avvisi per tutte le API. E dopo il go-live, io e i miei compagni di squadra, abbiamo ricevuto una chiamata e abbiamo monitorato il sistema in entrata e in uscita per almeno un'ora, dall'utilizzo della RAM e della CPU ai registri degli errori . Quindi date sempre uguale peso all'osservabilitàe anche il monitoraggio. Ci sono stati piccoli problemi nel sistema di produzione e siamo stati in grado di rilevarli in anticipo solo grazie al monitoraggio.

Capitolo 6: Retrospettiva

Il sistema funziona, ma dopo una pausa è importante fare una retrospettiva e identificare le cose che ci sono sfuggite e lavorarci sopra. Sono sicuro che abbiamo perso un sacco di cose e tagliato molte curve e ottenuto un enorme margine di miglioramento. Ad esempio, ecco un paio di...

Cose che potremmo fare di meglio

  1. Per questo abbiamo utilizzato il database Postgres già esistente poiché il driver, l'ORM e l'infrastruttura di supporto erano già presenti. Ma probabilmente esplorerei un po' le soluzioni di database.
  2. NodeJS è fantastico, ma sento che Go sarebbe una soluzione migliore per questo. Avremmo potuto esplorare questo.
  3. Ho provato a scrivere una query per calcolare il punteggio solo nel DB e ho fallito miseramente. Probabilmente potrei scriverlo e potrei anche eseguire l'elaborazione batch per il calcolo del punteggio, riducendo ulteriormente le operazioni DB.
  4. Non abbiamo potuto eseguire test approfonditi di carico e prestazioni, il che è un must.
  5. Avremmo potuto scrivere due diverse fasi per l'aggiornamento del punteggio DB e l'aggiornamento del set ordinato Redis, che sarebbe un'implementazione più pulita.

Note di addio

Abbiamo fatto del nostro meglio in quel poco tempo. Anche l'implementazione si è leggermente discostata dal design originale. Ma va bene, i compromessi ci saranno costantemente. Anche se abbiamo completato la funzionalità di base in circa una settimana, c'erano piccole patch che dovevamo pubblicare.

Spero che oggi tu sia riuscito a imparare qualcosa sulla progettazione di sistemi e sullo sviluppo del software ??

Titoli di coda

Un saluto ai miei fantastici compagni di squadra Akash Raj e Aashirwad Kashyap , abbiamo lavorato tutti insieme per costruirlo in circa una settimana.

Grazie per aver letto!

Sono Aritra Das, sono uno sviluppatore e mi piace molto costruire sistemi distribuiti complessi. Sentiti libero di contattarmi su Linkedin o Twitter per qualsiasi cosa relativa alla tecnologia.

Buon apprendimento...

Suggested posts

Dovresti randomizzare il tuo flusso di lavoro, ed ecco perché

Sono una di quelle persone che cercano costantemente il modo migliore per fare le cose. Planning, Pomodoro, To-Do list, Scheduling... lo chiami, probabilmente l'ho provato.

5 termini da conoscere nell'analisi delle serie temporali

Una parte fondamentale della scienza dei dati

5 termini da conoscere nell'analisi delle serie temporali

Una serie temporale è una sequenza di osservazioni o misurazioni ordinate nel tempo. La prima immagine che viene in mente quando si parla di serie temporali sono solitamente i prezzi delle azioni.

Related posts

Non sei un UX Designer migliore se sei un empatico

Non sei un UX Designer migliore se sei un empatico

Innanzitutto, analizziamo cos'è un empatico. La psicologia pop e i media virali hanno propagato questa idea che ci siano narcisisti, persone egoiste che sono spesso abusive, di cui noi brave persone dobbiamo stare attenti.

Recensione eJPT — La mia prima certificazione Pentesting

Recensione eJPT — La mia prima certificazione Pentesting

Introduzione: essendo nella comunità della sicurezza informatica da oltre un anno, mi sono reso conto che si impara molto dalla lettura di post come questo e dal prendere decisioni cruciali come scegliere la prima certificazione in assoluto o una tabella di marcia per ottenere un ruolo specifico nella sicurezza o ovunque nell'IT ho deciso di iniziare a scrivere delle mie certificazioni e delle esperienze in cui mi cimenterò d'ora in poi per restituire alla comunità in modo che le persone come me possano trarne beneficio Background Attualmente sono un finale anno Studente di Elettronica e Comunicazioni. La pandemia ha davvero giocato un ruolo molto importante nella mia vita in quanto mi ha aiutato a esplorare per vedere cosa mi piace ed è stato allora che ho scoperto la sicurezza informatica e ho capito immediatamente che era lì che avrei voluto vedere me stesso.

Potenza di GPT-3

Rapporto intermedio completo delle mie esplorazioni GPT-3 finora. Sarà continuamente aggiornato.

Potenza di GPT-3

Finalmente! GPT-3 senza lista d'attesa. Sì, lo hai letto correttamente.

Lancio di Umeeverse Genesis — Chiamata a tutti i sostenitori di Umee!

Lancio di Umeeverse Genesis — Chiamata a tutti i sostenitori di Umee!

Ieri, la rete Umee ha annunciato la vendita ufficiale di Coinlist. Come blockchain di livello base, siamo entusiasti di costruire insieme alla community mentre lanciamo questo hub DeFi a catena incrociata.

MORE COOL STUFF

Mike Krzyzewski, allenatore di basket dei Duke Blue Devils, è sposato?

Mike Krzyzewski, allenatore di basket dei Duke Blue Devils, è sposato?

Il ritiro di Mike Krzyzewski dal basket Duke alla fine della stagione in corso gli darà più tempo con sua moglie e la sua famiglia.

Quanto è alto Nicholas Braun di "Succession"?

Quanto è alto Nicholas Braun di "Succession"?

I fan di "Succession" non possono fare a meno di notare l'altezza insolitamente alta di Greg aka Nicholas Braun. Torreggia davvero sopra i suoi membri del cast?

Contorni del Ringraziamento di Ree Drummond "The Pioneer Woman" per le festività natalizie 2021

Contorni del Ringraziamento di Ree Drummond "The Pioneer Woman" per le festività natalizie 2021

La Pioneer Woman Ree Drummond è qui per prepararti per il Ringraziamento. Ecco alcuni dei suoi migliori contorni.

'90 Day Fiancé': aggiornamento sullo stato della relazione di Mike Youngquist mentre la moglie separata Natalie flirta in 'The Single Life'

Natalie è in '90 Day: The Single Life', ma cosa sta facendo Mike Youngquist? Ecco cosa sappiamo dello stato attuale della relazione di Mike.

Prova il nostro mini cruciverba

Prova il nostro mini cruciverba

Aggiornato settimanalmente, il nostro mini cruciverba combina le nostre letture HowStuffWorks preferite con indizi intelligenti!

Quale funziona meglio: cialde per bucato, detersivi in ??polvere o liquidi?

Quale funziona meglio: cialde per bucato, detersivi in ??polvere o liquidi?

Fare il bucato è già abbastanza brutto senza doversi preoccupare di scegliere il detersivo giusto. Quindi qual è il migliore? O ha anche importanza?

La vera storia del popolo blu del Kentucky

La vera storia del popolo blu del Kentucky

Le famiglie Fugates e Combs nel Kentucky rurale hanno perso la lotteria genetica, condividendo entrambe un raro tratto recessivo che ha reso la loro pelle blu quando si sono sposati. Qual è stata la causa di ciò? E cosa è successo alle famiglie?

La "nascita vergine" del condor californiano potrebbe salvare la specie?

Due pulcini maschi senza padre vengono allevati in un programma per salvare il condor della California dall'estinzione. Come sono possibili tali nascite "vergini"?

Presto, ci sarà Hanzo Mains in Heroes Of The Storm

Presto, ci sarà Hanzo Mains in Heroes Of The Storm

Heroes of the Storm Malato di tutte quelle condutture di Hanzo che stanno distruggendo la tua classifica competitiva di Overwatch? Bene, ora non puoi schivarli in Heroes of the Storm. Sta per emergere una nuova razza di Hanzo main.

Benvenuti alla Gizmodo Senior Week (We're Drunk !!!)

Benvenuti alla Gizmodo Senior Week (We're Drunk !!!)

Hai mai cliccato su un post di Gizmodo e ti sei chiesto se fosse stato scritto da un diciassettenne? Sei il commentatore che ha recentemente scritto "fanculo questo sito è gizmodo gestito da bambini? Fanculo questa merda e fottiti tutti ”? In effetti, Gizmodo impiega solo un adolescente in buona fede. Ma questa settimana, stiamo tutti abbracciando una gioia di vivere giovanile per la nostra primissima (e probabilmente ultima!) Settimana Senior alla Gawker Media.

Per $ 125.000 puoi comprare a tuo figlio un monster truck in miniatura

Per $ 125.000 puoi comprare a tuo figlio un monster truck in miniatura

Sappiamo tutti cosa significa rovinato, ma per la definizione più vera della parola non è necessario guardare oltre questo monster truck in miniatura progettato per i bambini che è alimentato da un vero motore Ford a quattro cilindri che lo spinge a una velocità massima di 25 miglia all'ora. è grande circa la metà dei veri monster truck come Bigfoot e Grave Digger, ed è costruito su misura con un telaio in tubo d'acciaio da due pollici senza cuciture che è abbastanza forte da resistere a incidenti e ribaltamenti.

La produzione automobilistica americana si sta lentamente spostando in Messico

La produzione automobilistica americana si sta lentamente spostando in Messico

Buongiorno! Benvenuto in The Morning Shift, la tua carrellata delle notizie automobilistiche che desideri, tutte in un unico posto ogni mattina nei giorni feriali. Ecco le storie importanti che devi sapere.

La figlia Kulture di Cardi B e Offset mostra bellissime nuove trecce su Instagram

La figlia Kulture di Cardi B e Offset mostra bellissime nuove trecce su Instagram

La figlia di 3 anni di Cardi B e Offset, Kulture, ha mostrato la sua nuova acconciatura intrecciata su Instagram.

Selena Gomez dà a Cara Delevingne un bacio sulla guancia per Kiss Cam al Knicks Game

Selena Gomez dà a Cara Delevingne un bacio sulla guancia per Kiss Cam al Knicks Game

"è così divertente ed è estremamente avventurosa", ha detto in precedenza Selena Gomez dell'amica Cara Delevingne

Madonna beve Gin dalla bottiglia nella sua palestra: "L'allenamento di oggi"

Madonna beve Gin dalla bottiglia nella sua palestra: "L'allenamento di oggi"

La cantante ha deciso di cambiare la sua routine di fitness giovedì

Jamie Dornan dice di aver perso il ruolo di Superman con Henry Cavill e si è avvicinato alla Marvel per un ruolo da supereroe

Jamie Dornan dice di aver perso il ruolo di Superman con Henry Cavill e si è avvicinato alla Marvel per un ruolo da supereroe

Jamie Dornan ha rivelato di aver fatto il provino per il ruolo di Superman ma ha perso contro Henry Cavill; e ha parlato con la Marvel dell'adesione all'MCU.

Languages

野花在线观看免费观看大全-野花视频在线观看免费观看8
国足最新出线概率0.08% 北京冬奥火炬宣传片获金花环奖 速度与激情9 得知母亲出事男子在地铁痛哭 国足战澳大利亚大名单:4归化在列 周冠宇成为中国首位F1车手 安娜贝尔 尚气与十环传奇 胡锡进谈中美元首会晤 红色通缉令 尚气与十环传奇 印度首都准备封城 房价上涨城市创七年新低 拐点来了? 24岁救人牺牲消防员获批为烈士 扫黑风暴 我要我们在一起 意大利错失直接晋级世界杯资格 中美元首会谈重点内容 中国共产党第三个历史决议全文发布 灵媒 意大利错失直接晋级世界杯资格 俄方回应卫星碎片危及国际空间站 中美元首是否达成新共识?中方回应 男子写80页PPT拯救爱情却离婚 动保组织向上饶信州区申请信息公开 许家印为恒大注入超70亿续命资金 动保组织向上饶信州区申请信息公开 千与千寻 意大利错失直接晋级世界杯资格 两个女人 浦发银行回应近3亿存款莫名被质押 罗永浩吐槽苹果文案没文化 大连现超级传播者26人在同一传播链 扫黑风暴 安娜贝尔 中美元首会谈重点内容 长津湖 图兰朵 24岁救人牺牲消防员获批为烈士 房价上涨城市创七年新低 拐点来了? 五个扑水的少年 大连一密接者擅自点外卖聚餐被调查 男子写80页PPT拯救爱情却离婚 #耿直真香哥黑化卖惨# 动保组织向上饶信州区申请信息公开 扫黑风暴 失控玩家 扫黑风暴 许家印为恒大注入超70亿续命资金 外交部回应拜登重申不支持台独 加拿大一枝黄花到底是什么? 中国医生 男子体检血中抽出2升油浆 红色通缉令 大连现超级传播者26人在同一传播链 国际人士热议中共十九届六中全会 俄方回应卫星碎片危及国际空间站 怒火·重案 得知母亲出事男子在地铁痛哭 嘉南传 中美元首是否达成新共识?中方回应 浦发银行回应近3亿存款莫名被质押 斗破苍穹 蜘蛛侠:英雄归来 扫黑风暴 林丹世界排名被正式移除 男子体检血中抽出2升油浆 大连现超级传播者26人在同一传播链 扫黑风暴 林丹世界排名被正式移除 国足战澳大利亚大名单:4归化在列
三穗县| 自贡市| 望谟县| 拉萨市| 三台县| 淮阳县| 石楼县| 明水县| 镇江市| 泰宁县| 龙口市| 临沂市| 孟津县| 鄂伦春自治旗| 武冈市| 海宁市| 彩票| 商水县| 尼勒克县| 靖边县| 丰县| 宜川县| 康平县| 江门市|