微服务系统面经之四: 以秒杀系统为例 - 用户秒杀状态的通知【京东支付后端一面】

5 篇文章 0 订阅

28 秒杀状态相关

28.1 对于一个秒杀系统,用户点击秒杀按钮后,怎么才能知道其秒杀状态?【京东支付后端一面】

对于秒杀系统,用户点击秒杀按钮后,确定其秒杀状态的过程通常包含以下几个关键步骤:

  1. 请求处理

    • 用户点击秒杀按钮后,前端会向服务器发送一个秒杀请求。
    • 为了应对高并发,通常使用负载均衡等技术将请求分发到多个服务器。
  2. 身份验证和参数校验

    • 服务器首先验证用户身份和请求的有效性,例如,检查用户是否登录、请求参数是否合法。
  3. 读取库存状态

    • 服务器查询当前商品的库存量。
    • 为了提高性能,库存数据可能存储在快速的缓存系统中,如 Redis。
  4. 判断库存

    • 如果库存足够,进入下一步;如果库存不足,直接返回“秒杀失败”状态。
  5. 库存扣减

    • 对库存进行扣减处理。
    • 这个操作需要保证原子性,防止超卖现象。
  6. 生成订单

    • 库存扣减成功后,生成秒杀订单。
    • 订单信息通常会被写入数据库。
  7. 【本节考察的重点】返回状态

    • 服务器向用户返回秒杀成功的消息。
    • 在高并发情况下,这一过程可能通过异步消息系统进行。
  8. 后续处理

    • 包括支付处理、订单超时监测等。
  9. 异常处理

    • 系统需要妥善处理各类异常情况,例如库存锁定失败、数据库写入失败等。

28.2 返回状态:服务器向用户返回秒杀成功的消息。在高并发情况下,这一过程可能通过异步消息系统进行。详细说说?

在秒杀系统中,尤其是在高并发的场景下,使用异步消息系统来处理和返回用户的秒杀状态可以极大地提高系统的性能和响应速度。以下是详细的解释:

28.2.1 为何使用异步消息系统?

  1. 降低系统压力

    • 在高并发情况下,同步处理所有的秒杀请求和立即返回状态会给服务器带来巨大压力,可能导致响应延迟甚至系统崩溃。
    • 异步处理允许系统先快速响应用户请求,然后在后台处理复杂的业务逻辑。
  2. 提高用户体验

    • 用户在提交秒杀请求后不需要等待整个处理过程完成,即可得到一个初步的响应(如“请求已提交”)。
    • 用户可以继续其他操作或者在客户端轮询/等待最终结果。
  3. 提升系统伸缩性

    • 异步消息系统允许分布式处理,易于横向扩展,有助于处理更多的用户请求。

28.2.2 异步消息系统的工作流程

  1. 请求接收

    • 用户提交秒杀请求后,服务器立即返回一个预处理响应,如“请求已接收,正在处理中”。
  2. 消息队列

    • 请求被放入消息队列中。消息队列起到缓冲的作用,平衡请求处理的负载。
    • 可以使用如 RabbitMQ、Kafka 等消息中间件。
  3. 后台处理

    • 后台服务不断从消息队列中拉取请求并处理,如库存扣减、订单生成等。
    • 这个处理过程可以分布在多个服务器或服务实例上。
  4. 返回最终结果

    • 处理完成后,最终结果(如“秒杀成功”或“秒杀失败”)通过异步方式返回给用户。
    • 这可以通过 WebSocket、服务端事件(SSE)、轮询等方式实现。

28.2.3 总结

使用异步消息系统,在用户发起秒杀请求后,可以迅速响应,然后在后台异步处理请求,并最终将处理结果返回给用户。这种方式不仅提高了系统的处理能力和伸缩性,还能提供更好的用户体验。在设计秒杀系统时,异步处理机制是提高系统性能的关键之一。

28.3 处理完成后,最终结果(如“秒杀成功”或“秒杀失败”)通过异步方式返回给用户。这可以通过 WebSocket、服务端事件(SSE)、轮询等方式实现。再讲解一下?

