JavaScript系列(44)--微服务架构实现详解

news2025/1/28 1:17:24

JavaScript微服务架构实现详解 🏗️

今天,让我们来学习如何在JavaScript中实现微服务架构。微服务架构是一种将应用程序构建为一组小型服务的方法,每个服务运行在自己的进程中,并通过轻量级机制通信。

微服务基础概念 🌟

💡 小知识:微服务架构的核心是将大型应用拆分成多个独立的服务,每个服务都可以独立部署、扩展和维护。

基础架构实现 📊

// 1. 基础服务类
class MicroService {
    constructor(name, port) {
        this.name = name;
        this.port = port;
        this.express = require('express');
        this.app = this.express();
        this.routes = new Map();
    }
    
    // 配置中间件
    setupMiddleware() {
        this.app.use(this.express.json());
        this.app.use(this.express.urlencoded({ extended: true }));
    }
    
    // 注册路由
    registerRoute(method, path, handler) {
        this.routes.set(`${method}:${path}`, handler);
        this.app[method.toLowerCase()](path, handler);
    }
    
    // 启动服务
    async start() {
        return new Promise((resolve) => {
            this.server = this.app.listen(this.port, () => {
                console.log(`Service ${this.name} started on port ${this.port}`);
                resolve();
            });
        });
    }
    
    // 停止服务
    async stop() {
        return new Promise((resolve) => {
            this.server.close(() => {
                console.log(`Service ${this.name} stopped`);
                resolve();
            });
        });
    }
}

// 2. 服务注册中心
class ServiceRegistry {
    constructor() {
        this.services = new Map();
        this.healthChecks = new Map();
    }
    
    // 注册服务
    register(name, host, port) {
        const serviceId = `${name}-${host}:${port}`;
        this.services.set(serviceId, {
            name,
            host,
            port,
            status: 'healthy',
            lastHeartbeat: Date.now()
        });
        
        return serviceId;
    }
    
    // 注销服务
    unregister(serviceId) {
        this.services.delete(serviceId);
        this.healthChecks.delete(serviceId);
    }
    
    // 获取服务实例
    getService(name) {
        const services = Array.from(this.services.values())
            .filter(s => s.name === name && s.status === 'healthy');
            
        if (services.length === 0) {
            throw new Error(`No healthy instances of service ${name} found`);
        }
        
        // 简单的负载均衡:随机选择一个实例
        return services[Math.floor(Math.random() * services.length)];
    }
    
    // 健康检查
    startHealthCheck(serviceId, interval = 30000) {
        const check = setInterval(() => {
            const service = this.services.get(serviceId);
            if (!service) {
                clearInterval(check);
                return;
            }
            
            if (Date.now() - service.lastHeartbeat > interval) {
                service.status = 'unhealthy';
            }
        }, interval);
        
        this.healthChecks.set(serviceId, check);
    }
}

服务通信实现 🔄

// 1. HTTP通信适配器
class HttpCommunicator {
    constructor() {
        this.axios = require('axios');
    }
    
    async request(service, method, path, data) {
        const url = `http://${service.host}:${service.port}${path}`;
        try {
            const response = await this.axios({
                method,
                url,
                data
            });
            return response.data;
        } catch (error) {
            throw new Error(`Service communication failed: ${error.message}`);
        }
    }
}

// 2. 消息队列通信
class MessageQueueCommunicator {
    constructor() {
        this.amqp = require('amqplib');
        this.connection = null;
        this.channel = null;
    }
    
    async connect(url) {
        this.connection = await this.amqp.connect(url);
        this.channel = await this.connection.createChannel();
    }
    
    async publish(queue, message) {
        await this.channel.assertQueue(queue);
        return this.channel.sendToQueue(queue, Buffer.from(JSON.stringify(message)));
    }
    
    async subscribe(queue, callback) {
        await this.channel.assertQueue(queue);
        return this.channel.consume(queue, (msg) => {
            if (msg) {
                const content = JSON.parse(msg.content.toString());
                callback(content);
                this.channel.ack(msg);
            }
        });
    }
}

// 3. 事件总线
class EventBus {
    constructor() {
        this.events = new Map();
    }
    
    publish(event, data) {
        if (!this.events.has(event)) {
            return;
        }
        
        const handlers = this.events.get(event);
        handlers.forEach(handler => handler(data));
    }
    
