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

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);}}
}

高级微服务模式 🚀

// 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)}`;}
}

性能优化技巧 ⚡

// 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. 服务设计原则
// 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.rhkb.cn/news/4771.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql之基本常用的语法

mysql之基本常用的语法 1.增加数据2.删除数据3.更新/修改数据4.查询数据 4.1.where子句4.2.order by4.3.limit与offset4.4.分组与having4.5.连接 5.创建表 1.增加数据 insert into 1.指定列插入 语法&#xff1a;insert into table_name(列名1,列名2,....,列名n) values (值…

Jenkins 启动

废话 这一阵子感觉空虚&#xff0c;心里空捞捞的&#xff0c;总想找点事情做&#xff0c;即使这是一件微小的事情&#xff0c;空余时间除了骑车、打球&#xff0c;偶尔朋友聚会 … 还能干什么呢&#xff1f; 当独自一人时&#xff0c;究竟可以做点什么&#xff0c;填补这空虚…

阳振坤:AI 大模型的基础是数据,AI越发达,数据库价值越大

2024年1月12日&#xff0c;第四届OceanBase数据库大赛决赛在北京圆满落幕。在大赛的颁奖典礼上&#xff0c;OceanBase 首席科学家阳振坤老师为同学们献上了一场主题为“爱上数据库”的公开课&#xff0c;他不仅分享了个人的成长历程&#xff0c;还阐述了对数据库行业现状与未来…

麦田物语学习笔记:场景切换淡入淡出和动态UI显示

基本流程 人物在切换场景有些僵硬,所以增加淡入淡出效果 1.代码思路 (1)核心原理是控制Fade Panel中的CanvasGroup中的Alpha值的大小来实现淡入淡出的效果 (2)用协程去表示变黑或变透明 (3)人物输入被阻拦的情况下,人物却还在移动,这个问题需要解决 2.代码实现 在TransitionM…

一次理清楚Java中的日期和时间

Java中的日期和时间 概述 学习最大的问题困难在于沉下心&#xff0c;现实社会纷乱复杂&#xff0c;充满诱惑&#xff0c;同时随着成家立业年岁增长更无当年之志&#xff0c;顿感无力。回想公瑾当年之言&#xff1a;“日抚谣琴听音&#xff0c;夜有娇妻伴读&#xff0c;此生足矣…

Linux探秘坊-------3.开发工具详解(2)

1.动静态库和动静态链接&#xff08;操作&#xff09; 静态库是指编译链接时,把库⽂件的代码全部加⼊到可执⾏⽂件中,因此⽣成的⽂件 ⽐较⼤,但在运⾏时也就不再需要库⽂件了。其后缀名⼀般为“.a” 动态库与之相反,在编译链接时并 没有把库⽂件的代码加⼊到可执⾏⽂件中 ,⽽…

亲测有效!如何快速实现 PostgreSQL 数据迁移到 时序数据库TDengine

小T导读&#xff1a;本篇文章是“2024&#xff0c;我想和 TDengine 谈谈”征文活动的优秀投稿之一&#xff0c;作者从数据库运维的角度出发&#xff0c;分享了利用 TDengine Cloud 提供的迁移工具&#xff0c;从 PostgreSQL 数据库到 TDengine 进行数据迁移的完整实践过程。文章…

C语言:位段

位段的内存分配: 1. 位段的成员可以是 int unsigned int signed int 或者是char &#xff08;属于整形家族&#xff09;类型 2. 位段的空间上是按照需要以4个字节&#xff08; 类型 int &#xff09;或者1个字节&#xff08; char &#xff09;的方式来开辟的。 3. 位段涉及…

多级缓存 JVM进程缓存

目录 多级缓存 1.什么是多级缓存 2.JVM进程缓存 2.1 导入案例 2.2 初识Caffeine 2.3 实现JVM进程缓存 2.3.1 需求 2.3.2 实现 3.Lua语法入门 3.1 初识Lua 3.1 HelloWorld 3.2.变量和循环 3.2.1 Lua的数据类型 3.2.3 循环 3.3 条件控制、函数 3.3.1 函数 3.3.2 条件控制 3.3.3 案…

记录一下OpenCV Contrib 编译踩的坑

