Crédits : vecteur technologique créé par pikisuperstar — www.freepik.com

En tant que développeurs, nous nous retrouvons souvent dans des situations où nous devons construire quelque chose, mais nous n'avons pas suffisamment de temps pour développer comme nous le souhaiterions. Et on ne peut pas toujours repousser les délais, car le ? time to market ? joue parfois un r?le crucial dans le succès du produit. Alors que faisons-nous? Nous prenons des raccourcis, prenons des risques calculés, abandonnons le puriste en vous (meilleures pratiques, couverture des tests unitaires et bla bla bla). Je suppose que ce serait terriblement similaire pour la plupart d'entre vous aussi.

L'histoire d'aujourd'hui est sur la fa?on dont nous avons construit une haute échelle , à tolérance de pannes , distribué système Leaderboard / Marquer un point, dans le temps de environ une semaine dans une équipe de trois personnes.

Il y aura principalement ces seaux d'apprentissage dans ce blog

  1. Technique : Comment construisez-vous réellement un tel système, des sujets tels que la conception de système distribué, l'évolutivité, la résilience, la disponibilité doivent être couverts.
  2. Travailler contre le temps : comment vous livrez en peu de temps, quel type de compromis vous faites, comment prendre des décisions plus rapidement.
  3. Cycle de vie du développement : vous obtenez également un aper?u du cycle de vie du développement du produit, du genre de choses qui entrent dans la création d'un bon logiciel.

Chapitre 1 : Les exigences

Tout a commencé lorsque notre équipe produit a annoncé que c'était la saison de la coupe du monde T20 et que nous voulions créer un système de quiz pour nos utilisateurs, pour des prédictions à court terme.

Le cas d'utilisation était qu'au début d'un over, les utilisateurs seraient invités à prédire un scénario pour lequel ils auraient 20/30 secondes. Et à la fin, le modérateur soumettra ce qui s'est réellement passé parmi tous les scénarios prévus. Et la notation fonctionnerait en fonction de qui a répondu correctement et du temps qu'il a fallu pour répondre.

Donc, immédiatement après avoir obtenu l'exigence, nous avons fait une estimation de l'effort et cela ne correspondait clairement pas à notre budget, nous avons donc supprimé des fonctionnalités que nous pouvions ignorer sur la v0. Ceci est important car dans un délai serré, vous voudrez peut-être donner moins de fonctionnalités que de donner des fonctionnalités à moitié cuites.

Ce blog sera principalement axé sur le backend, désolé, je ne pourrai pas expliquer comment ces belles interfaces utilisateur ont été créées.

Chapitre 2 : Conception

Ensuite, il s'agissait évidemment de concevoir le système, communément appelé High-Level Design. C'était la partie la plus difficile ainsi que la partie la plus amusante pour moi. Nous n'avons pas fait de conception de bas niveau étendue et avons pris tous les appels de modélisation à la volée lors de la mise en ?uvre.

étape 1 : Estimation de l'échelle

Avant de commencer quoi que ce soit, nous avons fait une estimation approximative du type de trafic qui allait nous frapper. Compte tenu de l'ampleur de notre système, nous avons estimé que peut-être 50 000 personnes participeront au quiz. Nous avons donc ciblé la création pour 100 000 utilisateurs. Mais la plupart des gens répondraient probablement dans les 10 premières secondes d'une fenêtre de 30 secondes. Ce qui nous donne à peu près un qps cible de 20k.

Ma règle d'or est qu'un nouveau système con?oive toujours le système pour deux fois le nombre d'utilisateurs prévus. Ainsi, si vous finissez par avoir plus d'utilisateurs, votre système ne manquera pas de s'adapter. Et les utilisateurs grandissent généralement avec le temps, vous n'avez donc pas à changer constamment le système. Mais cela ne signifie pas que vous mettez deux fois l'infrastructure à la place de ce qui est réellement nécessaire. J'aurais principalement activé la mise à l' échelle automatique dans mes systèmes, donc chaque fois qu'il y a des pics de trafic, le système se met à l'échelle.

(Nous avons également fait d'autres estimations quant au stockage sur le cache, mais nous les avons ignorées pour garder l'article court)

étape 2 : Identification des API à grande échelle

Après l'estimation à l'échelle, nous avons rapidement identifié quelles sont les API à grande échelle et où le traitement pourrait être élevé afin que nous puissions faire de manière sélective une conception évolutive pour celles-ci. Le reste des API à petite échelle ne nous importait pas ou nous ne passions pas beaucoup de temps.