    subscribe(event, handler) {
        if (!this.events.has(event)) {
            this.events.set(event, new Set());
        }
        
        this.events.get(event).add(handler);
    }
    
    unsubscribe(event, handler) {
        if (!this.events.has(event)) {
            return;
        }
        
        this.events.get(event).delete(handler);
    }
}

服务发现与负载均衡 ⚖️

// 1. 服务发现客户端
class ServiceDiscoveryClient {
    constructor(registry) {
        this.registry = registry;
        this.cache = new Map();
        this.cacheTimeout = 60000; // 1分钟缓存
    }
    
    async getService(name) {
        const now = Date.now();
        const cached = this.cache.get(name);
        
        if (cached && now - cached.timestamp < this.cacheTimeout) {
            return cached.service;
        }
        
        const service = this.registry.getService(name);
        this.cache.set(name, {
            service,
            timestamp: now
        });
        
        return service;
    }
}

// 2. 负载均衡器
class LoadBalancer {
    constructor() {
        this.algorithms = new Map();
        this.setupAlgorithms();
    }
    
    setupAlgorithms() {
        // 轮询算法
        this.algorithms.set('round-robin', {
            counter: new Map(),
            select: (services, serviceName) => {
                const count = this.algorithms.get('round-robin').counter;
                const current = count.get(serviceName) || 0;
                count.set(serviceName, (current + 1) % services.length);
                return services[current];
            }
        });
        
        // 随机算法
        this.algorithms.set('random', {
            select: (services) => {
                return services[Math.floor(Math.random() * services.length)];
            }
        });
        
        // 最少连接算法
        this.algorithms.set('least-connections', {
            connections: new Map(),
            select: (services) => {
                const conns = this.algorithms.get('least-connections').connections;
                return services.reduce((min, service) => {
                    const serviceConns = conns.get(service.id) || 0;
                    const minConns = conns.get(min.id) || 0;
                    return serviceConns < minConns ? service : min;
                });
            }
        });
    }
    
    select(algorithm, services, serviceName) {
        if (!this.algorithms.has(algorithm)) {
            throw new Error(`Unknown load balancing algorithm: ${algorithm}`);
        }
        
        return this.algorithms.get(algorithm).select(services, serviceName);
    }
}

容错与熔断机制 🔌

// 1. 断路器
class CircuitBreaker {
    constructor(options = {}) {
        this.failureThreshold = options.failureThreshold || 5;
        this.resetTimeout = options.resetTimeout || 60000;
        this.failures = 0;
        this.state = 'CLOSED';
        this.lastFailure = null;
    }
    
    async execute(fn) {
        if (this.state === 'OPEN') {
            if (Date.now() - this.lastFailure >= this.resetTimeout) {
                this.state = 'HALF-OPEN';
            } else {
                throw new Error('Circuit breaker is OPEN');
            }
        }
        
        try {
            const result = await fn();
            this.onSuccess();
            return result;
        } catch (error) {
            this.onFailure();
            throw error;
        }
    }
    
    onSuccess() {
        this.failures = 0;
        this.state = 'CLOSED';
    }
    
    onFailure() {
        this.failures++;
        this.lastFailure = Date.now();
        
        if (this.failures >= this.failureThreshold) {
            this.state = 'OPEN';
        }
    }
}

// 2. 重试机制
class RetryMechanism {
    constructor(options = {}) {
        this.maxRetries = options.maxRetries || 3;
        this.delay = options.delay || 1000;
        this.backoffFactor = options.backoffFactor || 2;
    }
    
    async execute(fn) {
        let retries = 0;
        let delay = this.delay;
        
        while (true) {
            try {
                return await fn();
            } catch (error) {
                retries++;
                
                if (retries >= this.maxRetries) {
                    throw error;
                }
                
                await new Promise(resolve => setTimeout(resolve, delay));
                delay *= this.backoffFactor;
            }
        }
    }
}

// 3. 超时控制
class TimeoutController {
    async execute(fn, timeout) {
        const timeoutPromise = new Promise((_, reject) => {
            setTimeout(() => reject(new Error('Operation timed out')), timeout);
        });
        
        return Promise.race([fn(), timeoutPromise]);
    }
}

监控与日志 📊

