Всем привет!
Сегодня я расскажу, как мы разработали распределённое приложение для анализа вакансий с платформы hh.ru. Мы применили микросервисную архитектуру, контейнеризацию, брокеры сообщений и инструменты визуализации данных, чтобы создать решение, которое может быть полезно аналитикам, компаниям и соискателям.
Если вы хотите узнать, как собрать все эти технологии в единое целое и сделать это эффективно — устраивайтесь поудобнее. Поехали!
Идея проекта
На рынке труда ежедневно появляются тысячи новых вакансий, и их анализ помогает понять востребованные профессии, технологии и тренды. Наша задача состояла в разработке системы, которая:
Собирает данные с платформы hh.ru с помощью API.
Обрабатывает их и сохраняет в базу данных.
Обеспечивает поиск и визуализацию информации для конечных пользователей.
Масштабируется при росте нагрузки.
Для этого мы решили использовать микросервисную архитектуру, так как она позволяет:
Изолировать отдельные модули приложения.
Масштабировать компоненты независимо друг от друга.
Легко добавлять новые функции.
Архитектура решения
Архитектура построена из следующих компонентов:
Фронтенд: Vue.js, отображение вакансий и диаграмм.
Бэкенд: Node.js (NestJS), взаимодействие с базами данных и брокером сообщений Kafka.
Сервис сбора данных: Python, интеграция с API hh.ru.
Хранилища данных: MongoDB для структурированных данных, Elasticsearch для аналитики.
Kafka: асинхронная передача сообщений между сервисами.
Nginx: балансировка нагрузки и проксирование запросов.
Схема архитектуры
Технические детали
1. Фронтенд
Фронтенд написан на Vue.js. Это позволило быстро создать компонентный интерфейс, поддерживающий адаптивный дизайн.
Ключевые инструменты:
Axios — для запросов к API.
Chart.js — для построения графиков.
Пример компонента для отображения вакансий:
<template>
<div class="jobs">
<div v-for="job in jobs" :key="job.id">
<h3>{{ job.title }}</h3>
<p>{{ job.description }}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return { jobs: [] };
},
async mounted() {
const response = await fetch('/api/jobs');
this.jobs = await response.json();
}
};
</script>
2. Бэкенд
Бэкенд реализован на Node.js с использованием NestJS. Это позволило модульно организовать код, выделив такие модули, как:
Контроллеры: принимают HTTP-запросы.
Сервисы: реализуют бизнес-логику.
Интеграция с Kafka: обработка сообщений от других микросервисов.
Пример контроллера API:
@Controller('api/jobs')
export class JobsController {
constructor(private readonly jobsService: JobsService) {}
@Get()
async getAllJobs() {
return this.jobsService.findAll();
}
}
Для взаимодействия с MongoDB используется Mongoose:
@Injectable()
export class JobsService {
constructor(@InjectModel(Job.name) private jobModel: Model<Job>) {}
async findAll(): Promise<Job[]> {
return this.jobModel.find().exec();
}
}
3. Сервис сбора данных
Для сбора вакансий с hh.ru используется Python. API hh.ru позволяет фильтровать данные по региону, специальности и другим параметрам.
Ключевые инструменты:
aiohttp — асинхронные запросы.
pymongo — сохранение данных в MongoDB.
Асинхронная функция для запросов к API hh.ru:
async def fetch_vacancies(self, session, url, params=None):
async with session.get(url, params=params) as response:
if response.status == 200:
return await response.json()
else:
logging.error(f"Ошибка {response.status}")
4. Хранилища данных
MongoDB: Основное хранилище данных.
Elasticsearch: Используется для поиска и аналитики.
Данные индексируются в Elasticsearch, после чего визуализируются в Kibana.
5. Kafka
Брокер сообщений Kafka обеспечивает взаимодействие между микросервисами.
Конфигурация Docker Compose для Kafka:
version: '3.7'
services:
kafka:
image: confluentinc/cp-kafka:latest
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
zookeeper:
image: confluentinc/cp-zookeeper:latest
environment:
ZOOKEEPER_CLIENT_PORT: 2181
6. Nginx
Для маршрутизации запросов настроен Nginx. Он распределяет трафик между экземплярами бэкенда.
Пример конфигурации Nginx:
upstream backend_servers {
server backend_1:3000;
server backend_2:3000;
}
server {
listen 80;
location / {
proxy_pass http://backend_servers;
}
}
Результаты анализа
На основе данных с hh.ru мы провели несколько ключевых исследований:
-
Распределение вакансий по уровням опыта:
Senior: 60%.
Middle: 30%.
Junior: 10%.
-
Популярные технологии:
Python и JavaScript — лидеры.
-
География:
70% вакансий сосредоточено в Москве и Санкт-Петербурге.
-
Тип занятости:
Полная занятость доминирует, но гибкие графики набирают популярность.
Итоги и выводы
Этот проект показал, как можно собрать мощное и масштабируемое приложение с использованием современных технологий. Мы использовали Docker для контейнеризации, Kafka для обмена сообщениями, а также Elasticsearch и Kibana для визуализации данных.
Проект может быть полезен:
Исследователям рынка труда.
Компаниям для мониторинга востребованных навыков.
Соискателям, чтобы понимать тенденции.
Если вам интересно узнать больше о проекте, пишите в комментариях — с радостью отвечу!
Комментарии (9)
PrinceKorwin
18.12.2024 20:30Эм. А сколько реально у вас данных было скравлено в итоге?
Звучит так, что достаточно какого-то SQL для хранилища. А аналитику строить по данным в памяти. Есть подозрение, что оно все туда влезет.
mister_xen
18.12.2024 20:30"
Итоги и выводы
Этот проект показал, как можно собрать мощное и масштабируемое приложение
"
ну нет. не показал.
"Итоги и выводы"
ну мы рады за вас
alpha_man
18.12.2024 20:30Ваш преподаватель определено вас похвалит за эту статью.
В остальном соглашусь с комментариями: если цель проекта была обучающая, то так и надо было писать, но с большей детализацией. Если практическая, то тут явно всего больше чем нужно
gmtd
Какой-то жуткий оверинжениринг...
Vue, MySQL и PHP
mxr
Звучит как монолит на Laravel c Vue через Inertia =)
Не плохой бы сервис вышел, но таким образом мы отказываешься лишь от node.js в данной архитектуре. И даже так, в качестве зависимости он нужен.