Всем привет!
Сегодня я расскажу, как мы разработали распределённое приложение для анализа вакансий с платформы 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 для визуализации данных.
Проект может быть полезен:
-
Исследователям рынка труда.
-
Компаниям для мониторинга востребованных навыков.
-
Соискателям, чтобы понимать тенденции.
Если вам интересно узнать больше о проекте, пишите в комментариях — с радостью отвечу!
Автор: ustinov-iv