当秒杀系统后台完成处理后,将最终结果(例如“秒杀成功”或“秒杀失败”)异步地返回给用户,可以通过几种不同的技术来实现,主要包括 WebSocket、服务端事件(Server-Sent Events, SSE)和轮询。下面是这些技术的详细讲解:

28.3.1 WebSocket

  1. 原理:WebSocket 提供了全双工通信机制,允许服务器和客户端之间建立持久的连接,并随时发送消息。
  2. 应用:在秒杀场景中,一旦用户提交了秒杀请求,客户端(如网页或移动应用)通过 WebSocket 与服务器建立连接。服务器在处理完秒杀请求后,可以立即通过这个连接将结果推送给客户端。
  3. 优点:提供实时、双向的通信,适用于需要快速响应的场景。

28.3.2 服务端发送事件(Server-Sent Events, SSE)

  1. 原理:SSE 允许服务器主动向客户端发送新的数据流。与 WebSocket 不同,SSE 是单向通信,仅服务器向客户端发送数据。
  2. 应用:在秒杀系统中,服务器可以通过 SSE 将秒杀结果实时发送给客户端,而客户端无需发送请求即可接收数据。
  3. 优点:简单易用,适合于只需要服务器单向推送数据的场景。

28.3.3 轮询(polling)

  1. 原理:轮询是一种最传统的技术,客户端定期向服务器发送请求以询问最新的状态。
  2. 应用:用户提交秒杀请求后,客户端开始周期性地向服务器发送查询请求,直到收到秒杀结果。
  3. 优点与缺点:轮询实现简单,兼容性好,但效率相对较低,可能存在延迟,并且对服务器造成一定的负担。

28.3.4 总结

  • WebSocketSSE 更适合需要实时通信的场景,如秒杀系统,它们可以减少延迟并提高用户体验。
  • 轮询 更适合简单应用或对实时性要求不高的场景。尽管它的效率相对较低,但在一些场景中仍然是一个可行的解决方案。

在选择合适的技术时,需要根据应用的具体需求和现有架构来决定。例如,WebSocket 和 SSE 需要服务器和客户端支持长连接,而轮询则对服务器的并发处理能力有一定要求。

28.4 WebSocket和SSE技术这两者在性能上有什么区别?哪一个更消耗资源呢?

WebSocket 和 Server-Sent Events (SSE) 在性能和资源消耗方面有一些关键区别,这些区别通常取决于应用场景和通信的性质:

28.4.1 WebSocket

  • 全双工通信:WebSocket 提供全双工通信,即客户端和服务器可以同时发送和接收消息。这种通信方式非常适合实时互动和高频数据交换的场景。
  • 资源消耗:由于维持了一个持久的连接,WebSocket 可能在某些场景下会消耗更多资源。服务器需要为每个客户端保持一个打开的连接,这在大量用户同时在线的情况下可能会占用更多的内存和网络资源。
  • 适用场景:需要频繁、双向通信的场景,如在线游戏、实时聊天等。

28.4.2 Server-Sent Events (SSE)

  • 单向通信:SSE 是一种单向通信,只允许服务器推送数据到客户端。客户端不能通过 SSE 连接发送数据给服务器(需要使用其他方式,如 AJAX 请求)。
  • 资源消耗:SSE 通常在服务器端的资源消耗上比 WebSocket 要少,因为它仅支持单向通信。对于不需要客户端向服务器发送消息的应用来说,SSE 可能是一个更轻量的选择。
  • 适用场景:只需要服务器单向推送的场景,如股票价格更新、新闻订阅等。

28.4.3 性能对比(重点)

  • 连接维持WebSocket 需要维持一个持久的双向连接,而 SSE 只需维持单向连接(维持双向连接意味着同时双方都需要read和write buffer以及双工连接的建立和释放过程)。因此,在大规模并发连接的环境下,WebSocket 可能对服务器造成较高压力。
  • 网络延迟和吞吐量:WebSocket 由于是双向的,对于需要快速响应的双向数据传输更为有效。SSE 在单向数据流中表现更好,特别是当消息主要从服务器到客户端时。

