开发者必知必会的 WebSocket 协议

关于 WebSocket,我之前也写过了两篇文章进行介绍:《WebSocket 从入门到写出开源库》和《Python如何爬取实时变化的WebSocket数据》。今天这篇文章,大体上与之前的文章内容结构相似。但质量更进一步,适合想要完全掌握 WebSocket 协议的朋友。

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它的出现使客户端和服务器之间的数据交换变得更加简单。WebSocket 通常被应用在实时性要求较高的场景,例如赛事数据、股票证券、网页聊天和在线绘图等。

WebSocekt 与 HTTP 协议完全不同,但同样被广泛应用。无论是后端开发者、前端开发者、爬虫工程师或者信息安全工作者,都应该掌握 WebSocekt 协议的知识。

在本篇文章中,你将收获如下知识:

  • 读懂 WebSocket 协议规范文档 RFC6455
  • WebSocket 与 HTTP 的关系
  • 数据帧格式及字段含义
  • 客户端与服务端交互流程
  • 客户端与服务端如何保持连接
  • 何时断开连接

本篇文章适用于互联网领域的开发者和产品经理


开始

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 通信协议于 2011 年被 IETF 定为标准 RFC6455,并由 RFC7936 补充规范。看到这里,很多读者会有疑问:什么是 RFC?

RFC 是一系列以编号排定的文件,它由一系列草案和标准组成。几乎所有互联网通信协议均记录在 RFC 中,例如 HTTP 协议标准、本篇介绍的 WebSocket 协议标准、Base64 编码规范等。除此之外,RFC 还加入了许多论题。在本篇 Chat 中,我们对 WebSocekt 的学习和讨论将基于 RFC6455。

WebSocket 协议的来源

在 WebSocket 协议出现以前,网站通常使用轮询来实现类似“数据实时更新”这样的效果。要注意的是,这里的“数据实时更新”是带有引号的,这表示并不是真正意义上的数据实时更新。轮询指的是在特定的时间间隔内,由客户端主动向服务端发起 HTTP 请求,以确认是否有新数据的行为。下图描述了轮询的过程:

 

首先,客户端会向服务端发出一个 HTTP 请求,这个请求的意图就是向服务器询问“大哥,有新数据吗?”。服务器在接收到请求后,根据实际情况(有数据或无数据)做出响应:

  • 有数据,我发给你;
  • 无数据,你待会再问;

这种一问一答的方式有着明显的缺点,即浏览器需要不断的向服务器发出请求。由于 HTTP 请求包含较长的头部信息(例如 User-Agent、Referer 和 Host 等),其中真正有效的数据可能只是很小的一部分,所以这样会浪费很多的带宽资源。

比轮询更好的“数据实时更新”手段是 Comet。这种技术可以实现双向通信,但依然需要反复发出请求。而且在 Comet 中,采用的是 HTTP 长连接,这同样会消耗服务器资源。在这种情况下,HTML5 定义了更节省资源,且能够让双端稳定实时通信的 WebSocket 协议。在 WebSocket 协议下,客户端和服务端只需要完成一次握手,就直接可以创建持久性的连接,并进行双向数据传输。下图描述了 WebSocket 协议中,双端通信的过程:

 

WebSocket 的优点

相对于 HTTP 协议来说,WebSocket 具有开销少、实时性高、支持二进制消息传输、支持扩展和更好的压缩等优点。这些优点如下所述:

较少的开销

WebSocket 只需要一次握手,在每次传输数据时只传输数据帧即可。而 HTTP 协议下,每次请求都需要携带完整的请求头信息,例如 User-Agent、Referer 和 Host 等。所以 WebSocket 的开销相对于 HTTP 来说会少很多。

更强的实时性

由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于一问一答的 HTTP 来说,WebSocket 协议下的数据传输的延迟明显更少。

支持二进制消息传输

WebSocket 定义了二进制帧,可以更轻松地处理二进制内容。

支持扩展

开发者可以扩展协议,或者实现部分自定义的子协议。

更好的压缩

Websocket 在适当的扩展支持下,可以沿用之前内容的上下文。这样在传递类似结构的数据时,可以显著地提高压缩率。

WebSocket 协议规范

WebSocket 是一个通信协议,该协议的规范与标准均记录在 RFC6455 中。协议共有 14 个部分,但与协议规范相关的只有 11 个部分:

  1. 介绍
  2. 术语和其他约定
  3. WebSocket URI
  4. 握手规范
  5. 数据帧
  6. 发送和接收数据
  7. 关闭连接
  8. 错误处理
  9. 扩展
  10. 通信安全
  11. 注意事项

而与本篇 Chat 相关的为 4、5、6、7 部分的内容,这些也是 WebSocket 中较为重要的内容。接下来,我们就来学习这些知识。

双端交互流程