// 1. 性能监控
class PerformanceMonitor {
    constructor() {
        this.metrics = new Map();
        this.startTime = Date.now();
    }
    
    recordMetric(name, value) {
        if (!this.metrics.has(name)) {
            this.metrics.set(name, []);
        }
        
        this.metrics.get(name).push({
            timestamp: Date.now(),
            value
        });
    }
    
    getMetrics(name, timeRange) {
        const metrics = this.metrics.get(name) || [];
        const now = Date.now();
        
        return metrics.filter(m => now - m.timestamp <= timeRange);
    }
    
    calculateStatistics(name, timeRange) {
        const metrics = this.getMetrics(name, timeRange);
        const values = metrics.map(m => m.value);
        
        return {
            count: values.length,
            average: values.reduce((a, b) => a + b, 0) / values.length,
            min: Math.min(...values),
            max: Math.max(...values)
        };
    }
}

// 2. 分布式日志
class DistributedLogger {
    constructor(options = {}) {
        this.serviceName = options.serviceName;
        this.logLevel = options.logLevel || 'info';
        this.transport = options.transport || 'console';
    }
    
    log(level, message, metadata = {}) {
        const logEntry = {
            timestamp: new Date().toISOString(),
            level,
            service: this.serviceName,
            message,
            metadata,
            correlationId: metadata.correlationId || this.generateCorrelationId()
        };
        
        this.send(logEntry);
    }
    
    send(logEntry) {
        switch (this.transport) {
            case 'console':
                console.log(JSON.stringify(logEntry));
                break;
            case 'elasticsearch':
                // 实现Elasticsearch传输
                break;
            case 'fluentd':
                // 实现Fluentd传输
                break;
        }
    }
    
    generateCorrelationId() {
        return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    }
}

实际应用示例 💼

// 1. 用户服务
class UserService extends MicroService {
    constructor() {
        super('user-service', 3000);
        this.setupRoutes();
    }
    
    setupRoutes() {
        this.registerRoute('GET', '/users', this.getUsers.bind(this));
        this.registerRoute('GET', '/users/:id', this.getUserById.bind(this));
        this.registerRoute('POST', '/users', this.createUser.bind(this));
    }
    
    async getUsers(req, res) {
        // 实现获取用户列表
    }
    
    async getUserById(req, res) {
        // 实现获取单个用户
    }
    
    async createUser(req, res) {
        // 实现创建用户
    }
}

// 2. 订单服务
class OrderService extends MicroService {
    constructor() {
        super('order-service', 3001);
        this.setupRoutes();
        this.userServiceClient = new ServiceDiscoveryClient(registry);
    }
    
    setupRoutes() {
        this.registerRoute('POST', '/orders', this.createOrder.bind(this));
        this.registerRoute('GET', '/orders/:id', this.getOrderById.bind(this));
    }
    
    async createOrder(req, res) {
        const { userId, items } = req.body;
        
        // 使用断路器调用用户服务
        const circuitBreaker = new CircuitBreaker();
        const user = await circuitBreaker.execute(async () => {
            const userService = await this.userServiceClient.getService('user-service');
            const communicator = new HttpCommunicator();
            return communicator.request(userService, 'GET', `/users/${userId}`);
        });
        
        // 创建订单逻辑
    }
}

// 3. API网关
class ApiGateway extends MicroService {
    constructor() {
        super('api-gateway', 8080);
        this.setupRoutes();
        this.loadBalancer = new LoadBalancer();
        this.registry = new ServiceRegistry();
    }
    
    setupRoutes() {
        this.app.use(this.routeRequest.bind(this));
    }
    
    async routeRequest(req, res) {
        const service = this.determineTargetService(req.path);
        const instances = await this.registry.getServiceInstances(service);
        
        if (instances.length === 0) {
            return res.status(503).json({ error: 'Service Unavailable' });
        }
        
        const target = this.loadBalancer.select('round-robin', instances, service);
        const communicator = new HttpCommunicator();
        
        try {
            const result = await communicator.request(target, req.method, req.path, req.body);
            res.json(result);
        } catch (error) {
            res.status(500).json({ error: error.message });
        }
    }
}