最近有需要采用OpenCV Contrib 里面的函数做一下处理&#xff0c;要重新编译&#xff0c;一路编译两三个小时了&#xff0c;记录一下备忘吧。 1、编译前先准备好如下环境 ①visual studio已安装&#xff0c;具体版本和型号根据需求经验来&#xff0c;我看常用的是VS2015、VS201…

每日一刷——1.20——准备蓝桥杯

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目一 请统计某个给定范围[L, R]的所有整数中&#xff0c;数字2出现的次数。 比如给定范围[2, 22]&#xff0c;数字2在数2中出现了1次&#xff0c;在数12中出现1次&#xff0c;在数20中出现1次&a…

整数的分离与合成

整数的分离与合成 一、整数的分离1.1 整数拆成数字的方法1.1.1 取尾法1.1.2 取头法 1.2 任意整数的分离 二、整数的合成 整数是由数字和数位组成的&#xff0c;比如327是一个三位数&#xff0c;它的数字是3、2、7,数位是个数、十位、百位。 经常有些题目考查将一个整数拆分成各…

动态规划(多状态)

面试题 17.16. 按摩师 面试题 17.16. 按摩师 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int massage(vector<int>& nums) {int n nums.size();//特殊情况&#xff1a;空数组if(n0)return 0;vector<int> f(n);vector<int> g(n);…

【json_object】mysql中json_object函数过长,显示不全

问题&#xff1a;json只显示部分 解决&#xff1a; SET GLOBAL group_concat_max_len 1000000; -- 设置为1MB&#xff0c;根据需要调整如果当前在navicat上修改&#xff0c;只有效本次连接和后续会话&#xff0c;重新连接还是会恢复默认值1024 在my.ini配置文件中新增或者修…

ElasticSearch DSL查询之高亮显示

什么是高亮显示&#xff1f; 高亮显示是指在搜索结果中&#xff0c;将用户搜索的关键字突出显示&#xff0c;使其更为醒目。以百度搜索为例&#xff0c;当用户搜索“JAVA”时&#xff0c;搜索结果中的标题或概述部分会将“JAVA”高亮显示&#xff0c;通常以红色标出&#xff0…

WGAN - 瓦萨斯坦生成对抗网络

1. 背景与问题 生成对抗网络&#xff08;Generative Adversarial Networks, GANs&#xff09;是由Ian Goodfellow等人于2014年提出的一种深度学习模型。它包括两个主要部分&#xff1a;生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discriminator&#xff09;…

低代码系统-产品架构案例介绍(五)

接上篇&#xff0c;某搭介绍。 某搭以低代码为核心驱动&#xff0c;利用AI能力强势推动应用深度体验&#xff0c;打通钉钉对接&#xff0c;且集成外部系统。 可以看出&#xff0c;某搭在未来的规划上&#xff0c;着重在于AI 也就说明&#xff0c;低代码产品在未来的竞争上&…

嵌入式知识点总结 ARM体系与架构 专题提升(一)-硬件基础

嵌入式知识点总结 ARM体系与架构 专题提升(一)-硬件基础 目录 1.NAND FLASH 和NOR FLASH异同 ? 2.CPU,MPU,MCU,SOC,SOPC联系与差别? 3.什么是交叉编译&#xff1f; 4.为什么要交叉编译&#xff1f; 5.描述一下嵌入式基于ROM的运行方式和基于RAM的运行方式有什么区别? 1…

学习记录之原型,原型链

构造函数创建对象 Person和普通函数没有区别&#xff0c;之所以是构造函数在于它是通过new关键字调用的&#xff0c;p就是通过构造函数Person创建的实列对象 function Person(age, name) {this.age age;this.name name;}let p new Person(18, 张三);prototype prototype n…

迈向 “全能管家” 之路:机器人距离终极蜕变还需几步?

【图片来源于网络&#xff0c;侵删】 这是2024年初Figure公司展示的人形机器人Figure 01&#xff0c;他可以通过观看人类的示范视频&#xff0c;在10小时内经过训练学会煮咖啡&#xff0c;并且这个过程是完全自主没有人为干涉的&#xff01; 【图片来源于网络&#xff0c;侵删】…