客户端与服务端连接成功之前,使用的通信协议是 HTTP。连接成功后,使用的才是 WebSocket 协议。下图描述了双端交互的流程:

 

首先,客户端向服务端发出一个 HTTP 请求,请求中携带了服务端规定的信息,并在信息中表明希望将协议升级为 WebSocket。这个请求被称为升级请求,双端升级协议的整个过程叫做握手。然后服务端验证客户端发送的信息,如果符合规范则将协议替换成 WebSocket,并将升级成功的信息响应给客户端。最后,双方就可以基于 WebSocket 协议互相推送信息了。现在,我们需要学习的第一个知识点就是握手。

双端握手

我们先来看看 RFC6455 对客户端握手的规定,原文锚点链接为 Opening Handshak。此段原文如下:

The opening handshake is intended to be compatible with HTTP-based server-side software and intermediaries, so that a single port can be used by both HTTP clients talking to that server and WebSocket clients talking to that server.  To this end, the WebSocket client's handshake is an HTTP Upgrade request:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

In compliance with [RFC2616], header fields in the handshake may be sent by the client in any order, so the order in which different header fields are received is not significant.

原文表明,握手时使用的并不是 WebSocekt 协议,而是 HTTP 协议,握手时发出的请求叫做升级请求。客户端在握手阶段通过 Connection 和 Upgrade 头域及对应的值告知服务端,要求将当前通信协议升级为指定协议,此处指定的是 WebSocket 协议。其他头域名及值的作用如下:

  • GET /chat HTTP/1.1 表明本次请求基于 HTTP/1.1,请求方式为 GET;
  • Sec-WebSocket-Protocol 用于指定子协议;
  • Sec-WebSocket-Version 表明协议版本,要求双端版本一致。当前 WebSocekt 协议版本默认为 13;
  • Origin 表明请求来自于哪个站点;
  • Host 表明目标主机;
  • Sec-WebSocket-Key 用于防止攻击者恶意欺骗服务端;

也就是说,握手时客户端只需要按照上述规定向服务端发出一个 HTTP 请求即可。

服务端收到客户端发起的请求后,按照 RFC6455 的约定验证请求信息。验证通过就代表握手成功,此时服务端应当按照约定将以下内容响应给客户端:

 HTTP/1.1 101 Switching Protocols
 Upgrade: websocket
 Connection: Upgrade
 Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
 Sec-WebSocket-Protocol: chat

服务端会给出代表连接结果的响应状态码,101 状态码表示表示本次请求成功且得到服务端的正确处理。Connection 和 Upgrade 表示已经切换成 websocket 协议。Sec-WebSocket-Accept 则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key,这个值根据客户端发送的 Sec-WebSocket-Key 生成。Sec-WebSocket-Protocol 表明双端约定的子协议。

这样,客户端与服务端就完成了握手操作。双端达成一致,通信协议将由 HTTP 协议切换成 WebSocket 协议。

发送和接收数据

双方握手成功,并确定协议后,就可以互相发送信息了。客户端和服务端互发消息与我们平时在社交应用中互发消息类似,例如:

client: Hello, Server boy.

server: Hello, Client Man.

当然,这里的 Hello, Server boy 和 Hello, Client Man 是有助于我们理解的比喻。实际上,WebSocket 协议的中的数据传输格式并不是这样直接呈现的。

数据帧

WebSocket 双端传输的是一个个数据帧,数据帧的约定原文如下:

In the WebSocket Protocol, data is transmitted using a sequence of frames. To avoid confusing network intermediaries (such as intercepting proxies) and for security reasons that are further discussed in Section 10.3, a client MUST mask all frames that it sends to the server (see Section 5.3 for further details). (Note that masking is done whether or not the WebSocket Protocol is running over TLS.)  The server MUST close the connection upon receiving a frame that is not masked.  In this case, a server MAY send a Close frame with a status code of 1002 (protocol error) as defined in Section 7.4.1.  A server MUST NOT mask any frames that it sends to the client.  A client MUST close a connection if it detects a masked frame.  In this case, it MAY use the status code 1002 (protocol error) as defined in Section 7.4.1.  (These rules might be relaxed in a future specification.)
The base framing protocol defines a frame type with an opcode, a payload length, and designated locations for "Extension data" and "Application data", which together define the "Payload data". Certain bits and opcodes are reserved for future expansion of the
protocol.
A data frame MAY be transmitted by either the client or the server at any time after opening handshake completion and before that endpoint has sent a Close frame (Section 5.5.1).

原文表明,协议中约定数据传输时并不是使用 Unicode 编码,而是使用数据帧(Frame)。下图描述了数据帧的组成:

 

数据帧由几个部分组成:FIN、RSV1、RSV2、RSV3、opcode、MASK、Payload length、Payload Data、和 Masking-key。下面,我们来了解一下数据帧组件的大体含义或作用。