28.4.4 结论

  • 如果应用需要双向通信且频繁交互,WebSocket 可能是更好的选择,尽管可能会消耗更多资源。
  • 如果应用仅需要服务器向客户端推送数据,并且对服务器资源使用有较严格的要求,SSE 可能是一个更高效的选项。

在选择时,还需要考虑服务器的负载能力、客户端的需求以及应用的特定场景。

28.5 对于我提到的秒杀系统的秒杀成功的通知,选用websoket还是sse?

对于秒杀系统来说,选择 WebSocket 还是 SSE 主要取决于系统的具体需求和架构。考虑到秒杀场景的特点,下面是一些决策因素:

28.5.1 使用 WebSocket 的考虑因素:

  1. 双向通信需求:如果您的系统除了发送秒杀结果之外,还需要实现客户端到服务器的实时通信(例如,实时更新用户的出价、聊天等),那么 WebSocket 是更好的选择。

  2. 高频更新:如果秒杀系统涉及到频繁的状态更新,如实时库存显示,WebSocket 由于其低延迟特性可能更适合。

  3. 连接维持:WebSocket 需要在客户端和服务器之间维持一个持久的连接,这可能在资源上更加昂贵,特别是当有大量用户同时在线时。

28.5.2 使用 SSE 的考虑因素:(解答京东支付面试官的问题)

  1. 单向数据流如果秒杀系统只需要服务器向客户端推送消息(例如,仅通知秒杀结果),SSE 是一个简单而高效的选择

  2. 资源效率:相比于 WebSocket,SSE 在服务器端通常更加轻量,因为它只涉及单向通信,并且连接的维护开销较低。

  3. 易于实现和维护:SSE 在某些情况下比 WebSocket 更容易实现和维护,特别是当应用的主要需求是单向数据流时。

结论

  • 如果秒杀系统需要的是一种简单的单向通知机制,且希望尽可能节省服务器资源,那么 SSE 可能是更合适的选择。
  • 如果秒杀系统的需求超出了单纯的通知,例如需要实现双向实时交互,则 WebSocket 更加适合。

在做出选择时,还需要考虑系统的整体架构、预期的用户规模、以及服务器资源等因素。在某些情况下,也可以考虑将这两种技术结合使用,以满足不同的业务需求。

28.6 websokcet技术在springboot中的代码是如何实现的呢

在 Spring Boot 中实现 WebSocket 通信涉及几个关键步骤。以下是一个简化的示例,展示如何在 Spring Boot 应用中设置 WebSocket 以用于秒杀系统通知。

1. 添加依赖

首先,在 pom.xml 文件中添加 Spring WebSocket 的依赖:

<dependencies>
    <!-- Spring WebSocket Dependency -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <!-- 其他依赖... -->
</dependencies>

2. 配置 WebSocket

创建一个配置类来启用和配置 WebSocket:

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app");
    }
}

在这里,我们配置了一个 STOMP(Simple Text Oriented Messaging Protocol)端点 /websocket 并启用了 SockJS 作为备选选项。我们还设置了一个简单的消息代理,它将在 /topic 前缀下广播消息。

3. 创建 WebSocket 控制器

创建一个控制器来处理 WebSocket 消息:

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class WebSocketController {

    @MessageMapping("/seckill")
    @SendTo("/topic/seckillResult")
    public String handleSeckill(String seckillInfo) {
        // 处理秒杀逻辑...
        // 返回秒杀结果
        return "Seckill result for " + seckillInfo;
    }
}

在这个控制器中,当客户端发送消息到 /app/seckill 时,将触发 handleSeckill 方法,并将返回的消息广播到 /topic/seckillResult

4. 前端集成

在前端,使用 JavaScript 来建立与 WebSocket 的连接并发送/接收消息:

var socket = new SockJS('/websocket');
var stompClient = Stomp.over(socket);

stompClient.connect({}, function(frame) {
    // 订阅秒杀结果主题
    stompClient.subscribe('/topic/seckillResult', function(response) {
        alert("Received: " + response.body);
    });
    
    // 发送秒杀请求
    stompClient.send("/app/seckill", {}, "user1234");
});

