Si vous ne vivez pas dans une grotte, vous savez peut-être que les microservices sont l'architecture d'aujourd'hui. Avec le développement de cette tendance, le produit Segment l'a
acceptée à un stade précoce
comme la meilleure pratique qui a bien servi dans certains cas, et, comme vous le verrez bientôt, pas si bonne dans d'autres.
En bref, les microservices sont une architecture logicielle orientée services dans laquelle les applications côté serveur sont construites en combinant de nombreux services réseau à tâche unique et minimaux. Les avantages comprennent une modularité améliorée, des tests simplifiés, une meilleure composition fonctionnelle, l'isolement de l'environnement et l'autonomie des équipes de développement. L'inverse est une architecture monolithique, où une grande quantité de fonctionnalités est située dans un service, dans lequel les tests, le déploiement et la mise à l'échelle ont lieu dans leur ensemble.
Début 2017, nous avons atteint un point de basculement avec l'essentiel de notre
produit Segment . Il semblait que nous tombions d'un arbre de microservices, heurtant chaque branche en descendant. Au lieu de se développer plus rapidement, une petite équipe s'est embourbée dans une complexité croissante. Les avantages importants de cette architecture sont devenus un fardeau. À mesure que notre vitesse diminuait, le nombre de défauts augmentait.
En conséquence, l'équipe n'a pas pu réussir avec trois ingénieurs à temps plein qui passent la plupart de leur temps à simplement entretenir le système. Quelque chose devait changer. Ce post est une histoire sur la façon dont nous avons pris du recul et adopté une approche qui correspondait bien à nos exigences et aux besoins de l'équipe.
Pourquoi le travail des microservices a fonctionné
L'infrastructure de données client Segment reçoit des centaines de milliers d'événements par seconde et les redirige vers l'API partenaire, que nous appelons des destinations côté serveur. Il existe plus d'une centaine de types de ces domaines, tels que Google Analytics, Optimizely ou les crochets Web personnalisés.
Il y a des années, lorsque le produit a été lancé à l'origine, l'architecture était simple. Il y avait une API qui recevait des événements et les envoyait à la file d'attente de messages distribués. L'événement dans ce cas était un objet JSON généré par une application Web ou mobile contenant des informations sur les utilisateurs et leurs actions. Un exemple de charge utile ressemblait à ceci:
{
"type": "identify",
"traits": {
"name": "Alex Noonan",
"email": "anoonan@segment.com",
"company": "Segment",
"title": "Software Engineer"
},
"userId": "97980cfea0067"
}
, , . API , , , – Segment API, , . Segment .
, . , . , , , . , HTTP 500, -. , , , , . , .

, , , ,
. , , ,
.
, X -. , , X, . , , . , X . , .

, . -, . , , , . , , , .

API , . – X
traits.dob
, API
traits.birthday
. X :
const traits = {}
traits.dob = segmentEvent.birthday
Segment, . , API . , , XML .
, , . , , . , . . , .
. .
50 50 . , , HTTP , .
, ,
event.name()
.
name
Name
. ,
firstName
,
first_name
,
FirstName
. , .
Identify.prototype.name = function() {
var name = this.proxy('traits.name');
if (typeof name === 'string') {
return trim(name)
}
var firstName = this.firstName();
var lastName = this.lastName();
if (firstName && lastName) {
return trim(firstName + ' ' + lastName)
}
}
. .
. . . , , . .
, . , . . , , .
, . , – . , .
, , - , .
, , , . , . .
140 . . , .
, . , , .
Centrifuge. Centrifuge .

, , , . , .
120 . . , .
, . , . .
, . , .
, . HTTP , , , .
, . , . , HTTP , . , . . , , .
HTTP . , . 5 . 140 .
Traffic Recorder. Traffic Recorder
yakbak, . , , . . , . , HTTP , .
, , Traffic Recorder. , 140+ . .
., . , . 140+ . .
. 2016, , 32 . 46. 6 , 2016 .
. , . , , .
, :
- . , , , . , . , , .
- . , , , . 3000+ , . - Redis , . , .
, . , . , . , .
, . , , , .
- . , , . , , .
- , , , . , .
. , , . .