FIN

占 1 bit,其值为 0 或 1,值对应的含义如下:

0:不是消息的最后一个分片;

1:是消息的最后一个分片;

RSV1 RSV2 RSV3

均占 1 bit,一般情况下值为 0。当客户端、服务端协商采用 WebSocket 扩展时,这三个标志位可以非 0,且值的含义由扩展进行定义。如果出现非零的值,但并没有采用 WebSocket 扩展,则连接出错。

Opcode

占 4 bit,其值可以是 %x0、%x1、%x2、%x3~7、%x8、%x9、%xA 和 %xB~F 中的任何一个。值对应的含义如下:

%x0:表示一个延续帧。当 Opcode 为 0 时,表示本次数据传输采用了数据分片,当前收到的数据帧为其中一个数据分片;

%x1:表示这是一个文本帧(text frame);

%x2:表示这是一个二进制帧(binary frame);

%x3-7:保留的操作代码,用于后续定义的非控制帧;

%x8:表示连接断开,是一个控制帧;

%x9:表示这是一个心跳请求(ping);

%xA:表示这是一个心跳响应(pong);

%xB-F:保留的操作代码,用于后续定义的控制帧;

Mask

占 1 bit,其值为 0 或 1。值 0 表示要对数据进行掩码异或操作,反之亦然。

Payload length

占 7 bit 或 7+16 bit 或 7+64 bit,表示数据的长度,其值可以是0~127 中的任何一个数。值对应的含义如下:

0~126:数据的长度等于该值;

126:后续 2 个字节代表一个 16 位的无符号整数,该无符号整数的值为数据的长度;

127:后续 8 个字节代表一个 64 位的无符号整数(最高位为 0),该无符号整数的值为数据的长度。

掩码

掩码的作用并不是为了防止数据泄密,而是为了防止早期版本的协议中存在的代理缓存污染攻击(proxy cache poisoning attacks)问题。这里要注意的是从客户端向服务端发送数据时,需要对数据进行掩码操作;从服务端向客户端发送数据时,不需要对数据进行掩码操作。

如果服务端接收到的数据没有进行过掩码操作,服务端需要断开连接。如果Mask是1,那么在Masking-key中会定义一个掩码键(masking key),并用这个掩码键来对数据载荷进行反掩码。

所有客户端发送到服务端的数据帧,Mask都是1。

掩码算法:按位做循环异或运算,先对该位的索引取模来获得 Masking-key 中对应的值 x,然后对该位与 x 做异或,从而得到真实的 byte 数据。

Making-key

占 0 或 4 bytes,其值为 0 或 1。值对应的含义如下:

0:没有 Masking-key;
1:有 Masking-key;

Payload Data

双端接收到数据帧之后,可以根据上述几个数据帧组件的值对 Payload Data 进行处理或直接提取数据。

数据收发流程

在了解到 WebSocket 传输的数据帧格式后,我们再来学习数据收发的流程。在双端建立 WebSocket 连接后,任何一端都可以给另一端发送消息,这里的消息指的就是数据帧。但平时我们输入或输出的信息都是“明文”,所以在消息发送前需要将“明文”通过一定的方法转换成数据帧。而在接收端,拿到数据帧后需要按照一定的规则将数据帧转换为”明文“。下图描述了双端收发 Hello, world 的主要流程:

 

保持连接和关闭连接

WebSocket 双端的连接可以保持长期不断开,但实际应用中却不会这么做。如果保持所有连接不断开,但连接中有很多不活跃的成员,那么就会造成严重的资源浪费。

服务端如何判断客户端是否活跃呢?

服务端会定期给所有的客户端发送一个 opcode 为 %x9 的数据帧,这个数据帧被称为 Ping 帧。客户端在收到 Ping 帧时,必须回复一个 opcode 为 %xA 的数据帧(又称为 Pong 帧),否则服务端就可以主动断开连接。反之,如果服务端在发送 Ping 帧后能够得到客户端 Pong 帧的回应,就代表这个客户端是活跃的,不要断开连接。

如果需要关闭连接,那么一端向另一端发送 opcode 为 %x8 的数据帧即可,这个数据帧被称为关闭帧。


实际代码解读-Python

上面所述均为 RFC6455 中约定的 WebSocket 协议规范。在学习完理论知识后,我们可以通过一些示例(代码伪代码)来加深对上述知识的理解。

Echo Test 是 websocket.org 提供的一个测试平台,开发者可以用它测试与 WebSocket 相关的连接、消息发送和消息接收等功能。下面的代码演示也将基于 Echo Test。

客户端握手

上面提到过,客户端向服务端发出升级请求时,请求头如下:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

对应的 Python 代码如下:

import requests