5. 总结

在这个简单的例子中,我们设置了一个 Spring Boot 应用,其中包含 WebSocket 支持以实现秒杀系统中的实时通讯。当用户发起秒杀请求时,前端通过 WebSocket 向服务器发送信息,并订阅特定主题以接收秒杀结果。

请注意,这只是一个基础的示例,实际的秒杀系统可能涉及更复杂的逻辑,如处理高并发请求、确保数据一致性和安全性等。

28.7 sse技术呢?

在 Spring Boot 中实现 Server-Sent Events (SSE) 用于秒杀系统的通知相对简单。SSE 允许服务器端向客户端推送实时数据,而无需客户端轮询或建立复杂的连接。下面是一个基本的实现流程:

1. 添加依赖

通常情况下,使用 Spring Boot Web Starter 依赖就足够了,因为 SSE 依赖于 Spring MVC 的功能:

<dependencies>
    <!-- Spring Web Starter Dependency -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 其他依赖... -->
</dependencies>

2. 创建 Controller

在 Spring Boot 应用中创建一个 Controller,使用 SseEmitter 类来发送事件给客户端:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;

@RestController
public class SseController {

    private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>();

    @GetMapping("/sse")
    public SseEmitter handleSse() {
        SseEmitter emitter = new SseEmitter();
        emitters.add(emitter);

        emitter.onCompletion(() -> emitters.remove(emitter));
        emitter.onTimeout(() -> emitters.remove(emitter));

        return emitter;
    }

    public void sendToAllClients(String data) {
        for (SseEmitter emitter : emitters) {
            try {
                emitter.send(data);
            } catch (IOException e) {
                emitters.remove(emitter);
            }
        }
    }

    // 其他逻辑...
}

在这个 Controller 中,当客户端请求 /sse 时,将创建一个新的 SseEmitter 并添加到列表中。sendToAllClients 方法可以被用来发送秒杀结果给所有连接的客户端。

3. 前端集成

在前端,你可以使用 EventSource API 来监听来自服务器的事件:

var eventSource = new EventSource('/sse');

eventSource.onmessage = function(event) {
    console.log('Received: ', event.data);
    // 处理服务器发送的数据
};

eventSource.onerror = function(event) {
    // 处理错误
};

4. 触发事件

在服务器端的某个逻辑中(例如秒杀处理逻辑),你可以调用 sendToAllClients 方法来向所有监听的客户端发送数据。

5. 注意事项

  • SSE 支持在单个 HTTP 连接上持续发送多个消息。
  • SSE 适用于单向数据流,即只有服务器向客户端发送数据。
  • SSE 连接是长期存在的,因此需要考虑客户端断开连接时的处理。

6. 总结

使用 SSE,秒杀系统的服务器可以轻松地向客户端推送实时更新(如秒杀成功或失败的通知)。这种方法的优点是实现简单,无需建立复杂的通信协议,而且对于单向数据流来说是非常高效的。

28.8 【重点】如果你采用了发布订阅机制来通知用户,服务端仍然需要维持大量的订阅端点,保持大量的,会消耗资源,有没有什么可以改进的【京东支付后端一面】

答案就是参考28.7的sse技术,只允许单向推送,服务端可以用更少的资源维护和大量的秒杀客户端建立的连接

28.8.1 为什么sse技术无需和客户端建立连接?

实际上,Server-Sent Events (SSE) 技术确实需要与客户端建立一个连接,但这种连接的性质和 WebSocket 不同,它是一种单向的、长期的 HTTP 连接。让我们来详细了解一下:

