JavaScript系列(36)--微服务架构详解

devtools/2025/1/21 18:20:27/

JavaScript微服务架构详解 🏗️

今天,让我们深入了解JavaScript的微服务架构,这是构建大规模分布式系统的关键技术。

微服务基础概念 🌟

💡 小知识:微服务架构是一种将应用程序构建为一组小型服务的方法,每个服务运行在自己的进程中,并使用轻量级机制进行通信。

基本微服务实现 📊

javascript">// 1. 服务注册中心
class ServiceRegistry {constructor() {this.services = new Map();this.healthChecks = new Map();}register(serviceName, instance) {if (!this.services.has(serviceName)) {this.services.set(serviceName, new Set());}this.services.get(serviceName).add(instance);this.setupHealthCheck(serviceName, instance);console.log(`Service ${serviceName} registered: ${instance.url}`);}deregister(serviceName, instance) {if (this.services.has(serviceName)) {this.services.get(serviceName).delete(instance);this.healthChecks.delete(instance.url);console.log(`Service ${serviceName} deregistered: ${instance.url}`);}}getInstances(serviceName) {return Array.from(this.services.get(serviceName) || []);}setupHealthCheck(serviceName, instance) {const healthCheck = setInterval(async () => {try {const response = await fetch(`${instance.url}/health`);if (!response.ok) {throw new Error('Health check failed');}} catch (error) {console.error(`Health check failed for ${instance.url}:`, error);this.deregister(serviceName, instance);}}, 30000); // 每30秒检查一次this.healthChecks.set(instance.url, healthCheck);}
}// 2. 负载均衡器
class LoadBalancer {constructor() {this.algorithms = {'round-robin': this.roundRobin.bind(this),'random': this.random.bind(this),'least-connections': this.leastConnections.bind(this)};this.currentIndex = 0;this.connectionCounts = new Map();}roundRobin(instances) {if (instances.length === 0) return null;const instance = instances[this.currentIndex];this.currentIndex = (this.currentIndex + 1) % instances.length;return instance;}random(instances) {if (instances.length === 0) return null;const randomIndex = Math.floor(Math.random() * instances.length);return instances[randomIndex];}leastConnections(instances) {if (instances.length === 0) return null;let minConnections = Infinity;let selectedInstance = null;for (const instance of instances) {const connections = this.connectionCounts.get(instance.url) || 0;if (connections < minConnections) {minConnections = connections;selectedInstance = instance;}}return selectedInstance;}incrementConnections(instance) {const current = this.connectionCounts.get(instance.url) || 0;this.connectionCounts.set(instance.url, current + 1);}decrementConnections(instance) {const current = this.connectionCounts.get(instance.url) || 0;if (current > 0) {this.connectionCounts.set(instance.url, current - 1);}}
}// 3. API网关
class APIGateway {constructor(serviceRegistry, loadBalancer) {this.serviceRegistry = serviceRegistry;this.loadBalancer = loadBalancer;this.middlewares = [];}use(middleware) {this.middlewares.push(middleware);}async handleRequest(req) {// 执行中间件for (const middleware of this.middlewares) {await middleware(req);}const serviceName = this.extractServiceName(req.path);const instances = this.serviceRegistry.getInstances(serviceName);if (instances.length === 0) {throw new Error(`No instances available for service: ${serviceName}`);}const instance = this.loadBalancer.roundRobin(instances);return this.forwardRequest(instance, req);}extractServiceName(path) {// 从路径中提取服务名return path.split('/')[1];}async forwardRequest(instance, req) {this.loadBalancer.incrementConnections(instance);try {const response = await fetch(`${instance.url}${req.path}`, {method: req.method,headers: req.headers,body: req.body});return response;} finally {this.loadBalancer.decrementConnections(instance);}}
}

高级微服务模式 🚀

javascript">// 1. 断路器模式
class CircuitBreaker {constructor(service, options = {}) {this.service = service;this.options = {failureThreshold: 5,resetTimeout: 60000,...options};this.state = 'CLOSED';this.failures = 0;this.lastFailureTime = null;}async execute(request) {if (this.state === 'OPEN') {if (this.shouldReset()) {this.halfOpen();} else {throw new Error('Circuit breaker is OPEN');}}try {const response = await this.service.execute(request);this.onSuccess();return response;} catch (error) {this.onFailure();throw error;}}onSuccess() {this.failures = 0;this.state = 'CLOSED';}onFailure() {this.failures++;this.lastFailureTime = Date.now();if (this.failures >= this.options.failureThreshold) {this.state = 'OPEN';}}shouldReset() {return Date.now() - this.lastFailureTime >= this.options.resetTimeout;}halfOpen() {this.state = 'HALF-OPEN';this.failures = 0;}
}// 2. 服务网格
class ServiceMesh {constructor() {this.proxies = new Map();this.metrics = new Map();}addProxy(serviceName, instance) {const proxy = new ServiceProxy(instance);if (!this.proxies.has(serviceName)) {this.proxies.set(serviceName, new Set());}this.proxies.get(serviceName).add(proxy);this.initializeMetrics(proxy);return proxy;}initializeMetrics(proxy) {this.metrics.set(proxy, {requests: 0,errors: 0,latency: []});}async routeRequest(serviceName, request) {const proxySet = this.proxies.get(serviceName);if (!proxySet || proxySet.size === 0) {throw new Error(`No proxies available for service: ${serviceName}`);}const proxy = Array.from(proxySet)[0]; // 简单选择第一个代理const metrics = this.metrics.get(proxy);const startTime = Date.now();metrics.requests++;try {const response = await proxy.forward(request);metrics.latency.push(Date.now() - startTime);return response;} catch (error) {metrics.errors++;throw error;}}getMetrics(serviceName) {const proxySet = this.proxies.get(serviceName);if (!proxySet) return null;const serviceMetrics = {totalRequests: 0,totalErrors: 0,averageLatency: 0};for (const proxy of proxySet) {const metrics = this.metrics.get(proxy);serviceMetrics.totalRequests += metrics.requests;serviceMetrics.totalErrors += metrics.errors;if (metrics.latency.length > 0) {const sum = metrics.latency.reduce((a, b) => a + b, 0);serviceMetrics.averageLatency += sum / metrics.latency.length;}}return serviceMetrics;}
}// 3. 分布式追踪
class DistributedTracer {constructor() {this.traces = new Map();this.spans = new Map();}startTrace(traceId = this.generateTraceId()) {const trace = {id: traceId,startTime: Date.now(),spans: []};this.traces.set(traceId, trace);return traceId;}startSpan(traceId, spanId = this.generateSpanId(), parentSpanId = null) {const span = {id: spanId,traceId,parentSpanId,startTime: Date.now(),events: []};this.spans.set(spanId, span);this.traces.get(traceId).spans.push(span);return spanId;}addEvent(spanId, event) {const span = this.spans.get(spanId);if (span) {span.events.push({timestamp: Date.now(),...event});}}endSpan(spanId) {const span = this.spans.get(spanId);if (span) {span.endTime = Date.now();span.duration = span.endTime - span.startTime;}}endTrace(traceId) {const trace = this.traces.get(traceId);if (trace) {trace.endTime = Date.now();trace.duration = trace.endTime - trace.startTime;return this.generateTraceReport(trace);}}generateTraceReport(trace) {return {traceId: trace.id,duration: trace.duration,spans: trace.spans.map(span => ({id: span.id,parentId: span.parentSpanId,duration: span.duration,events: span.events}))};}generateTraceId() {return `trace-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;}generateSpanId() {return `span-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;}
}

性能优化技巧 ⚡

javascript">// 1. 缓存管理器
class CacheManager {constructor(options = {}) {this.options = {maxSize: 1000,ttl: 3600000, // 1小时...options};this.cache = new Map();this.accessLog = new Map();}set(key, value, ttl = this.options.ttl) {this.ensureCapacity();const entry = {value,expires: Date.now() + ttl};this.cache.set(key, entry);this.accessLog.set(key, Date.now());}get(key) {const entry = this.cache.get(key);if (!entry) return null;if (Date.now() > entry.expires) {this.cache.delete(key);this.accessLog.delete(key);return null;}this.accessLog.set(key, Date.now());return entry.value;}ensureCapacity() {if (this.cache.size >= this.options.maxSize) {// 删除最少访问的条目const entries = Array.from(this.accessLog.entries());entries.sort((a, b) => a[1] - b[1]);const keyToDelete = entries[0][0];this.cache.delete(keyToDelete);this.accessLog.delete(keyToDelete);}}clear() {this.cache.clear();this.accessLog.clear();}
}// 2. 请求合并器
class RequestBatcher {constructor(options = {}) {this.options = {maxBatchSize: 100,maxDelay: 50,...options};this.batch = [];this.timer = null;}async add(request) {return new Promise((resolve, reject) => {this.batch.push({request,resolve,reject});if (this.batch.length >= this.options.maxBatchSize) {this.flush();} else if (!this.timer) {this.timer = setTimeout(() => this.flush(), this.options.maxDelay);}});}async flush() {if (this.batch.length === 0) return;const currentBatch = this.batch;this.batch = [];if (this.timer) {clearTimeout(this.timer);this.timer = null;}try {const results = await this.processBatch(currentBatch);currentBatch.forEach((item, index) => {item.resolve(results[index]);});} catch (error) {currentBatch.forEach(item => {item.reject(error);});}}async processBatch(batch) {// 实现批处理逻辑return Promise.all(batch.map(item => this.processRequest(item.request)));}async processRequest(request) {// 实现单个请求处理逻辑return request;}
}// 3. 性能监控器
class PerformanceMonitor {constructor() {this.metrics = {requestCount: 0,errorCount: 0,responseTime: [],cpuUsage: [],memoryUsage: []};this.startMonitoring();}startMonitoring() {setInterval(() => {this.collectMetrics();}, 5000); // 每5秒收集一次}collectMetrics() {const metrics = process.metrics();this.metrics.cpuUsage.push({timestamp: Date.now(),value: metrics.cpu.usage});this.metrics.memoryUsage.push({timestamp: Date.now(),value: process.memoryUsage().heapUsed});// 保持最近1小时的数据this.pruneMetrics();}recordRequest(duration, isError = false) {this.metrics.requestCount++;if (isError) this.metrics.errorCount++;this.metrics.responseTime.push({timestamp: Date.now(),value: duration});}pruneMetrics() {const oneHourAgo = Date.now() - 3600000;['cpuUsage', 'memoryUsage', 'responseTime'].forEach(metric => {this.metrics[metric] = this.metrics[metric].filter(item => item.timestamp > oneHourAgo);});}getMetrics() {return {requestCount: this.metrics.requestCount,errorCount: this.metrics.errorCount,errorRate: this.metrics.errorCount / this.metrics.requestCount,averageResponseTime: this.calculateAverage(this.metrics.responseTime),averageCpuUsage: this.calculateAverage(this.metrics.cpuUsage),averageMemoryUsage: this.calculateAverage(this.metrics.memoryUsage)};}calculateAverage(metrics) {if (metrics.length === 0) return 0;const sum = metrics.reduce((acc, item) => acc + item.value, 0);return sum / metrics.length;}
}

最佳实践建议 💡