url = 'http://echo.websocket.org/?encoding=text'
header = {
    "Host": "echo.websocket.org",
    "Upgrade": "websocket",
    "Connection": "Upgrade",
    "Sec-WebSocket-Key": "9GxOnSwEuBNbLeBwiltymg==",
    "Origin": "http://www.websocket.or",
    "Sec-WebSocket-Protocol": "chat, superchat",
    "Sec-WebSocket-Version": "13"
}

resp = requests.get(url, headers=header)
print(resp.status_code)

代码运行后返回的结果为 101,这说明上方代码完成了升级请求的工作。

数据转换为数据帧

数据转换为数据帧涉及到很多知识,同时需要运行完整的 WebSocket 客户端。本篇 Chat 不演示完整的代码结构,仅讲解对应的代码逻辑。完整的 WebSocket 客户端可在 Github 上克隆我编写的开源的库:aiowebsocekt。

克隆到本地后打开 freams.py ,这就是负责数据帧的转换处理的主要文件。

首先看 write() 方法,发送端发送数据时,数据会经过该方法。write() 方法的完整代码如下:

 async def write(self, fin, code, message, mask=True, rsv1=0, rsv2=0, rsv3=0):
        """Converting messages to data frames and sending them.
        Client data frames must be masked,so mask is True.
        """
        head1, head2 = self.pack_message(fin, code, mask, rsv1, rsv2, rsv3)
        output = io.BytesIO()
        length = len(message)
        if length < 126:
            output.write(pack('!BB', head1, head2 | length))
        elif length < 2**16:
            output.write(pack('!BBH', head1, head2 | 126, length))
        elif length < 2**64:
            output.write(pack('!BBQ', head1, head2 | 127, length))
        else:
            raise ValueError('Message is too long')

        if mask:
            # pack mask
            mask_bits = pack('!I', random.getrandbits(32))
            output.write(mask_bits)
            message = self.message_mask(message, mask_bits)

        output.write(message)
        self.writer.write(output.getvalue())

首先,调用 pack_message() 方法构造数据帧中的 FIN、Opcode、RSV1、RSV2、RSV3。然后根据消息的长度构造数据帧中的 Payload length。接着根据发送端是客户端或服务端对数据进行掩码。最后将数据放到数据帧中,并将数据帧发送给接收端。这里用到的 pack_message() 方法代码如下:

@staticmethod
    def pack_message(fin, code, mask, rsv1=0, rsv2=0, rsv3=0):
        """Converting message into data frames
        conversion rule reference document:
        https://tools.ietf.org/html/rfc6455#section-5.2
        """
        head1 = (
                (0b10000000 if fin else 0)
                | (0b01000000 if rsv1 else 0)
                | (0b00100000 if rsv2 else 0)
                | (0b00010000 if rsv3 else 0)
                | code
        )
        head2 = 0b10000000 if mask else 0  # Whether to mask or not
        return head1, head2

用于执行掩码操作的 message_mask() 方法代码如下:

@staticmethod
    def message_mask(message: bytes, mask):
        if len(mask) != 4:
            raise FrameError("The 'mask' must contain 4 bytes")
        return bytes(b ^ m for b, m in zip(message, cycle(mask)))

以上就是数据转换为数据帧并发送给接收端的主要代码。

数据帧转换为数据

同样是 freams.py 文件,这次我们来看 read() 方法。接收端接收数据后,数据会经过该方法。read() 方法的完整代码如下:

    async def read(self, text=False, mask=False, maxsize=None):
        """return information about message
        """
        fin, code, rsv1, rsv2, rsv3, message = await self.unpack_frame(mask, maxsize)
        await self.extra_operation(code, message)  # 根据操作码决定后续操作
        if any([rsv1, rsv2, rsv3]):
            logging.warning('RSV not 0')
        if not fin:
            logging.warning('Fragmented control frame:Not FIN')
        if code is DataFrames.binary.value and text:
            if isinstance(message, bytes):
                message = message.decode()
        if code is DataFrames.text.value and not text:
            if isinstance(message, str):
                message = message.encode()
        return message

首先,调用 unpack_frame() 方法从数据帧中提取出 FIN、Opcode、RSV1、RSV2、RSV3 和 Payload Data(代码中是 message)。然后根据 Opcode 决定后续的操作,例如提取数据、关闭连接、发送 Ping 帧或 Pong 帧等。

