📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Backend архитектура: от микросервиса до маркетплейса

Сергей Соловьев41:50

Transcription

My name is Sergey Solovyov. I have been working in backend development for about 10 years. For about 2 years, I have been working in a large IT company. Often, when it comes to backend, people don't really understand what was done there, what the team size was to implement such functionality, and generally what the functionality was, in the end. For example, we will take an online store, start with a small microservice, and then grow it into one large, huge system, as it happens in big business. In order to understand step by step how such a system develops, so that you can orient yourself by some job description, or a description of your resume, what exactly you will have to do in such a team, what the tasks will be, what the complexity of these tasks will be, well, and how it will look like on the architecture. So, this is the smallest team size. One service, one container. All this is running and done by one person. There is no Rocket Science here, because there isn't even a database. What would I add here? Well, I guess I'd like to add a database where we will store some information. When we talk about some kind of system design, we need to abstract from specific technologies. It doesn't matter to us what database will be under the hood. What matters to us is that it is a storage for our data, that we understand that it will store our records in some form or some information. But it absolutely doesn't matter if it's Postgres, Mongo, or MySQL, who cares. Database. Well, and we just make a network connection, that is, network connectivity. Our service knows how to access the database. That's it, now we have learned to access and respond to some requests via API. That is, we can send an HTTP request, for example, get Order, which will return us a list of products. We can also, for example, make an HTTP request get orders ID, that is, specific information about a specific product. That is, this is just some backend, which is without authorization, without anything. Just two methods, two endpoints are exposed, and they can be called. For this, we will need a database and this network access. Before we start adding more microservices or complicating things further, let's talk about how the communication of our components in a large system is generally organized. For our current diagram, which we are trying to understand in the legend and so on, we will need some basic superficial knowledge. The client of our application can be any frontend. It's an honest website, or it can be a mobile application, or it can be your smart refrigerator or vacuum cleaner that knows how to access APIs. In general, it doesn't matter. Therefore, let's just draw a rectangle that will be responsible for the frontend. We will call it frontend and write client in parentheses. And it doesn't matter what it actually is. So that our frontend doesn't have to think about where this service is located, right? Or if we have several such services, and so that the frontend doesn't have to keep in mind, right, meaning it doesn't know the exact addresses where it needs to go, and so on, usually different mechanisms are used. The simplest basic mechanism that we can encounter, actually, is Nginx, that is, the load balancer itself. This is how it will look. Nginx, right, and it is responsible for redirecting requests that come to it within its network. That is, in fact, our microservices are not accessible from the outside, they are not exposed. They also usually say in slang "sticking their ass out". Well, meaning our microservice is not sticking its ass out, it's hidden somewhere. And we have only one entrance door, like to an apartment, and only through it can you get into other rooms. It's the same here. Essentially, well, or any other load balancer, is the entrance door to our backend backstage. Honestly, if so, the frontend also lives there, it is also hidden behind this door. And when our client wants to make a request, for example, visits some website, it goes into something that distributes this traffic further. This is usually called a load balancer, but it's not necessarily Nginx, it can be something else, it can be something custom-written, it doesn't matter. In the diagram further, I will not draw Nginx, because it will simply complicate our system. I will draw the frontend as if it goes directly to our services. But once again, you should understand that in reality, somewhere under the hood, there is a balancer hidden. Okay, let's bring it back, remove our little guy, we don't need him anymore. Let's keep the frontend, remove the balancer, and let's do this thing. Well, since we started doing everything here about the online store, let's name our microservice Orders service, DB Orders, and add some other microservice so that we have two logics. If we have orders, then, probably, we should also have customers, right, so-called customers. Customer service. Look, it can be organized differently here. Customer service can know how to access a common database, right, to DB Orders, and there will be tables there and so on. It can be a separate database. Both ways exist. But if we are talking about a true microservice architecture, then each microservice should access its own database. Why? Because, actually, a microservice is some atomic thing that can be removed, added, and it will not affect other services. That is, the Order service should not depend on the customer service in any way. Therefore, the Order service lives its own life. And the most logical thing is to completely separate them, not to give them, uh, one common database, right. Therefore, here let's put DB, well, there, DB customer. Understood. Look, what else. It may not be obvious, but in fact, these databases can live on the same PostgreSQL instance. That is, PostgreSQL allows you to start several databases within one, one large PostgreSQL infrastructure, right? Therefore, it's not like completely different servers are started with a database, it can simply be two logical units on one server, there DB1, DB2, DB3, and so on. Therefore, it is not very difficult to organize. We need to make sure that the frontend always goes to one application, to some. And after that, the requests will be distributed. It is actually the responsibility of backend developers to provide a convenient API for the frontend. We can have many different endpoints inside, call them whatever you want. But externally for the frontend, we must provide only what it needs, only what is convenient to use. Therefore, we will not complicate things, do anything complex. I suggest simply applying the usual pattern, the so-called API gateway, which will simply act as a proxy for our frontend. Well, meaning some call it a proxy service, some call it a front-to-back service, I will call it API Gateway. Front-to-back service. Now we will correct the picture so that everything is convenient. It has become much better. The frontend started going to one point, and all the flat lines will be our internal connections, meaning we will manage them. All dashed lines will come to us. This is how it will be more convenient for us to communicate. Perhaps a legend will appear here somewhere. Yes, let's even make it ourselves. Let it be our help. So, uh, [music] for external and internal requests. Here. And now I will draw these arrows. So. So. And we agreed that external requests are dashed. Okay. Look. Oh, it became very convenient, everything became clear immediately. Okay, let's go further. One person is unlikely to develop such a system if we are talking about a team. Most likely, there should be two people, and it would be great if there was at least one QA who allows all this to be covered by testing. Possibly one analyst. Well, and in general, it looks like some kind of product, so a product owner could appear here. That is, this is a scheme for a team of two to four people. In principle, okay. But it looks a bit small, right, you agree. That is, we have functionality for orders, right, meaning for orders, there is for customers. But it would be cool if we could also check authorization on the frontend. Indeed, can this buyer authorize and buy, right, something? That is, is this really that buyer or is this really that store that placed the order? Well, meaning it would be cool for us to add some service for authorization. There is a service, and every request that requires authorization will go here, get information about whether this is really our user, and whether he has access to this request. So-called authorization, right? Let's check. So, here we have, and here, well, either 200, or 400, right? That is, either we get 200, which is good. 200 is an HTTP response that says there is access. Well, let's say Okay or Error. It will be more convenient. Okay. In parentheses, 200, error 400. That is, no access. Usually 401 is given. Super. Good. It became much better. Here, this Auth service, it can be implemented in different ways. There can be its own database. It can be a Keycloak service, right? Or Keycloak. Well, let's write it like this. Or Keycloak. I always confuse how to spell it. Right. Well, it can also be some custom-written service that somehow works with JWT, or Keycloak is essentially also a service. Just like PostgreSQL, right? That is, you can install a Docker dependency on your own, however you want, and use it. It has its own database inside, an API for checking, validating tokens, different types of authorization SSO, and so on. By the way, if you are interested in learning more about this, be sure to write a comment. I will cover this topic in as much detail as possible. We will write an application in FastAPI and definitely practice with different types of authorization, how it works, configure Keycloak. In general, it should be interesting. Be sure to write a comment. I will be happy to help you. Okay, let's move on. Before the request goes to some service, we want to validate it for rights, right? So. That is, our request will go to the API Gateway. There we will see a requirement that this request must pass verification. We will go to our service, get the user from this service, and then with this user, we will go further to this service or to this service or without it. Well, it's important that we check that we have access here. Okay. This is all still about a team of two to four people, no more. Well, such a small application. Further, there can be various caching things here to reduce the load on our application. Imagine, one popular blogger on his YouTube channel starts advertising products from our online store. Well, let's assume he recommends us to buy this wonderful product. And a lot of traffic comes to us. By the way, the link to this product will be in the description. A lot of traffic comes to us. And this is a large load on the database, right? And we don't need such a load, because the product rarely changes. That is, the product card will not change constantly, depending on who visited. And we can cache it. That is, we can remember the state of the card for a certain period of time. That is, all the information that we need to show to the frontend, we can remember. We can cache at different levels. These are different methodologies. Today we will talk about caching on the backend using Redis. Let's attach Redis. To reduce the load on our database, we will simply remember our card, the data for our card. And with each request, we will go to this Redis and first ask, do you have information for this. We can attach Redis at different levels. That is, look, we can attach it here. Yes, let's put Redis. Then our request will go here, pass authorization, then go here, then go here. In general, this sounds logical. Not bad. But why should we make this request here if we can, like, check authorization and go here immediately? That is, we can raise Redis to a higher level. Thus, we will reduce the load on our order service. That is, the request simply won't go there, because we call our endpoint, go to the API Gateway, check authorization, and then go to Redis and get information that we have such a product, and simply download it. That is, we don't load the database. Super, we have reduced the load, cool, all that. Okay, it became much better, right? That is, we now have different buzzwords that you have seen in your resume but didn't understand how they work. Here they are, Redis, and database, and some API Gateway, and authorization. Everything has appeared. Now we want to provide integration to our customers, right? That is, earlier we only sold our own products, and somehow did it through the admin panel. By the way, we can draw it, right, the admin panel. It will not be exposed, we will connect to it ourselves from somewhere. Here we filled in products from the admin panel. Again, I remind you, this can be Django, this can be FastAPI, it doesn't matter. Okay. To move forward, we need to develop our product. And we want to add integration of external stores so that they sell their goods through us. Correct. For this integration, we will need some new service. Let's create it and call it store service. Service for stores. Yes, what will it do? Store service. Service for integrating our stores. Now we will not go into the details of how our products and stores are connected. Somehow we have integrated it, it doesn't matter. Let's move the admin panel here so that it doesn't interfere with us. Now we will establish the connection. DB Store. Look, how to connect our store service with order. That is, now we have to somehow place the store's products in our product service. How can we do this? We can simply go directly, actually, but then we might get a mess. That is, we will start communicating between services in a very complex, convoluted way. A lot of arrows will appear. This is nonsense. But this can happen. You can encounter this in your team or your new team, where you get a job literally tomorrow. So don't be scared of this. Also, we can go the other way around, go from the service to the API Gateway, since it knows where everyone lives. Yes, meaning the domain addresses within our network. And, accordingly, it will go back and make a request and do everything. This can also be done, but it's not very good, because we have requests in this direction, and requests in the opposite direction. Well, something, you agree, doesn't look very good. Another option is to provide a service. That is, we have our internal data storage service for stores, and we can make all these changes from the outside. That is, we can go like this, right? That is, integration with the store, it, for example, comes via API to our API Gateway, goes to the store service, and this same request can go here to do something. Already better, it has become much better, but still, it seems a bit complicated, right? Yes. Yes, and we also have our own frontend here. There will be some access here too. Not very convenient. Let's create an integration service, that is, store integration service. This service will be exposed externally. Exactly like our frontend. Our client in the form of a store will come here, also authorize, meaning it will have its own different role and so on, and then it will get to the store service or the order service. That is, it can view its products, it can view customers who are somehow registered there or somehow interact, are involved with its store, and it can view information about itself, about its store. This is a more classic approach, but here a problem arises. Look, if the store suddenly wants to export a lot of data via API, it puts a heavy load on the API Gateway, and from here requests can multiply. That is, they can go here, here, a lot. This will be very difficult for our service. Therefore, we can think about how to integrate with this service differently. Let's think about how this can be done. If anything, this project is quite viable. This is a possible implementation. Perhaps you know such online stores or work in such a place yourself. I will be glad if you tell me about it. This is more about a team of at least three people. That is, two developers, 1 QA or 2 QA, because there is quite a lot of functionality, it depends on the automation of this functionality. That is, are there any scripts for integration here. or extraction. That is, we can pull data from their accounting or from their warehouses ourselves. Or we can integrate with them via API, or there are other ways to integrate. There is a lot of logic here, a lot of authorization. The frontend, most likely, has already become a very large application, because there is such a cabinet, and such a cabinet, and products, and so on. All this is quite complex, so the team must grow. Here, in my opinion, it will be optimal to have two to three developers, 2 QA, a business analyst, because any integration requires a lot of communication with the outside world, so it's better to provide at least one analyst here. Or the product owner can cover this topic. And the team already has more than five people. It seems like someone is needed here to help manage this team. It can be a developer, it can be a product owner, it can be a lead QA, it doesn't matter. He can be this person concurrently, because he doesn't have that much communication with personnel, but there is already a responsible person needed who will command all this. And what else needs to be added here. I think without this it's already very difficult to live. Especially when we talk about external integrations, we bear responsibility. That is, we most likely take money for this from real business clients, B2B. And here we bear responsibility, we sign contracts with them on such concepts as SLA, possibly Latency, and so on. These are metrics for the duration of our requests. That is, well, or SLA is the availability of our site for external connection. Well, meaning, roughly speaking, we promise our client that our online store will work 99.999% of the time during the month. That is, it will not work for a maximum of 5 seconds. For calculating SLA, there is a special calculator. Here is an example. If you need a link, I will send it to you. But this is generally the first line of Google. How does this calculator work? We enter the percentage we agreed on for our site to be active, and we get how much downtime is available under this agreement. Well, meaning, if we signed 99.9, it means that for the entire day our site can be down for 1 minute and 26 seconds. Usually they sign 99. Let's look. Uh-huh. Well, in a day, 8 seconds of downtime is available. So in a week, our site can be down for one minute. That is, these are quite large numbers, right? Or rather, quite small numbers, so as not to risk the contract like this. Therefore, we must surround ourselves with metrics. What does it mean to surround yourself with metrics? For this, Prometheus and Grafana are used. Usually, this is the de facto standard in the market, you might encounter something else, but basically almost everyone uses Prometheus and Grafana. This is a tool that collects metrics. Well, let's, okay, honestly, let's draw how it looks, so as not to get confused. Look, Prometheus collects metrics from all services. That is, it itself, essentially, goes to each service and asks for metrics from it. I will remove these arrows now or make them super-duper dashed, thin, so that we don't see them, so that they don't interfere with us. Right. And its essence is what? To go and every certain period of time, for example, every 5 seconds, ask the service: "How are you doing?" And the service provides him in text form all the information about how it is doing, how many, which handler is called, what is the duration of requests, and so on. And based on this, we can build some graphs in Grafana. I think we will definitely cover this topic in more detail. It's not important for us now. But it's important for us to just understand that such a thing should already be at this moment. This is not entirely our job, this is more the job of a DevOps engineer. That is, this is not pure backend. But it may be that a DevOps engineer has set up Grafana, Prometheus, configured metric scraping, that is, collecting these metrics from our services, but we draw the dashboards themselves. This happens. I advise you to look at the Grafana website for this. Everything is explained there on how to draw it. Or you can write comments, we will discuss how to draw a regular dashboard for a regular application, practice, and you will try everything with your own hands and understand that there is nothing particularly difficult. Something very complex is usually done by guys who do this professionally. SRE, DevOps, and so on. Backend developers usually have enough basic things. RPS, latency, SLA, Availability, right, for example, well, CPU, RAM, number of pods, if we are talking about Kubernetes, and so on. Yes, by the way, if we are talking about Kubernetes, I think it's time for Kubernetes to appear here, because if we roll out our services, that is, stop and roll out a new version, new functionality, then everything will simply fall apart, right, and we will not maintain our SLA. Therefore, we add a magical Kubernetes cluster on top and start making replicas. That is, each service will have several replicas. And when we roll out, we will roll them out one container at a time. In general, here we can already organize deployment in such a way that containers are rolled out without dropping all functionality at once. This can be blue-green deployment, canary deployment, or any other deployment you've heard of. This is already a mature team. It provides a decent service. There can be other various microservices here, or in fact, it doesn't have to be a microservice. It is quite possible that you will encounter such a thing in the form of one large distributed monolith. It will look like this. That is, there is no API Gateway, it is located here. Let's delete it for now. And this is all one big monolith. Usually, such things can be found in Django. That is, each microservice inside is like a project, right? And externally, only one Django is exposed. But we will talk about microservice architecture. It's just much more convenient to look at it on a diagram than one big square. Usually, we aim for a larger company, so we may have a situation where one team develops all of this, which is responsible for the online store. There is another team that is responsible for the delivery of goods from this online store, so-called Delivery service, right, let it be. I will draw it like this. And it will be just a big big square. Under the hood of this square, there can be absolutely the same diagram. And externally, only an API Gateway will be exposed. This can be internal authorization, this can be their internal authorization, this can be cross-service authorization for communication between us. It doesn't matter how it's done. It doesn't matter to us. We just know that some of our services know how to access this delivery service. Let's color it in some interesting color to distinguish it from others. Like this. We might have some other service. I don't know. Let's, let's call it service or warehouse, as you like. Warehouse service. This will be a warehouse. And somehow we know how to access it. Well, let's, our internal request we know how to make, and here, for example, from order, from delivery, for example, customer service knows how to access. All this can diverge. That is, it's actually not so important for us now. We have a large integration, a complex system. And here we will communicate via API, for example, right? That is, HTTP requests via API and so on. But what if, for example, we want to interact asynchronously? I don't want to poke, call handlers to find out how my delivery is doing or something else. Well, this looks complicated and like some overhead. Therefore, let's push all this down. Regarding Prometheus and Grafana, I hope it's clear. I removed them down because we discussed everything. Look, for us to start communicating with these teams, or even with ourselves in an asynchronous manner, that is, not calling a handler and waiting for a response, but we can just throw something, and it will be processed somehow later. So-called message. For this, we use a data bus. Usually, a data bus in large companies is Kafka. You can also encounter RabbitMQ. NATS is gaining