1 SSE 连接的特性
  1. 单向通信:SSE 是一种服务器到客户端的单向通信。服务器可以不断地向客户端发送消息,但客户端无法通过这个连接发送消息给服务器(客户端需要使用其他方式,如 AJAX 请求,来发送数据到服务器)。

  2. 基于 HTTP:SSE 通过标准的 HTTP 协议建立连接。当客户端通过 EventSource 接口发起请求时,服务器响应这个请求并保持连接打开,然后通过这个连接推送消息。

  3. 长期连接:一旦建立,SSE 连接会保持开放,允许服务器持续不断地发送更新,直到连接被关闭。这种长期连接是通过 HTTP 的响应机制实现的,其中服务器不会立即结束响应,而是保持响应打开状态。

  4. 无需手动管理:对于开发者而言,SSE 无需手动管理连接建立和维护的过程。客户端通过创建 EventSource 对象自动处理连接的创建和维护,服务器端只需按照 SSE 的标准格式发送消息即可。

2 为什么说“无需建立连接”?

当我们说 SSE “无需建立连接”时,通常是指与 WebSocket 相比(WebSocket 基于http上再进行了握手交互以建立websokcet连接),SSE 不需要实现复杂的握手协议和连接管理。在 SSE 中,连接的建立和维护对于开发者来说是透明的,他们只需关注如何发送消息。从技术角度看,SSE 确实建立了一个持久的 HTTP 连接,但这个过程对开发者而言是简化和隐藏的。

3 总结

SSE 技术确实涉及到与客户端的连接建立,但这个过程对开发者来说是简化的,主要体现在单向通信和基于标准 HTTP 协议的长期连接上。这使得 SSE 在单向数据流场景下(如服务器推送更新)变得非常高效和易于实现。

28.8.2 websoket的建立流程

WebSocket 的建立流程包括一个名为“握手”的过程,该过程在客户端和服务器之间建立一个全双工的通信通道。下面是详细的步骤:

1. 客户端请求(握手请求)
  1. 发起请求:客户端创建一个到服务器的标准 HTTP 请求。

  2. 升级头部:在这个请求中,客户端包括一个 “Upgrade” 头部,指明希望“升级”到 WebSocket 协议。

  3. Key:客户端还会发送一个 Base64 编码的随机值(Sec-WebSocket-Key),这是一个握手的一部分,用于之后的验证过程。

    示例请求头可能如下所示:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
    Sec-WebSocket-Version: 13
    
2. 服务器响应(握手响应)
  1. 校验请求:服务器会校验请求是否有效,包括检查 Upgrade 头部和 WebSocket 版本等。

  2. 接受升级:如果校验通过,服务器返回一个 HTTP 响应,确认升级到 WebSocket。

  3. 响应头部:响应中包括一个 “Sec-WebSocket-Accept” 头部,其值是对客户端 Sec-WebSocket-Key 的回应,由服务器生成。

    示例响应头可能如下所示:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
    
3. 连接建立
  1. 完成握手:一旦客户端收到服务器的确认响应,WebSocket 握手过程就完成了,此时,一个全双工的 WebSocket 连接就建立起来了。
  2. 数据传输:随后,客户端和服务器就可以通过这个连接开始发送和接收数据。
4. 数据帧
  • 数据通过 WebSocket 数据帧传输,这些帧可以包含文本或二进制数据。
  • 客户端和服务器都可以随时发送数据帧。
5. 连接维护
  • WebSocket 连接保持活跃,直到被客户端或服务器主动关闭。
6总结

WebSocket 握手过程实际上是一个将标准的 HTTP 连接“升级”到 WebSocket 连接的过程。这个过程保证了服务器和客户端都理解和同意建立一个全双工的通信通道。这种机制使 WebSocket 非常适合需要实时双向通信的应用,如聊天应用、游戏、实时数据监控等。

28.8.3 sse连接建立流程

  1. 客户端请求: 客户端通过发送一个常规的 HTTP GET 请求来初始化 SSE 连接。这个请求的目标是一个服务器上的特定端点,通常是一个返回实时数据流的 URL。

  2. 设置接收格式: 在请求中,客户端通常会设置 Accept: text/event-stream 头,以表明它期望接收事件流格式的数据。

  3. 服务器响应: 服务器识别这个特定的请求,并保持连接打开。然后,它开始以特定的格式发送数据:以 “data:” 开头的行来发送消息内容,后跟一个空行表示消息结束。

  4. 持续数据流: 与 WebSocket 不同,SSE 是单向的,只有服务器可以发送数据。客户端通过监听到来的数据来处理事件。连接将保持打开状态,直到客户端或服务器显式关闭它。
    在这里插入图片描述

