微服务设计原则——高性能:异步与并发

文章目录

  • 1.异步
    • [1.1 调用异步](#1.1 调用异步)
    • [1.2 流程异步](#1.2 流程异步)
    • [1.3 数据流异步](#1.3 数据流异步)
    • [1.4 小结](#1.4 小结)
  • 2.并发
    • [2.1 请求并发](#2.1 请求并发)
    • [2.2 冗余请求](#2.2 冗余请求)
    • [2.3 小结](#2.3 小结)
  • 参考文献

1.异步

对于处理耗时长的任务,如果采用同步等待的方式,会严重降低系统的吞吐量,可以采用异步化进行解决。

异步(Asynchronous)是一种编程模型或执行方式,在这种方式中,任务的启动和完成不是同步的,也就是说,程序不会在等待任务完成时阻塞,而是可以继续执行其他操作。当异步任务完成时,程序会通过回调、通知或事件的方式获取结果或处理后续操作。

1.1 调用异步

异步调用发生在使用异步编程模型来提高代码效率的时候,实现方式主要有:

  • Callback

异步回调通过注册一个回调函数,然后发起异步任务,当任务执行完毕时会回调用户注册的回调函数,从而减少调用端等待时间。这种方式会造成代码分散难以维护,定位问题也相对困难。

  • Promise 和 Future

当用户提交一个任务时会立刻先返回一个Future,然后任务异步执行,后续可以通过 Future 获取执行结果。

JavaScript 中的 Promise 和 Java 中的 CompletableFuture 都是常见的异步处理方式。

js 复制代码
// 使用 Promise 处理异步操作
let promise = new Promise((resolve, reject) => {
  // 模拟异步操作
  setTimeout(() => resolve('Operation complete'), 1000);
});

promise.then(result => console.log(result));  // 输出: "Operation complete"
  • Async/Await

Async/Await 是对 Promise 的进一步封装,提供了更简洁、更易读的异步代码写法。使用 async 标记的函数会返回一个 Promise,而 await 关键字用于暂停函数的执行,直到 Promise 处理完成。

JavaScript 和 Python 都支持 async/await 语法。

js 复制代码
async function fetchData() {
  let response = await fetch('https://api.example.com/data');
  let data = await response.json();
  console.log(data);
}

fetchData();
  • 事件驱动

事件驱动模型常用于 GUI 编程和服务器端编程,通过事件触发异步操作的处理。

比如 Node.js 通过事件驱动模型来处理异步 I/O 操作。

js 复制代码
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();

// 定义事件处理程序
eventEmitter.on('dataReceived', (data) => {
  console.log('Data received:', data);
});

// 模拟异步数据接收
setTimeout(() => eventEmitter.emit('dataReceived', 'Sample Data'), 1000);

可以对多个异步编程进行编排,组成更复杂的异步处理,并以同步的代码调用形式实现异步效果。

CPS 将后续的处理逻辑当作参数传递给 Then 并可以最终捕获异常,解决了异步回调代码散乱和异常跟踪难的问题。Java 中的 CompletableFuture 和 C++ PPL(Parallel Patterns Library)基本支持这一特性。典型的调用形式如下:

cpp 复制代码
void handleRequest(const Request &req) {
  return req.Read().Then([](Buffer &inbuf){
      return handleData(inbuf);
  }).Then([](Buffer &outbuf){
      return handleWrite(outbuf);
  }).Finally(){
      return cleanUp();
  });
}

关于 CPS 更多信息推荐阅读:2018 中国 C++ 大会的吴锐_C++服务器开发实践部分

调用异步是一种异步编程模型,通过允许任务非阻塞地执行,使程序在等待某些操作(如 I/O 操作)完成的同时,能够继续处理其他任务,从而提高并发性和性能。常见的实现方式包括回调函数、Promise/Future、Async/Await,以及事件驱动模型等。

1.2 流程异步

一个业务流程往往伴随着调用链路长、后置依赖多等特点,导致业务流程处理耗时长,降低了系统的可用性和并发处理能力。

同步改异步,可以降低主链路的处理耗时。

举个例子,比如我们去 KFC 点餐,遇到排队的人很多,当点完餐后,大多情况下我们会隔几分钟就去问好了没,反复去问了好几次才拿到,在这期间我们也没法干活了。

这个就叫同步轮训,这样效率太低了。

服务员被问烦了,就在点完餐后给我们一个号码牌,每次准备好了就会在服务台叫号,这样我们就可以在被叫到的时候再去取餐,中途可以继续干自己的事。这就叫异步。

当一个微服务需要处理大量的请求或任务时,直接处理这些任务可能导致服务压力过大。通过消息队列(如 Kafka、RabbitMQ、RocketMQ 等)对耗时的任务进行异步化。

微服务将任务消息发送到消息队列中,另一个处理服务从队列中取出任务异步处理。这样可以解耦服务,提升系统的弹性和扩展性。

1.3 数据流异步

处理大量实时数据流(如日志数据、传感器数据)。

使用流处理框架(如 Apache Flink、Spark Streaming)来异步处理数据流。数据被实时处理和分析,结果可以用于实时监控和决策。

1.4 小结

在微服务架构中,异步处理可以显著提高系统的性能和扩展性。通过异步编程模型、消息队列、数据流异步处理,微服务可以更高效地处理并发请求、管理任务和优化资源利用。异步编程不仅提升了系统的响应速度,还增强了系统的灵活性和可扩展性。

2.并发

在微服务架构中,并发处理是提升系统性能和响应能力的关键技术。并发使得系统能够同时处理多个任务或请求,显著提高吞吐量和资源利用率。

2.1 请求并发

如果一个任务需要处理多个子任务,可以将没有依赖关系的子任务并发化,这种场景在后台开发很常见。

如一个请求需要查询 3 个数据,分别耗时 T1、T2、T3,如果串行调用总耗时 T=T1+T2+T3。对三个任务执行并发,总耗时 T=max(T1,T 2,T3)。同理,写操作也如此。对于同种请求,还可以同时进行批量合并,减少 RPC 次数。

2.2 冗余请求

冗余请求指同时向后端服务发送多个同样的请求,谁响应快就是使用谁,其他的则丢弃。

这种策略缩短了主调方的等待时间,但也使整个系统调用量猛增,一般适用于初始化或者请求少的场景。比如腾讯的移动连通服务维纳斯(WNS,Wireless Network Service)的跑马模块其实就是这种机制,跑马模块为了快速建立长连接同时向后台多个 IP/Port 发起请求,谁快就用谁,这在弱网的移动设备上特别有用,如果使用等待超时再重试的机制,无疑将大大增加用户的等待时间。

这种方式较少使用,知道即可。

2.3 小结

并发在微服务架构中通过多线程/多进程、异步 I/O、并行计算和流处理等方式,显著提升了系统的处理能力和性能。它能够有效地处理大量并发请求和数据流,优化资源利用率,并提高系统的响应速度和吞吐量。通过合理应用并发技术,微服务系统可以更好地应对高负载和高并发的挑战。


参考文献

服务高并发、高性能、高可用实现方案- 杨岂

相关推荐
你喜欢喝可乐吗?14 分钟前
RuoYi-Cloud 验证码处理流程
java·spring cloud·微服务·vue
Kookoos16 小时前
ABP VNext + .NET Minimal API:极简微服务快速开发
后端·微服务·架构·.net·abp vnext
小安运维日记2 天前
CKS认证 | Day4 最小化微服务漏洞
安全·docker·微服务·云原生·容器·kubernetes
Code季风2 天前
将 gRPC 服务注册到 Consul:从配置到服务发现的完整实践(上)
数据库·微服务·go·json·服务发现·consul
Code季风2 天前
微服务分布式配置中心:Gin Web 服务层与 gRPC 服务层集成 Nacos 实战
分布式·微服务·rpc·架构·go·gin·consul
步、步、为营2 天前
.net微服务框架dapr保存和获取状态
微服务·架构·.net
guojl2 天前
微服务OpenFeign源码分析
spring cloud·微服务
guojl2 天前
微服务OpenFeign使用手册
spring cloud·微服务
Code季风3 天前
Gin Web 层集成 Viper 配置文件和 Zap 日志文件指南(下)
前端·微服务·架构·go·gin