最佳实践建议 💡

  1. 服务设计原则

    • 保持服务的单一职责
    • 定义清晰的服务边界
    • 使用异步通信减少耦合
    • 实现适当的服务粒度
  2. 可靠性保障

    • 实现健康检查
    • 使用断路器模式
    • 实现优雅降级
    • 添加重试机制
  3. 监控与可观测性

    • 实现分布式追踪
    • 收集关键指标
    • 集中式日志管理
    • 设置适当的告警
  4. 安全性考虑

    • 服务间认证
    • API安全
    • 数据加密
    • 访问控制

结语 📝

微服务架构为构建大规模分布式系统提供了强大的解决方案。通过本文,我们学习了:

  1. 微服务的基础架构实现
  2. 服务通信和发现机制
  3. 负载均衡和容错处理
  4. 监控和日志系统
  5. 实际应用示例和最佳实践

💡 学习建议:在实施微服务架构时,要注意平衡系统的复杂性和业务需求。不是所有应用都需要微服务架构,要根据实际情况选择合适的架构方案。


如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2283603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS 权限管理:同时请求相机和麦克风权限的最佳实践

引言 在开发视频类应用时&#xff0c;我们常常会遇到需要同时请求相机和麦克风权限的场景。比如&#xff0c;在用户发布视频动态时&#xff0c;相机用于捕捉画面&#xff0c;麦克风用于录制声音&#xff1b;又或者在直播功能中&#xff0c;只有获得这两项权限&#xff0c;用户…

【深入理解FFMPEG】命令行阅读笔记

这里写自定义目录标题 第三章 FFmpeg工具使用基础3.1 ffmpeg常用命令3.1.13.1.3 转码流程 3.2 ffprobe 常用命令3.2.1 ffprobe常用参数3.2.2 ffprobe 使用示例 3.3 ffplay常用命令3.3.1 ffplay常用参数3.3.2 ffplay高级参数3.3.4 ffplay快捷键 第4章 封装与解封装4.1 视频文件转…

数据结构:二叉树—面试题(二)

1、二叉树的最近公共祖先 习题链接https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/description/ 描述&#xff1a; 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点…

【C++高并发服务器WebServer】-6:信号

本文目录 信号的概念1.1 core文件1.2 kill命令1.3 alarm函数1.4 setitimer调用1.5 signal捕捉信号1.6 信号集1.7 内核实现信号捕捉的过程1.8 sigaction1.9 sigchld 信号的概念 信号是 Linux 进程间通信的最古老的方式之一&#xff0c;是事件发生时对进程的通知机制&#xff0c…

【数据分享】1929-2024年全球站点的逐月平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff01;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2024年全球气象站点…

【PyTorch】3.张量类型转换

个人主页&#xff1a;Icomi 在深度学习蓬勃发展的当下&#xff0c;PyTorch 是不可或缺的工具。它作为强大的深度学习框架&#xff0c;为构建和训练神经网络提供了高效且灵活的平台。神经网络作为人工智能的核心技术&#xff0c;能够处理复杂的数据模式。通过 PyTorch&#xff0…

不解释快上车

聊一聊 最近有小伙伴问我有小红书图片和短视频下载的软件吗&#xff0c;我心想&#xff0c;下载那上面的图片和视频做什么&#xff1f;也许是自己没有这方面的需求&#xff0c;不了解。 不过话又说回来&#xff0c;有些很多下载器可能作者没有持续的维护&#xff0c;所以可能…

C++红黑树详解

文章目录 红黑树概念规则为什么最长路径不超过最短路径的二倍&#xff1f;红黑树的时间复杂度红黑树的结构插入叔叔节点情况的讨论只变色(叔叔存在且为红)抽象的情况变色单旋&#xff08;叔叔不存在或叔叔存在且为黑&#xff09;变色双旋&#xff08;叔叔不存在或叔叔存在且为黑…

csapp2.4节——浮点数

目录 二进制小数 十进制小数转二进制小数 IEEE浮点表示 规格化表示 非规格化表示 特殊值 舍入 浮点运算 二进制小数 类比十进制中的小数&#xff0c;可定义出二进制小数 例如1010.0101 小数点后的权重从-1开始递减。 十进制小数转二进制小数 整数部分使用辗转相除…

神经网络|(一)加权平均法,感知机和神经元