unpack_frame() 方法的完整代码如下:

 async def unpack_frame(self, mask=False, maxsize=None):
        reader = self.reader.readexactly
        frame_header = await reader(2)
        head1, head2 = unpack('!BB', frame_header)

        fin = True if head1 & 0b10000000 else False
        rsv1 = True if head1 & 0b01000000 else False
        rsv2 = True if head1 & 0b00100000 else False
        rsv3 = True if head1 & 0b00010000 else False
        code = head1 & 0b00001111

        if (True if head2 & 0b10000000 else False) != mask:
            raise FrameError("Incorrect masking")

        length = head2 & 0b01111111
        if length == 126:
            message = await reader(2)
            length, = unpack('!H', message)
        elif length == 127:
            message = await reader(8)
            length, = unpack('!Q', message)
        if maxsize and length > maxsize:
            raise FrameError("Message length is too long)".format(length, maxsize))
        if mask:
            mask_bits = await reader(4)
        message = self.message_mask(message, mask_bits) if mask else await reader(length)
        return fin, code, rsv1, rsv2, rsv3, message

从数据帧中提取 FIN、RSV1、Opcode 和 Payload Data(代码中是 message) 等组件时,使用的是按位与运算。对位运算不太了解的朋友可以查阅我之前在微信公众号发表的《七分钟全面了解位运算》文章。接着根据是否掩码调用 message_mask() 方法,最后将得到的组件返回给调用方。

总结

本篇 Chat 我们了解了 WebSocekt 协议的来源,并讨论了它的优点。然后解读 RFC6455 中对 WebSocket 的约定,了解到双端交互流程、保持连接和关闭连接方面的知识。最后学习到如何将 WebSocket 协议转换为具体的代码。

WebSocket 有几个关键点:握手、数据与数据帧的转换、保持连接的 Ping 帧和 Pong 帧、主动关闭连接的关闭帧。希望大家在看过本篇 Chat 后,能够对 WebSocket 协议有一个全新的认识。


作者:华为云享专家 韦世东

 

相关推荐:

Python如何爬取实时变化的WebSocket数据

WebSocket 从入门到写出开源库

相关推荐

鸿蒙案例上新啦 | 购物、听歌、健身:15个模板带你一键激活社交娱乐

页面层级如何组织、跨页共享状态如何同步、列表与详情及个人中心如何形成稳定闭环。鸿蒙开发实践中心将这些高频消费与互动场景沉淀为可参考的标准模板,提供从业务架构到界面实现的快捷实践入口。更多实战案例欢迎前往鸿蒙开发实践中心案例中心查看并开启云端体验。

华为云官方博客 355

鸿蒙案例上新啦 | 出门打车、到家上课:25个模板带你一屏打通日常生活

如何合理拆分页面组件、如何建立单一可信的状态源、如何让用户在每一步操作中都获得明确反馈。鸿蒙开发实践中心以标准化的应用与元服务模板为入口,将清晰的业务架构与可复用的代码结构直观呈现。不妨立即挑选一个感兴趣的方向进入云端环境,从页面布局、组件封装、状态管理到路由组织,亲手跑通你的鸿蒙实战项目。

华为云官方博客 336

LakeAgent:DWS数据仓库的第二大脑,告别 “翻译式运维”,迈入智能自治时代

和普通 SQL 改写工具不同,LakeAgent 自动做多方案代价对比,主动规避负优化陷阱:补充分区键过滤实现剪枝,扫描分区由 37 收敛至 1,执行代价从 758.28 降至 113.74;未来的数据仓库,将不止能算、能存,更能看懂自己、诊断自己、理解自己。长久以来,数仓的智能都依附于人:信号需要人解读,瓶颈需要人研判,经验困在个体里,无法随底座永续生长。CPU 高、CPU 告警、CPU 诊断、CPU 使用率过高、CPU 满。语法、错误码、计费、性能调优、最佳实践、故障处置等全场景内容。

华为云官方博客 563

如何使用RDS Supabase后端BaaS能力:文件存储(File Storage)

• product-images(公开桶,允许公共读取):策略名称"Public read for product-images",允许SELECT,目标角色anon,策略定义bucket_id = 'product-images'。上传/删除需另配INSERT/DELETE策略,详见SQL。• product-specs(私有桶,仅认证用户访问自己的文件夹):建议拆为上传、读取、删除三条策略,策略定义均为 bucket_id = 'product-specs' 且仅限本人文件夹(详见下文 SQL)。

华为云官方博客 484

如何使用RDS Supabase后端BaaS能力:实时订阅与推送(Realtime)

Realtime 把数据库的每次变更同步到客户端:表里增、删、改一行,订阅者无需刷新页面或主动请求即可秒级收到。三大能力各司其职:• Postgres Changes — 监听表的 INSERT/UPDATE/DELETE,变化即通知• Broadcast — 客户端之间直接互发,适合瞬时通知、协同编辑• Presence — 跟踪频道里“谁在线”典型场景有实时数据展示(订单、库存、监控指标即时刷新)、即时通讯(消息收发、在线名单、“对方正在输入”)、协同编辑与实时通知。

华为云官方博客 474

AI Agent如何通过MCP连接到华为云RDS Supabase应用平台