Voici donc les API à grande échelle que nous avons identifiées

  1. Obtenez le score et le classement des utilisateurs
  2. Obtenir le classement
  3. Calculer le classement (principalement le traitement des données et non l'API)
  4. Publier la réponse de l'utilisateur

étape 3 : Considérations relatives à la conception

Immédiatement après avoir vu l'exigence, deux choses étaient très évidentes pour moi.

  1. Nous allons avoir besoin d' un traitement asynchrone et distribué pour le calcul du score et du classement pour les raisons les plus évidentes. Si vous prévoyez d'exécuter le calcul du score de manière synchrone sur un seul n?ud pour 1 million d'utilisateurs ou au-delà, bonne chance à vous ??. L'idée est simple, nous divisons une grosse tache en taches plus petites et les exécutons sur différents n?uds, et les laissons faire à leur propre rythme. Et nous voulons également que ce processus soit tolérant aux pannes .
  2. Cache va être notre ami pour lire les rangs d'un utilisateur et le classement. Pour deux raisons principalement, la vitesse et la facilité de mise à l'échelle . Un cache est beaucoup plus rapide que DB pour les opérations de lecture simples et, en général, il est plus facile de faire évoluer le cluster Redis/ Memcached/ Hazelcast que Postgres .

étape 4 : Concevoir le système

En prenant les décisions de conception cette fois, j'ai choisi d'opter pour des technologies que je connaissais et que je ne voulais pas m'aventurer à trouver quelle pourrait être la meilleure technologie pour ce cas d'utilisation. Par exemple, je connaissais Redis , donc pour le cache, c'était le choix évident. De plus, chaque fois que j'entends le classement, il se traduit automatiquement en ensembles triés Redis dans mon esprit. Et pour le traitement asynchrone, Kafka reste toujours mon choix numéro un. Avec le temps, je ferais probablement un peu plus d'exploration, mais pour cette fois, je n'allais pas me promener dans les terres sauvages pour trouver la meilleure technologie parce que je n'avais pas le TEMPS !!!!

une. API de réponse post-utilisateur

Cette API allait donc permettre à nos utilisateurs de soumettre des réponses au quiz. Le principal défi ici était que cela générerait de nombreuses opérations d'écriture simultanées , ce qui augmenterait considérablement la charge de notre base de données. Nous avons donc d? faire deux choses

  1. Diminuer la charge sur la base de données
  2. Générer une sorte de contre-pression ou laisser les opérateurs DB travailler à leur propre rythme, afin que la DB ne soit pas submergée

Ma solution goto pour diminuer la charge d'écriture est de faire du traitement par lots . Donc, si je devais effectuer 10 opérations d'écriture, je les regrouperais pour obtenir une seule requête, puis exécuterais 1 opération d'écriture de base de données.

Et la contre -pression crie presque des files d'attente de messages .

Donc en combinant les deux, la solution que nous avons trouvée est la suivante…

Ne paniquez pas, permettez-moi d'expliquer ce qui se passe

  1. Les réponses des utilisateurs sont re?ues par le récepteur de réponses et un code d'état HTTP 202 est renvoyé. Ce qui revient à dire que j'ai re?u votre demande et que je vais la traiter, mais continuez et faites ce que vous faisiez. C'est la première étape du traitement asynchrone, que nous ne bloquons pas l'appelant.
  2. Le récepteur de réponse place la réponse de l'utilisateur dans une file d'attente de messages, qui est à nouveau partitionnée à des fins d' évolutivité/disponibilité/redondance . Vous pouvez comprendre le partitionnement assez facilement si vous connaissez déjà Kafka. Au cas où vous ne le feriez pas, considérez simplement qu'il s'agit d'un moyen de distribuer vos messages dans votre file d'attente en plusieurs files d'attente isolées plus petites qui peuvent techniquement résider sur différents n?uds. Si vous connaissez le sharding de base de données, c'est la même chose mais principalement pour les files d'attente de messages. N'hésitez pas à en savoir plus sur Kafka ici .
  3. Maintenant, ces réponses brutes sont re?ues par le batcher. Ensuite, il crée des lots de 10 messages et les pousse à l'étape de traitement suivante.
  4. Le rédacteur de la base de données récupère les lots et effectue des requêtes d'insertion dans la base de données. La contre-pression est principalement introduite par le rédacteur de la base de données, il récupère les messages à son propre rythme puisque le consommateur de messages était basé sur le pull . Et ainsi, nous évitons la surcharge de la base de données. Et comme il fonctionne par lots au lieu d'exécuter 100 requêtes DB, nous n'avons exécuté que 10 requêtes DB.

Cela résout 30% de notre problème, passons au suivant.

b. Calcul du score et du classement

Maintenant, l'éléphant dans la salle, le problème majeur, le calcul du classement. Si vous voyez ce système, ce n'est pas comme un système de quiz traditionnel où nous connaissons la bonne réponse à l'avance. Nous ne pouvons donc pas vraiment calculer les scores et le classement dès que quelqu'un répond. Nous devons calculer le score et le classement de tous les utilisateurs une fois que le modérateur a soumis les bonnes réponses. Donc une énorme quantité de travail d'un seul coup. Assez évident que ni nos n?uds ni notre serveur de base de données ne peuvent gérer cela correctement dans une synchronisationmode. Alors que faisons-nous? Nous retournons à notre ami Messages Queues pour un nouveau traitement asynchrone. Cool donc on peut calculer les scores de manière asynchrone, mais qu'en est-il du classement ? Cela doit être disponible tout le temps, n'est-ce pas ? Et qu'en est-il du classement ? Tant que les scores de tous les utilisateurs n'ont pas été calculés, vous ne pouvez pas vraiment mettre de classement, n'est-ce pas ? Et calculer le rang en particulier pourrait être un problème difficile.

Maintenant, qui va nous sauver de ?a ? Ne vous inquiétez pas mon ami, rappelez-vous que j'ai brièvement mentionné Redis en parlant de cache ? Ils ont une belle chose appelée ensemble trié (quelle création incroyable, merci Redis Labs ??). Dans un ensemble trié, vous pouvez ajouter des clés avec une partition, et Redis l'ordonnera en conséquence dans O(log(N)) . Cela réglera notre problème de classement ??. Cela nous permet également d'exécuter des requêtes de plage, telles que me donner le top 5, ou me donner le rang pour une clé spécifique, et tout cela se passe en O(log(N)). C'est exactement ce dont nous avons besoin ici.

Les éléments sont ajoutés à une table de hachage mappant les objets Redis aux scores. Dans le même temps, les éléments sont ajoutés à une liste de sauts mappant les scores aux objets Redis (les objets sont donc triés par scores dans cette ? vue ?) — Internes de l'ensemble trié

Bammmmmm le problème du classement est également résolu.

Très bien, ce n'est pas facile, j'étais juste heureux d'avoir pu obtenir une solution viable rapidement. Revenons maintenant à notre planche à dessin.

?a a l'air un peu intimidant non ? Permettez-moi d'expliquer

  1. Dès que le modérateur soumet la bonne réponse, un message de déclenchement de calcul de score est envoyé, ce qui lance l'ensemble du pipeline de traitement .
  2. Le batcher re?oit le message de déclenchement et génère une paire d'objets de décalage et de limite de base de données en fonction du nombre de personnes ayant répondu correctement. Par exemple, si 10 personnes ont répondu correctement et que la taille du lot est de 5, cela générera deux objets (lots). Lot 1 {décalage : 0, limite : 5}, lot 2 {décalage : 5, limite 5}. Pourquoi faisons-nous cela? Afin que nous puissions exécuter un traitement par lots ou exécuter des requêtes de base de données paginées et que nous ne finissions pas par appeler la base de données sans aucune limite. Donc, si je devais obtenir 1 million d'enregistrements de la base de données, et que je le fasse d'un seul coup, cela introduirait beaucoup de problèmes dans de nombreux endroits. Nous décomposons donc cela en plus petits morceaux et exécutons des requêtes plus petites mais multiples, ce qui renverrait un plus petit nombre de lignes.
  3. Le processeur de traitement par lots de l'utilisateur recevra désormais ces messages par lots et exécutera les requêtes de base de données en conséquence. Le processeur qui re?oit le message {offset: 0, limit: 5} obtiendra les 5 premiers identifiants d'utilisateurs de la base de données (il effectuera également une autre opération par lots, mais c'est un peu difficile à expliquer ici, donc sautez). Et après c'est là que nous disons au revoir au traitement par lots et passons au traitement par flux . Parce que le processeur par lots mettra maintenant 5 identifiants d'utilisateur dans la file d'attente qui seront traités par le processeur suivant.
  4. Désormais, le calculateur de score utilisateur re?oit des identifiants utilisateur individuels, exécute la logique de notation pour calculer les scores utilisateur individuels. Faites ensuite 1 mise à jour DB pour modifier le score de l'utilisateur. Il met ensuite à jour le score de cet utilisateur particulier dans l'ensemble trié, et Redis attribue ou met à jour le classement en interne. Et une fois cette étape terminée, nous aurons les scores de tous les utilisateurs de notre base de données et le classement + score de tous les utilisateurs de notre Redis. Et puisque nous avons le rang de tout le monde dans l'ensemble trié, nous pourrions simplement exécuter une requête de plage dessus pour obtenir le classement à une vitesse fulgurante .

La plupart de nos problèmes sont maintenant résolus car pour obtenir le score et le classement de l'utilisateur, nous pourrions simplement faire une requête Redis et ne pas atteindre la base de données. Et cela accélère également nos temps de réponse .

Ceci conclut la phase de conception primaire. Il y avait aussi la base de données, la conception d'API et d'autres choses que je saute ici.

Chapitre 4 : Mise en ?uvre

L'achèvement de la conception a résolu 70% de nos problèmes, et nous savions que nous pouvions résoudre ce problème, nous passerions donc rapidement au développement.

Dans un monde idéal, j'irais créer un nouveau service, essayer un nouveau langage tel que Go , pour un traitement parallèle meilleur et plus rapide et d'autres choses. Mais compte tenu du calendrier, ce n'était pas la bonne chose à faire. Nous sommes restés fidèles à notre service NodeJS de base et y avons tout mis. Les puristes des microservices pourraient le perdre après avoir vu cette déclaration, mais dans une course contre la montre, vos directeurs doivent parfois passer au second plan. Parmi les nombreux compromis , c'était l'un des appels majeurs que nous avons pris.

En dehors de cela, nous avons également d? réduire les tests unitaires et d'intégration , dont la culpabilité nous hante toujours. Mais nous remplissons les tests progressivement après la sortie.

Je suppose qu'après avoir vu la conception détaillée publiée ci-dessus, vous devriez être en mesure d'implémenter la v?tre, donc je ne vais pas faire une plongée profonde dans le code cette fois ??

Chapitre 5 : Déploiement et surveillance

Après quelques corrections de bugs et la signature du contr?le qualité, nous étions prêts à partir. Travail bien fait ? Non, mon ami, nous avons quand même d? mettre en place une surveillance lourde pour cette pièce. Comme il a été développé en très peu de temps, j'étais au moins un peu méfiant. Nous avions par défaut activé le tra?age sur ce service via LightStep . Donc en dehors des traces, j'avais mis en place un monitoring dédié du trafic, des taux d'erreurs, des tableaux de bord de latence, des alertes pour toutes les API. Et après la mise en service, moi et mes coéquipiers, nous avons eu un appel et nous avons surveillé le système à l'intérieur et à l'extérieur pendant au moins une heure, des utilisations de la RAM et du processeur aux journaux d'erreurs . Donnez donc toujours le même poids à l' observabilitéet la surveillance aussi. Il y avait de petits problèmes sur le système de production et nous n'avons pu les détecter qu'au début en raison de la surveillance.

Chapitre 6 : Rétrospective

Le système fonctionne, mais après une pause, il est important de faire une rétrospective et d'identifier les choses que nous avons manquées et de travailler dessus. Je suis s?r que nous avons raté une tonne de choses et coupé beaucoup de coins et obtenu une énorme marge d'amélioration. Par exemple, voici quelques…

Choses que nous pourrions faire mieux

  1. Nous avons utilisé la base de données Postgres déjà existante pour cela car le pilote, l'ORM et l'infrastructure de support étaient déjà là. Mais j'explorerais probablement un peu les solutions de base de données.
  2. NodeJS est génial, mais je pense que Go serait une meilleure solution pour cela. Nous aurions pu explorer cela.
  3. J'ai essayé d'écrire une requête pour calculer le score dans la base de données uniquement et j'ai lamentablement échoué. Je pourrais probablement écrire cela et effectuer un traitement par lots pour le calcul du score, réduisant encore plus les opérations de base de données.
  4. Nous n'avons pas pu exécuter de tests de charge et de performances approfondis, ce qui est indispensable.
  5. Nous aurions pu écrire deux étapes différentes pour la mise à jour du score DB et la mise à jour de l'ensemble trié Redis, ce serait une implémentation plus propre.

Notes d'adieu

Nous avons fait de notre mieux dans ce court laps de temps. Même la mise en ?uvre s'est légèrement détournée de la conception originale. Mais ce n'est pas grave, il y aura constamment des compromis. Même si nous avons terminé la fonctionnalité de base en une semaine environ, il y avait de petits correctifs que nous devions publier.

J'espère que vous avez pu apprendre une ou deux choses sur la conception de systèmes et le développement de logiciels aujourd'hui ??

Crédits

Bravo à mes formidables coéquipiers Akash Raj et Aashirwad Kashyap , nous avons tous travaillé ensemble pour construire cela en à peu près une semaine.

Merci d'avoir lu!

Je m'appelle Aritra Das, je suis développeur et j'aime beaucoup créer des systèmes distribués complexes. N'hésitez pas à me contacter sur Linkedin ou Twitter pour tout ce qui concerne la technologie.

Bon apprentissage…

Suggested posts

6 principaux avantages des développeurs d'Europe de l'Est

6 principaux avantages des développeurs d'Europe de l'Est

Comprendre pourquoi les entreprises étrangères cherchent à embaucher des développeurs de Russie, d'Ukraine et de Biélorussie Depuis plus de 6 ans, je gère Rocketech Software Development avec un partenaire, dont le siège est à Singapour et une équipe entièrement distribuée. Nous développons des produits informatiques et développons deux formats de service : outstaff et Dedicated Team.

5 termes incontournables dans l'analyse des séries chronologiques

Un élément fondamental de la science des données

5 termes incontournables dans l'analyse des séries chronologiques

Une série chronologique est une séquence d'observations ou de mesures classées dans le temps. La première image qui vient à l'esprit lorsque l'on parle de séries chronologiques est généralement le cours des actions.

Related posts

Une perspective d'ingénierie sur l'apprentissage automatique basé sur la physique

Une perspective d'ingénierie sur l'apprentissage automatique basé sur la physique

Les ingénieurs et les scientifiques sont tous deux aveuglés d'un ?il, bien que de c?tés différents. Bonjour, Je m'appelle Sivakorn Sansawas et je suis étudiant en génie mécanique à KMUTT.

IOTA, la révolution crypto

Que se passe-t-il le jour où le marché voit ce que fait l'IOTA ? Parfois, les annonces concernant les partenariats et les nouvelles au sein de l'espace cryptographique général sont dignes d'intérêt en raison du fait que les fondateurs de projets vantent des partenariats qui souvent n'existent pas réellement. Cela dit, toutes les pièces ne sont pas de cette fa?on.

27 conseils pratiques pour devenir un concepteur de produits plus précieux

27 conseils pratiques pour devenir un concepteur de produits plus précieux

Pas votre liste de choses à faire créative habituelle - avec l'inspiration de Ryan Holiday Qu'est-ce qu'un concepteur de produit précieux de toute fa?on ? Cela signifie-t-il qu'ils font une réelle différence dans la vie des gens ? Est-ce parce qu'ils encadrent de nouveaux designers ? Peut-être ont-ils écrit un best-seller sur le design ? Cela peut être tout ou rien de ce qui précède. Cela n'a pas d'importance.

Notes sur le bien-être

Le bien-être est pour ma génération ce que les régimes amaigrissants étaient dans les années 90, ou la coca?ne dans les années 80, regorgeant de toutes sortes de nouvelles fa?ons, franchement épuisantes, de s'y prendre. En tant que personne qui a grandi en même temps que les médias sociaux, j'ai vécu ses nombreuses phases.

MORE COOL STUFF

Mike Krzyzewski, l'entra?neur de basketball des Duke Blue Devils, est-il marié ?

Mike Krzyzewski, l'entra?neur de basketball des Duke Blue Devils, est-il marié ?

La retraite de Mike Krzyzewski du basketball Duke à la fin de la saison en cours lui donnera plus de temps avec sa femme et sa famille.

Quelle est la taille de Nicholas Braun de ? Succession ? ?

Quelle est la taille de Nicholas Braun de ? Succession ? ?

Les fans de "Succession" ne peuvent s'empêcher de remarquer la taille inhabituellement haute de Greg, alias Nicholas Braun. Est-ce qu'il domine vraiment ses acteurs?

'The Pioneer Woman' Ree Drummond Plats d'accompagnement de Thanksgiving pour la saison des fêtes 2021

La pionnière Ree Drummond est là pour vous préparer pour Thanksgiving. Voici quelques-uns de ses meilleurs plats d'accompagnement.

Pourquoi Lady Gaga portait une robe pare-balles pour cette performance

Pourquoi Lady Gaga portait une robe pare-balles pour cette performance

Lors de l'investiture du président Biden, la robe pare-balles de Lady Gaga fait une déclaration, que vous soyez d'accord avec elle ou non.

Essayez nos mini mots croisés

Essayez nos mini mots croisés

Mis à jour chaque semaine, nos mini mots croisés combinent nos lectures préférées de HowStuffWorks avec des indices intelligents !

Qu'est-ce qui fonctionne le mieux : dosettes de lessive, détergents en poudre ou liquides ?

Faire la lessive est déjà assez pénible sans avoir à se soucier de choisir le bon détergent. Alors, laquelle est la meilleure ? Ou est-ce même important?

La véritable histoire du peuple bleu du Kentucky

La véritable histoire du peuple bleu du Kentucky

Les familles Fugates et Combs du Kentucky rural ont perdu la loterie génétique, partageant toutes deux un trait récessif rare qui rendait leur peau bleue lorsqu'ils se mariaient entre eux. Quelle en était la cause ? Et qu'est-il arrivé aux familles?

Le Condor de Californie 'Virgin Birth' pourrait-il sauver l'espèce ?

Le Condor de Californie 'Virgin Birth' pourrait-il sauver l'espèce ?

Deux poussins males sans père sont élevés dans le cadre d'un programme visant à sauver le condor de Californie de l'extinction. Comment de telles naissances ? vierges ? sont-elles possibles ?

Quelles sont les chances qu'une mégastructure extraterrestre bloque la lumière d'une étoile lointaine?

Quelles sont les chances qu'une mégastructure extraterrestre bloque la lumière d'une étoile lointaine?

Une étrange étoile située à 1500 années-lumière de la Terre présente un étrange comportement de scintillement qui conduit certains scientifiques à supposer qu'une mégastructure extraterrestre bloque la lumière. Mais quelle serait exactement une telle structure et quelle est la probabilité que le télescope spatial Kepler en ait effectivement repéré une? En ce moment, l'étoile KIC 8462852 est vraiment chaude - et pas seulement parce que c'est une étoile de type F - mais parce que l'espace Kepler télescope a découvert qu'il scintillait d'une manière très inhabituelle, comme si quelque chose l'obscurcissait.

Les meilleures (et les pires) blagues du poisson d'avril pour 2016

Les meilleures (et les pires) blagues du poisson d'avril pour 2016

1er avril. Pour certains, une journée de manigances.

C'est ainsi qu'a été réalisé le clip vidéo OK Go : en "gravité zéro" et entouré de cosmonautes russes

? Comment diable ont-ils fait ?a ? semble être la réaction la plus courante au dernier clip d'OK Go. Le groupe qui nous a conquis avec la danse des tapis roulants l'a encore fait, mais cette fois nous demandons sérieusement : comment ont-ils fait ?a.

Le couloir le plus cher du monde se trouve sous la ville de New York

Le couloir le plus cher du monde se trouve sous la ville de New York

Imaginez marcher avec de l'argent. (Photo : No?l Y.

Kulture, la fille de Cardi B et Offset, montre de belles nouvelles tresses sur Instagram

Kulture, la fille de Cardi B et Offset, montre de belles nouvelles tresses sur Instagram

La fille de 3 ans de Cardi B et Offset, Kulture, a montré sa nouvelle coiffure tressée sur Instagram.

Selena Gomez donne à Cara Delevingne un bisou sur la joue pour Kiss Cam au Knicks Game

Selena Gomez donne à Cara Delevingne un bisou sur la joue pour Kiss Cam au Knicks Game

"Elle est tellement amusante et elle est juste extrêmement aventureuse", a déclaré Selena Gomez à propos de sa copine Cara Delevingne.

Jamie Dornan dit qu'il a perdu le r?le de Superman au profit d'Henry Cavill et a approché Marvel pour un r?le de super-héros

Jamie Dornan dit qu'il a perdu le r?le de Superman au profit d'Henry Cavill et a approché Marvel pour un r?le de super-héros

Jamie Dornan a révélé qu'il avait auditionné pour le r?le de Superman mais qu'il avait perdu face à Henry Cavill ; et il a parlé à Marvel de rejoindre le MCU.

Languages

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