28.8.4 对于服务器,sse技术的tcp层有没有read buffer呢,所以相对而言消耗的资源更少呢?

Server-Sent Events (SSE) 在服务器端实现时,通常涉及到 TCP 层的操作。对于 TCP 层来说,无论是使用 SSE 还是其他协议,都会有 read buffer(读缓冲区)和 write buffer(写缓冲区)。这些缓冲区是 TCP 协议的标准部分,用于临时存储即将被发送或接收的数据。然而,SSE 的特殊之处在于它的工作方式和用途:

  1. 单向数据流:SSE 主要用于服务器向客户端发送数据。因此,在 SSE 的上下文中,服务器主要使用 write buffer 来暂存准备发送给客户端的数据。

  2. Read Buffer 的作用:尽管 SSE 通信是单向的(服务器到客户端),服务器的 TCP 层仍然会有一个 read buffer。这是因为 TCP 是一个双向通信协议,即使在只用于单向传输的场景中。服务器的 read buffer 主要用于接收来自客户端的 TCP 控制消息,如确认接收数据的 ACKs、心跳检测、或断开连接的请求。

  3. 应用层处理:SSE 主要在应用层实现,通常是通过 HTTP 协议。服务器端的应用层负责将消息格式化成 SSE 所要求的格式,并将其写入到 TCP 的 write buffer 中。服务器并不直接与 TCP 的 read buffer 交互来处理 SSE 消息;这部分工作主要是 TCP 协议栈自动处理的。

总的来说,对于服务器来说,SSE 技术在 TCP 层会有 read buffer,但其主要作用不是为了 SSE 消息的处理,而是为了处理 TCP 协议本身的需要,如接收来自客户端的控制消息。在 SSE 的场景中,服务器的主要活动是将数据写入 write buffer,供客户端读取。

28.8.5 所以对于服务端的sse,应用层有没有read或者write buffer?(注意和28.8.4中提问的区别)

在服务器端实现 Server-Sent Events (SSE) 时,应用层确实会涉及到缓冲区的概念,但它们与 TCP 层的 read/write buffers 不完全相同。在应用层,这些缓冲区通常是由服务器软件或框架管理的,用于处理和传输数据。下面是对于 SSE 在应用层的缓冲区的一些关键点:

  1. Write Buffer(写缓冲区):

    • 存在: 在 SSE 的上下文中,服务器应用层通常会有一个 write buffer。这是因为 SSE 是一种单向的从服务器到客户端的数据流技术。
    • 用途: 当有数据需要发送给客户端时,这些数据首先会被写入应用层的 write buffer。然后,根据服务器的配置和网络条件,这些数据会从 write buffer 中被逐步发送到客户端。
  2. Read Buffer(读缓冲区):

    • 可能性较低: 由于 SSE 主要用于服务器向客户端发送数据,服务器端应用层通常不需要维护一个专门的 read buffer 来处理从客户端接收的数据。
    • 特殊情况: 不过,服务器可能会接收来自客户端的一些基本信息,如连接初始化的 GET 请求、心跳检测响应或断开连接的请求。这些信息通常通过标准的 HTTP 请求处理机制来管理,并不需要专门的 read buffer。
  3. 缓冲区管理:

    • 自动化: 在许多现代的服务器软件或框架中,缓冲区的管理是自动进行的,开发者不需要直接操作这些缓冲区。
    • 配置: 服务器配置(如缓冲区大小、发送策略等)可以影响数据传输的效率和性能。
  4. 流控制:

    • 在 SSE 中,服务器可能需要适当地管理数据的流量,以避免在应用层的 write buffer 中积累太多未发送的数据。这通常涉及到流量控制和反压机制,确保数据以可持续的速率发送。

总的来说,在 SSE 的场景中,服务器端应用层主要关注的是 write buffer,用于管理待发送给客户端的数据。读缓冲区在这种场景中通常不是重点,因为 SSE 主要是单向的服务器到客户端的数据流。