Schema元数据列出所有可访问的表(按schema分组)。Schema元数据列出表的列及元数据(类型/默认值/约束)。Schema元数据列出所有约束(PK/FK/UNIQUE/CHECK/EXCLUDE)。可按schema/表/类型过滤。Schema元数据列出所有外键关系。可按schema/表过滤。Schema元数据列出所有索引及定义和大小。可按schema/表过滤。Schema元数据列出已应用的数据库迁移记录。Schema元数据列出已安装的PostgreSQL扩展。

华为云官方博客 481

华为大数据Flink让每一 CU 算力,跑出开源 5.74 倍的性能

1. 开源Apache Flink 已成为业界流计算事实标准,但在极端重负载场景下存在性能瓶颈。2. 华为大数据Flink通过多项自研深度优化,在执行计划、算子执行、状态存储三个层面构建协同的优化体系。3. Nexmark Benchmark 测试结果:整体性能提升 5.74 倍,极端重负载场景性能领先最高 18.3 倍。4. 100% 兼容 Apache Flink 1.20,业务代码零改造,无缝迁移。

华为云官方博客 385

LakeAgent实战 | 业务分析篇从一句提问到业务分析

本文以“订单金额变化”分析为例,展示LakeAgent如何通过自然语言提问,结合DataArtsStudio的数据资产与专业技能,帮助业务人员快速定位数据、生成SQL、追踪血缘、生成报告。从问题出发,逐步实现数据发现、变化洞察、原因追溯与团队协作,最终形成可复用的分析流程与企业规则,显著提升数据分析效率与一致性。

华为云官方博客 394

华为云RDS Supabase AI应用已开放公测 :30分钟搭建AI应用后端

认证、存储、实时推送、数据库API——4个后端模块,传统开发需要数周。今天,你只需要30分钟。AI创业公司的全栈开发工程师。上周老板说"下周要上线的AI对话应用,后端你来搞"——认证鉴权、数据库接口、文件存储、实时推送,每一个模块都需要数周搭建,而市场不会等你。小张打开华为云RDS Supabase,30分钟搭好认证、数据库API、对象存储,剩下的时间全用来打磨AI交互体验。基于开源Supabase+华为云RDS PostgreSQL全托管能力,为开发者提供。

华为云官方博客 402

如何使用RDS Supabase后端BaaS能力:数据库函数(Database Function)

上一篇介绍了 Database Data API——建表即自动生成增删改查接口,解决单表读写,但聚合统计、跨表事务、字段自动维护等逻辑已超出其能力边界。本篇推进到数据库函数(Database Function):把业务逻辑封装进数据库,前端通过 .rpc() 调用,由触发器自动响应数据变更。上一篇中,小张基于 Data API 完成了产品目录的建表与基础读写。但新需求随之而来:按分类统计产品数与价格区间、上架新品同时写产品表与定价表、产品修改后自动刷新更新时间。

华为云官方博客 467

如何使用RDS Supabase后端BaaS能力:创表即生成API(Database Data API)

认证、存储、实时推送、数据库API——4个后端模块,传统开发要数周。本系列逐个拆解,首篇聚焦数据库API(Database Data API):建表即得 API,无需手写后端。小张,AI创业公司的全栈工程师。老板让他做个产品目录页,展示产品与价格、支持上下架。传统做法要搭后端、写接口、配权限,工期少说1-2周;而在华为云RDS Supabase,建两张表、应用 SDK 直连,几分钟增删改查全跑通。

华为云官方博客 483

从一句话到一个能出去的链接,AI开发者空间做了什么

自行搭建的 Agent、正在使用的开源项目、团队既有的工具,都可以接入,可以通过AI创建或者手动搭建环境;华为云 AI开发者空间——面向开发者的云端一站式开发平台,做的就是把这段路接上:环境免安装,浏览器打开即为完整的 Linux 运行环境,预置的 AI 智能体开箱即用。第一个任务建议选能出结果的:做一个游戏、生成一个页面、创建一台实例,从需求走到可访问的链接,一次就能看清这个环境在做什么。沙箱是一个完整的 Linux 环境,依赖、服务、端口都是真实的,不是模拟。环境释放后,权限随之失效。

华为云官方博客 430

华为云码道配置自定义大模型,四种方式完整实操

案例介绍。

华为云官方博客 634

图数据库:实现穿透式监管的数据基座

穿透式监管标志着国企监管从“管企业”向“管资本”转型过程中的关键一跃。而图数据库正是这一跃的技术支点。从股权穿透到资金链穿透,从供应链穿透到数据穿透,华为GES图数据库正在将“穿透式监管”从理念变为可落地、可操作的实践。无论是天眼查式的全量链路查询,还是某集团财经的税务规则判断,抑或是芯片供应链式的部件风险分析,乃至通过Palantir构建决策知识图谱,其底层逻辑都是一致的——用图的力量,穿透一切形式的“隔离层”,直抵风险本质与责任核心。