  1. 服务设计原则
javascript">// 1. 服务隔离
class ServiceIsolation {constructor(service) {this.service = service;this.circuitBreaker = new CircuitBreaker(service);this.bulkhead = new Bulkhead(10); // 限制并发请求数}async execute(request) {return this.bulkhead.execute(() => this.circuitBreaker.execute(request));}
}// 2. 服务发现
class ServiceDiscovery {constructor(registry) {this.registry = registry;this.cache = new Map();this.cacheTimeout = 30000; // 30秒缓存}async getService(name) {const cached = this.cache.get(name);if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {return cached.service;}const service = await this.registry.lookup(name);this.cache.set(name, {service,timestamp: Date.now()});return service;}
}// 3. 配置管理
class ConfigurationManager {constructor() {this.configs = new Map();this.watchers = new Map();}set(key, value) {this.configs.set(key, value);this.notifyWatchers(key, value);}get(key) {return this.configs.get(key);}watch(key, callback) {if (!this.watchers.has(key)) {this.watchers.set(key, new Set());}this.watchers.get(key).add(callback);}notifyWatchers(key, value) {const watchers = this.watchers.get(key);if (watchers) {watchers.forEach(callback => callback(value));}}
}

结语 📝

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

  1. 微服务的基本概念和实现方法
  2. 高级微服务模式和最佳实践
  3. 性能优化和监控技术
  4. 服务隔离和容错处理
  5. 配置管理和服务发现

💡 学习建议:在实践微服务架构时,要特别注意服务的隔离性和容错性。合理使用断路器、服务发现等模式,可以显著提升系统的可靠性和可维护性。


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

终身学习,共同成长。

咱们下一期见

💻


http://www.ppmy.cn/devtools/152398.html

相关文章

快速开发:用AI构造AI —— 打造属于个人的Copilot(M-聪明AI)

作品简介&#xff1a; 当今快速发展的AI时代&#xff0c;学会使用AI的同时&#xff0c;也可以融入AI&#xff0c;来打造自己的产品&#xff0c;我给我这个取名M-聪明&#xff0c; 是基于VUE 3 Spring Boot -Redis ChatGML RxJava SSE 的AI 服务平台。然后这款工具旨在为用户…

imbinarize函数用法详解与示例

一、函数概述 众所周知&#xff0c;im2bw函数可以将灰度图像转换为二值图像。但MATLAB中还有一个imbinarize函数可以将灰度图像转换为二值图像。imbinarize函数是MATLAB图像处理工具箱中用于将灰度图像或体数据二值化的工具。它可以通过全局或自适应阈值方法将灰度图像转换为二…

mac m4 安装 node

brew install node // 安装 node //安装的路径在&#xff1a; /opt/homebrew/bin/node brew install node14 // brew install node22 // 安装指定版本 如果需要设置环境变量&#xff1a;通过&#xff1a; which node 查找路径 export PATH"/usr/local/opt/…

Python基于OpenCV和PyQt5的人脸识别上课签到系统【附源码】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

什么是HTTP3?

要想讲清楚HTTP3是什么&#xff0c;就不得不先说下HTTP2&#xff0c;而要说清楚什么是HTTP2&#xff0c;就不得不介绍HTTP1。正所谓&#xff1a;计算机软件没有银弹&#xff0c;每项新技术都是解决了旧技术的问题&#xff0c;而又引入了新的问题。所以我们从HTTP1开始讲的话&am…

《汽车维修技师》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答&#xff1a; 问&#xff1a;《汽车维修技师》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊。 问&#xff1a;《汽车维修技师》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;北方联合出版传媒&#xff08;…

湖仓一体架构解析:数仓架构选择(第48天)

系列文章目录 1、Lambda 架构 2、Kappa 架构 3、混合架构 4、架构选择 5、实时数仓现状 6、湖仓一体架构 7、流批一体架构 文章目录 系列文章目录前言1、Lambda 架构2、Kappa 架构3、混合架构4、架构选择5、实时数仓现状6、湖仓一体架构7、流批一体架构 前言 本文解析了Lam…

警惕IDEA 2024版重大Bug问题:LomBok失效、Gradle冲突、Spring Boot启动错误

一直以来我认为工具类的软件是越新越好&#xff0c;因为工具代表着一定的先进性&#xff1b;但是IDEA 2024好好的给我上了一课&#xff0c;比如lombok 不起作用、比如Spring Boot 3.4.x 启动报错、再比如MyBatis log plus冲突、再比如Gradle插件冲突. 一、Lombok 失效问题 请不…