【1】引言 从这篇文章开始&#xff0c;将记述对神经网络知识的探索。相关文章都是学习过程中的感悟和理解&#xff0c;如有雷同或者南辕北辙的表述&#xff0c;请大家多多包涵。 【2】加权平均法 在数学课本和数理统计课本中&#xff0c;我们总会遇到求一组数据平均值的做法…

Spring 框架:配置缓存管理器、注解参数与过期时间

在 Spring 框架中&#xff0c;可通过多种方式配置缓存具体行为&#xff0c;常见配置方法如下。 1. 缓存管理器&#xff08;CacheManager&#xff09;配置 基于内存的缓存管理器配置&#xff08;以SimpleCacheManager为例&#xff09; SimpleCacheManager 是 Spring 提供的简单…

FPGA实现任意角度视频旋转(完结)视频任意角度旋转实现

本文主要介绍如何基于FPGA实现视频的任意角度旋转&#xff0c;关于视频180度实时旋转、90/270度视频无裁剪旋转&#xff0c;请见本专栏前面的文章&#xff0c;旋转效果示意图如下&#xff1a; 为了实时对比旋转效果&#xff0c;采用分屏显示进行处理&#xff0c;左边代表旋转…

openlayer getLayerById 根据id获取layer图层

背景&#xff1a; 在项目中使用getLayerById获取图层&#xff0c;这个getLayerById()方法不是openlayer官方文档自带的&#xff0c;而是自己封装的一个方法&#xff0c;这个封装的方法的思路是&#xff1a;遍历所有的layer&#xff0c;根据唯一标识【可能是id&#xff0c;也可能…

设计模式-建造者模式、原型模式

目录 建造者模式 定义 类图 优缺点 角色 建造者模式和工厂模式比较 使用案例 原型模式 定义 类图 优缺点 应用场景 应用类型 浅克隆 深克隆 建造者模式 定义 将一个复杂的对象的构造与它的表示分离&#xff0c;使同样的构建过程可以创建不同的表示&#xff0c;…

PTMD2.0-疾病相关的翻译后修饰数据库

翻译后修饰&#xff08;PTMs&#xff0c;post-translational modifications&#xff09;通过调节蛋白质功能参与了几乎所有的生物学过程&#xff0c;而 PTMs 的异常状态常常与人类疾病相关。在此&#xff0c;PTMD 2.0展示与疾病相关的 PTMs 综合数据库&#xff0c;其中包含 93 …

【Git版本控制器--3】Git的远程操作

目录 理解分布式版本控制系统 创建远程仓库 仓库被创建后的配置信息 克隆远程仓库 https克隆仓库 ssh克隆仓库 向远程仓库推送 拉取远程仓库 忽略特殊文件 为什么要忽略特殊文件&#xff1f; 如何配置忽略特殊文件&#xff1f; 配置命令别名 标签管理 理…

批量创建ES索引

7.x from elasticsearch import Elasticsearch# 配置 Elasticsearch 连接 # 替换为你的 Elasticsearch 地址、端口、用户名和密码 es Elasticsearch([http://10.10.x.x:43885],basic_auth(admin, XN272G9THEAPYD5N5QORX3PB1TSQELLB) )# # 测试连接 # try: # # 尝试获取集…

MySQL中的读锁与写锁:概念与作用深度剖析

MySQL中的读锁与写锁&#xff1a;概念与作用深度剖析 在MySQL数据库的并发控制机制中&#xff0c;读锁和写锁起着至关重要的作用。它们是确保数据在多用户环境下能够正确、安全地被访问和修改的关键工具。 一、读锁&#xff08;共享锁&#xff09;概念 读锁&#xff0c;也称为…

专利申请的价值

独占市场 一种产品只要授权专利权&#xff0c;等于在市场上拥有独占权。 政策奖励 各地方政府均出台响应文件&#xff0c; 对专利申请者进行奖励或者补助。 申报项目 申报高新技术企业、创新基金等 各类计划、项目的必要前提条件 专利申请 技术保护 防止新的技术与产品被他人 抄…

使用 OpenCV 和 Python 轻松实现人脸检测

目录 一、准备工作 二、加载人脸检测模型 三、读取图像并进行人脸检测 四、处理视频中的人脸检测 五、优化人脸检测效果 六、总结 在人工智能和计算机视觉领域,人脸检测是一项非常基础且重要的技术。通过人脸检测,我们可以在图像或视频中识别并定位人脸,进而进行后续的…