华为云官方博客 668

《公共云三十问》正式收官,奔赴企业AI百场景新征程

今年6月底,公共云产业联盟重点推出《公共云三十问》专栏,以每周三问的节奏,连载十周,解读《先进公共云》白皮书,分享国计民生系列案例,旨在凝聚共识、推动落地实践。同时,专栏分析公共云在产业升级、民生福祉、科技创新、全球发展等方面的作用,梳理中国特色公共云发展路径:以普惠云拓展用云广度,以智算云提升用云深度,以自主云夯实用云厚度,以全球云打开用云跨度。这十问从专属云、行业云切入,深入政务、金融、交通、电力、钢铁、化工、油气、制造等国计民生场景,回答公共云“怎么用”。

华为云官方博客 474

开发者小技巧|IAM配置,让码道代码智能体连续30天免登录

案例介绍。

华为云官方博客 648

码道深度对接CodeArts,让需求自动落地为代码

案例介绍。

华为云官方博客 722

【公共云三十问 之三十】拥抱AI,企业如何建设面向智能体的专属云?

企业可分阶段建设覆盖开发、运行、运营及安全的一体化智能体平台——从构建一站式、高低码协同的智能体开发平台,到打造高性能、极致弹性的运行时环境,再到搭建AgentOps驱动的持续运营与运维体系,同时构建端到端、多层次的全链路安全防护体系。在数据湖建设方面,遵循“存量复用、平滑演进、AI导向、分步迭代”原则,分三阶段推进——打造AI多模数据湖核心能力、完成存算分离与统一元数据管理、实现闭环赋能全面支撑智能体规模化落地,在保护既有投资的前提下将传统数据平台转型为AI数据专属供给平台。

华为云官方博客 824

【公共云三十问 之二十九】国计民生之制造:制造云如何重塑数智时代的新质生产力?

平台打通软件交付的完整路径,覆盖需求管理、代码托管、代码检查、编译构建、制品仓库、部署、测试等关键环节,支持大模型能力融入研发全流程,实现从需求到交付的端到端管理。通过构建“研发一朵云”,方案打破地域与组织壁垒,实现跨团队协同开发,有效缩短软件交付周期,助力工业制造企业从“传统研发”走向“敏捷研发”,加速数智化转型进程。当制造云真正成为数据流通的平台、AI创新的底座,公共云的社会价值将从基础设施层向生产场景层持续延伸,为新型工业化建设和制造强国战略注入源源不断的动力,重塑数智时代的中国制造新质生产力。

华为云官方博客 791

告别重复手工迁仓,码道MCP+Skill实现仓库批量迁移

案例介绍。

华为云官方博客 791

【公共云三十问 之二十八】国计民生之油气:智算云如何叩响数智时代的“地心蓝金”?

西南油气田以“向地球深部要资源”为战略方向,联合以华为云Stack为代表的公共云服务商共同打造统一算力底座,建设西南区域数据湖与通用技术平台,构建“勘探开发工程技术、天然气生产过程管控、天然气产运储销”等三个一体化协同应用场景,支撑油气勘探、开发生产、管输储运等全业务链的数智化转型。当智算云真正成为数据流通的平台、AI创新的底座,油气田得以将算力效能、数据价值与智能技术深度融入勘探开发全链条,将“看不见的算力”转化为“摸得着的储量”,以智能化手段持续降低勘探风险、缩短发现周期、提高采收效率,确保生产安全。

华为云官方博客 613

【公共云三十问 之二十七】国计民生之化工:数智云如何重塑传统化工新范式?

在架构方面,方案构建云边协同的统一体系,涵盖AI协同、数据协同与运营协同三大维度——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现“边用边学”的智能闭环,模型平均精度提升20%以上。此外,方案提供一站式企业级工业物联网平台、数据湖与数据治理平台,覆盖工业数据分析“采、存、算、管、用”全流程,打通生产现场与管理系统间的数据壁垒,有效消除数据孤岛。层面,方案充分发挥软硬协同优势,实现计算、存储、网络与云平台的深度协同,训练线性度超95%,为大模型训练推理提供强劲算力支撑。▲化工“数智”新模式。

华为云官方博客 664

【公共云三十问 之二十六】国计民生之钢铁:数智云如何淬炼中国钢铁新力量?

同时,构建云边端协同的统一架构,支撑集团总部与各生产基地两级协同发展——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现训推一体化的资源调度与高效协同,为钢铁行业的数智化转型构建了坚实的算力底座。层面,方案构建覆盖“工业数采→边缘IT/OT融合→统一数据湖→数据治理平台→数据应用”全链路的一站式数据治理与流通平台,打通生产现场与管理系统间的数据壁垒,让数据“采得到、流得动、用得好”,加速数据价值从生产现场向经营决策层流动释放。湘潭钢铁集团的钢铁数智云,是钢铁工业智能云建设的标杆案例。