28.8.6 WebSocket技术每一次发送完毕后都需要客户端响应吗?

客户端响应不是必需的:在 WebSocket 协议中,发送数据后并不强制要求客户端响应。WebSocket 提供了一个全双工的通信通道,客户端和服务器可以独立地发送消息,无需每次交互都进行请求和响应。

根据业务逻辑决定:是否需要客户端对服务器的消息进行响应,完全取决于特定的业务逻辑。例如,如果服务器发送了一个要求确认的指令或数据,客户端可能需要发送一个确认消息或相应的响应。

实时性和独立性:WebSocket 的一个关键优势是其实时性和通信的独立性,允许服务器和客户端按照各自的需求和逻辑独立发送数据。

在实际应用中,WebSocket 通常用于那些需要快速、实时通信的场景,其中客户端和服务器可能会独立地发送和接收消息,而不一定遵循传统的请求-响应模式。

28.9 能告诉我sse比websokcet到底高效在哪儿吗,细节一点?

Server-Sent Events (SSE) 和 WebSocket 都是现代的网络通信技术,用于在客户端和服务器之间实现实时数据传输。尽管它们都被用于实时通信,但它们在设计和使用上有一些关键差异,这些差异导致它们在某些方面的效率不同。以下是这些差异的细节对比,特别强调 SSE 的高效之处:

1. 单向 vs. 全双工通信

  • WebSocket: 提供全双工通信,即客户端和服务器都可以随时发送数据。这对于需要频繁双向数据交换的应用(如聊天应用、实时游戏)非常有效。
  • SSE: 仅支持单向通信,即仅服务器向客户端发送数据。这对于只需服务器推送更新的场景(如新闻订阅、股票价格更新)更为高效,因为它减少了通信协议的复杂性。

2. 实现和维护的简易性

  • WebSocket: 需要服务器和客户端都实现相对复杂的协议支持,包括握手、帧控制、保持连接等。
  • SSE: 实现更简单,客户端通常只需要监听服务器发来的事件即可。服务器端实现也更直接,因为它是基于标准的 HTTP 协议。

3. 网络开销和资源使用

  • WebSocket: 由于是持久化的全双工连接,WebSocket 在握手和维护连接时有额外的网络开销和资源消耗
  • SSE: 由于是基于 HTTP,没有复杂的握手过程,且在单向数据流的情况下网络开销较小。这使得 SSE 在只需要服务器到客户端的数据流的场景中更高效。

4. 消息格式和处理

  • WebSocket: 发送和接收的数据必须是帧结构,可能需要额外的编码和解码处理。
  • SSE: 发送的数据是标准的文本格式,可以直接为 JSON、XML 或任何纯文本,易于处理和解析。

5. 浏览器兼容性和支持

  • WebSocket: 得到了广泛的浏览器支持。
  • SSE: 虽然也被主流浏览器支持,但在一些旧的浏览器和某些环境(如某些移动设备)中可能不如 WebSocket 广泛支持。

6. 重连机制

  • WebSocket: 需要手动实现重连逻辑。
  • SSE: 浏览器会自动尝试重连,减少了开发者的负担。

7. HTTP/2 兼容性

  • WebSocket: 与 HTTP/2 的兼容性并不理想,因为 HTTP/2 主要是为了优化传统的 HTTP 请求。
  • SSE: 在 HTTP/2 环境下,由于其天然的 HTTP 性质,可以更好地利用 HTTP/2 的性能优势,如服务器推送。

8 总结

总的来说,SSE 在以下场景下更高效:

  • 当需要简单的单向数据流(服务器到客户端)时。
  • 当希望减少实现的复杂性和提高网络传输效率时。
  • 当应用可以从 HTTP/2 的优势中受益时。

而在需要复杂的双向通信和更高级功能(如二进制数据处理)的应用中,WebSocket 可能是更好的选择。

28.9【我的总结】

因为订单系统的复杂性,针对频繁和客户端双向交互的接口,我们采用websoket协议,比如查询订单状态,支付状态;对于秒杀结果返回这个接口,采用sse技术,只需要维持单向通信。

  • 21
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值