Popularity. Anything can be here. Well, we will analyze based on Kafka. Here, I will draw a blue one. Blue is like a technical thing, right, through which we interact. That is, we don't develop it, we just connect it. Here. And your and my services can send events to Kafka. Here. Yes, yes. Well, let's do it this way. send event. We can also read these events. That is, usually we send events either directly from such a service, or we use special tricks. If you want to learn this topic better, then definitely write comments, and we will talk with you about the producer, about the transactional outbox pattern, and about all these things that are required to guarantee the delivery of events and guarantee the processing of these events. Well, and since I'm talking about the Outbox Pattern, then we should have something like a consumer appear somewhere, something that can read messages from Kafka and process them. This cannot be your and my backend service, because this is like a separate process. We can make it a separate service, but in general, it is more reliably accepted to raise a separate container. This can be a service in one repository and just another command to run another script. In essence, what does this script do? It does while true, receives messages from Kafka, processes them, maybe puts something in the database. Usually, consumers do not send anything to anyone, do not send anything to any client. That is, the client interacts only through the service. A consumer is for reacting to external events in our system and taking some actions. For example, let's imagine a situation where we have some kind of warehouse service. And this service sends an event that the goods in the store have run out, right? That is, it sends an event like store house empty, let's assume such a name. Okay, it didn't fit in the camera. Here it is. Store House Empty sends such an event. Your and my consumer should hear this event. That is, it will read it from Kafka. How this is done now makes no sense to understand. Just take my word for it, that when a message gets into Kafka, we can write a consumer, that is, an event consumer, that will read these events from Kafka by a specific topic, by a specific name. Here, we will read by this name. Let's copy it so as not to confuse it, and write read. Uh, this is such an event. Your and my consumer received this event that in a certain store, the goods have run out, we saved it in the database, right, that some problem has occurred, and so on. And we would like to notify, look, we can reuse this integration service to go outside. Either our consumer itself can go outside, send requests to our stores, right, send them an alert, or we can also use our internal service. Well, we already have a large company, so we surely must have a service that does notification services. This service knows how to notify external companies or somehow else, by email, by API, however you want. We can integrate there in this way. Or we can implement sending emails or other notifications in a deferred manner. Usually, Celery and an SMTP server, or some other things are used for this. I will just draw Celery because very often in your resume you can find exactly this item, Celery, or some other asynchronous thing for performing some tasks. Cron jobs are the same. All this is needed to perform an asynchronous task. Look how it will look. Our consumer read the event, and its task is only to read these events and create some next action. That is, we pass this hot potato further so that the next service performs its work. We don't make one big combine that does all the logic. We make atomic pieces. Well, this is according to the Solid principle, the letter S, single responsibility. I hope you understand what I'm talking about. Therefore, let's add notification to this consumer, right? And it turns out that our consumer puts a task in Celery so that Celery sends the message later. Celery can use Redis as a broker, and then the connection will look like this. This can be a separate Redis instance raised purely for this. This can be reusing Redis. How it will be organized here. There is no specific correct solution, of course. Everyone has everything differently. Plus, there is also such a thing as historically formed. Therefore, you should not insist that my drawing is incorrect. I can come up with 10 arguments why it is correct. Okay. Here appeared our Celery, which knows how to send notifications. A consumer appeared that knows how to read from Kafka. Producers appeared that send events to Kafka. Third-party services appeared with which we integrate via API. And a lot, a lot of different logic appeared. Look, three or four developers and more can develop something like this. At some point, the team can grow so much, for example, seven developers, 3 QA, two analysts, Product, Team lead, and the team will be too large, there will be too much context. That is, there are some integrations, and we have some APIs outwards for these and for those, and stores, and goods, and customers, and some other notifications, and something else. That is, the business can grow to such a state that the team will be too large, and it will be easier to divide it in half and make two small teams again and divide the logic between them in half. This is also a common practice. It turns out that we have reached, perhaps, the maximum possible team size. This is about 4-5 developers, 3-2-3-4 QA, several business analysts. This is already a sufficiently large system. And most likely, if you are going through an interview now in a large company, you will most likely end up in something like this, some approximate format, where you will be responsible for different microservices. That is, you will have one large business domain. A business domain in our case is an online store. And we are responsible for everything that concerns the data presentation, right, the goods that we have somewhere here, how different suppliers integrate with us, and so on. But we are not responsible for the warehouse. Here it is. We are not responsible for delivery, we are not responsible for other things. That is, we have our own small business domain. In general, this is what an average level looks like, which we will work with. Further, there will simply be the addition of some new containers, some new entities, new integrations. Perhaps, for example, such a thing as data warehouses for analytics may appear. For example, the same ClickHouse can be used for this, right, and there orders will somehow send their data there. We will analyze how we are bought, with what frequency, at what price, and so on. Or such a thing as Elasticsearch may appear. This is a thing that is used for full-text search. Well, when you type, for example, iPhone, you can just write ph3 and iPhone 13 will be found. Well, to organize such a system, you need to set up search. This is a separate service. Here. Let's color them blue, just as we agreed with you before. Also, various scripts that will recalculate something can appear here. A service may appear. L team, right, which will be engaged in pricing, dynamic pricing, or something else. What else can appear? You can have various pipelines, Airflow, and so on, to process a large volume of data and somehow process it. Let's make a list of what you need to know to work with such a large legend, to write all this in your resume or to talk about it confidently. The first thing that should be on your list is, of course, frameworks. Here, definitely FastAPI and Django. Don't think about anything else. Don't add Flask, Tornado, and the like. FastAPI is a very popular modern framework. Django is also a popular framework, but it's just a little outdated. These two frameworks allow you to cover more than 90% of vacancies. Don't think further. Next step. You need to add SQL. Just add PostgreSQL. Postgres is the industry standard. De facto, almost everyone uses Postgres. If there is another database somewhere, your experience with Postgres will suit them. But vice versa, not necessarily. If you write MariaDB or MySQL, MSSQL, then people with Postgres might look at you askance and not even invite you for an interview. Therefore, Postgres is enough. It's also worth adding some ORM framework for interacting with the database. If we are talking about FastAPI, then it is SQLAlchemy. If we are talking about Django, then it is Django ORM. Choose one. I advise you to focus on FastAPI. The next thing that should be in your technology stack is Celery. Celery is a thing that allows us to perform tasks asynchronously. In our diagram, this is a microservice that is responsible for sending notifications. This can also be some outbox solutions and so on. Well, in general, Celery is a very simple tool. You can learn it very quickly, so be sure to add it to your resume. If Celery appears, then somewhere nearby there should be Redis, because Redis can be used as a broker for Celery, that is, a queue storage where we put these tasks so that your and my Celery. RabbitMQ is also used. But it doesn't matter. And Redis is also used for caching, just as we did today in our diagram. The next big thing that is desirable to add to your resume is Kafka. This thing helps us integrate with other teams for event systems, right, that is, for systems built on events or data buses. There is no special rocket science here. You just need to understand how Kafka works. You can practice locally, set up Kafka locally from Docker and publish messages and read messages. And, in principle, you will understand how it works. But be sure not to forget to add things to your list to configure the observability of your system, that is, the ability to observe it. This is Grafana for collecting metrics and displaying these metrics. And Sentry for collecting errors. This is a service that allows us to collect errors from the service and show if something went wrong. This is the standard gentleman's set to become a backend developer, or to work as a backend developer. Everything else that can be attached on top, left, right, no longer carries as much value as this core knowledge. That is, ClickHouse, Machine Learning, Elasticsearch, RabbitMQ, I don't know, some other things, some other frameworks, other programming languages, and so on, and so on, and so on. They all give very little boost compared to what these main buzzwords of all backend give. These are the most conversion-generating things that can be. That is, by adding them to your resume and understanding this technology stack, you increase your chances of getting a job exponentially. Therefore, I advise you to focus only on this knowledge. Well, that is, this is a rather large path, a rather difficult path, but in general, I think that after such a video, it became much clearer what a backend developer does, what these services are, how all this is built, how it all interacts. Further, you will have to dig into each hole point by point and understand how to interact with what. Well, I have posted this diagram and the list of what you need to know for it on my Telegram channel. The link will be in the description. I hope this video was interesting and very useful for you. Today we learned a lot of new information, or not new, just refreshed it. It is important that you understand what kind of team you are joining. And be sure to draw a similar diagram for your legend, because if you don't understand what you were doing, then they probably won't hire you. So, see you on the call. Bye. M.