华为云官方博客 526

LakeWatch——MRS 智能运维Agent

从资源池、队列、作业等多个维度,对集群CPU与内存资源进行精细化分析与对比,直观呈现不同时间段的空闲、满载等使用状态,识别资源浪费,指导治理优化,为扩缩容决策提供数据支撑。对HDFS存储进行多维度深度分析(目录、用户、用户组等),涵盖使用量、增量、文件大小分布及数据热度等指标,帮助快速识别增长较快的目录、长期未访问的文件,统计目录文件数量与小文件占比,评估HDFS总存储量与扩缩容需求,为存储治理与资源规划提供全面数据支撑。Agent主动巡检,识别异常趋势并提前预警,让运维从"事后处理"转向"事前预防"。

华为云官方博客 515

华为云专题文档发布:丰富的AI案例、选型指导和概念解读

发布 “云服务选型”、“云计算概念”专题,提供云服务选型指导,助您选择匹配业务的云服务,解读云计算相关概念,开启云上学习之路。开发者工具和文档专区上线,提供从学习、实践到反馈的全链路支持。帮助中心新增100余篇AI案例。

华为云官方博客 286

一个人,也能用AI做点“星东西”

华为云星耀创想者大赛-2026华为云OPC创意大赛等你来~

华为云官方博客 291

从需求到可执行工作项:MCP+Skill 让智能体规划真正落地

回顾整个体验,以前让智能体帮我拆需求,它是洋洋洒洒给我列了一大篇 Markdown,看着挺像那么回事,但最后还是得我一条条往 CodeArts Req 里搬,搬完再手动挂父子关系、排日期,拆需求五分钟,搬运两小时。现在好了,MCP 给智能体接上了"手",Skill 给它装上了"项目经理的脑子",一句话下去,34 个工作项连带排期、层级关系全给我建好了,甘特图一拉,齐刷刷都在两周内,节省了多少工作量啊,美滋滋。本次实操在码道代码智能体基础上,构建了一套"需求→可执行工作项"的自动化规划方案。

华为云官方博客 576

华为云码道「码力续航计划」更新!

✅上新GLM‑5.3‑Flash,高速响应,代码生成、工程解析、Agent调试高效输出。新增GLM‑5.3‑Flash福利模型,每日解锁1000万免费Tokens。● 本次活动共发放总量价值100万元Tokens,发完即止!把耗算力的编码重活,交给华为云码道代码智能体🚀🚀。● 每日额度准时刷新,当日清零、次日满血重置。✅复杂算法、大项目解析、批量代码生成随便跑。✅不用抠额度、不用算消耗,放开调试大胆迭代。✅无需额外操作,登录即送,直接切换模型使用。● 把算力交给码道,让撸码不再内耗👏🏻。

华为云官方博客 688

【公共云三十问 之二十四】国计民生之交通:交通云如何铺就数智通衢新坦途?

交通行业作为支撑实体经济的关键基础设施,涵盖公路、铁路、机场、港口、地铁等众多子领域,其中,公路网络作为综合交通运输体系的基础骨架,承担着全国超过70%的客货运量,其数字化、智能化转型的需求尤为迫切。方面,提供Agent开发框架、知识库管理、RAG工程、意图识别、静态应用编排及模型评测等能力,支持客户将行业知识、业务流程与AI能力深度融合,快速构建面向收费稽核、路网调度、应急处置等场景的智能应用。开发并实现落地应用,全面覆盖建设、管理、养护、运营、服务、安全、办公七大业务领域。

华为云官方博客 464

【公共云三十问 之二十五】国计民生之电力:电力云如何点亮数智电力新引擎?

方案构建了覆盖数据获取、质量评估到标准化处理的全链路能力。基于公共云服务商智算底座及气象大模型,通过时空图神经网络重新建模产流机制,中国华电建成超50TB多源融合数据集,突破时空建模与机理融合等五大关键技术,短期径流预测精度较传统机理模型提升5个百分点以上,实现15天中期径流预测精度超85%,推理效率达秒级。基于气象大模型的基础架构与预训练能力,客户可直接在大模型之上开展增量训练与微调,充分利用场站所在区域的高精度历史数据(如3公里、1公里分辨率),针对不同场站和区域的地形地貌与气候特征进行模型调优。

华为云官方博客 381
上一篇: 【华为云技术分享】Spark如何与深度学习框架协作,处理非结构化数据
下一篇: 电商业务容器化遇瓶颈,公有云Docker镜像P2P加速很安全
华为云开发者联盟
华为云开发者联盟 企业官方账号 企业官方账号
博客等级 码龄10年 72万+粉丝 5985原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值