Web 性能优化|了解 HTTP 协议后才能理解的预加载

news2024/11/24 11:13:24

Web 性能优化|了解 HTTP 协议后才能理解的预加载

作者:谦行

一、前言

在性能优化过程中,开发者通常会集中精力在以下几个方面:服务器响应时间(RT)优化、服务端渲染(SSR)与客户端渲染优化、以及静态资源体积的减少。然而,对于许多用户进入网站的第一个页面(如首页),网络开销也是一个不容忽视的问题。





由于新用户可能从未与网站建立连接,从 DNS 查询到 TCP 连接,再到下载服务器返回的内容,这些步骤的耗时通常远远超过服务器的响应时间。而多数情况下开发者无法通过代码优化来减少这部分时间消耗。

为了解决新用户访问网站时可能遇到的网络开销问题,我们可以借助多种预加载技术在用户实际需要之前提前加载资源,从而减少等待时间,实现更流畅的用户体验。接下来本文将详细探讨几种常见的预加载方法,并在 prefetch、preload 等基础上,结合流式渲染、HTTP Early Hints、HTTP/2 push 等技术,对预加载技术灵活运用,从而在用户到达网站的瞬间就提供无缝、快速的访问体验。

二、CDN 动态加速

在开始介绍预加载之前,其实开发者可以通过 CDN 动态加速优化用户与服务器的建连、内容传输时间。CDN 通常被用来加速静态资源的传输,比如图像、JavaScript 和 CSS,这个大部分开发者非常熟悉,但现代的 CDN 技术已经不仅仅局限于静态内容的优化,大部分 CDN 厂商可以利用其全球广泛分布的边缘节点服务器为网站提供动态内容的访问加速。

用户访问网站动态内容需要通过互联网连接到源站服务器,这个过程中数据需要经过多个网络节点和长距离传输,容易受到各种网络拥塞和延迟的影响。





使用 CDN 动态加速时,CDN 通过在全球分布的边缘节点缓存和处理用户请求,显著缩短了从用户到服务器的物理距离,减少了传输延迟。同时 CDN 服务商会实时监控全球的网络状态,通过智能路由技术选择当前最优的路径传输数据,这避免了网络中的拥塞和瓶颈,确保数据以最快的速度传输到用户端。





当然如果使用了 CDN 提供的边缘计算能力,可以让用户直接从 CDN 边缘节点获取动态内容,进一步加速动态内容的访问。



三、dns-prefetch DNS 预解析

当浏览器需要访问特定域名时,必须先将先将域名解析为 IP 地址,这一步骤就是 DNS 解析。dns -prefetch 可以让浏览器提前在后台完成这一解析工作,避免用户在实际请求资源时等待 DNS 解析的时间。

在 HTML 顶部通过<link>标签来指示浏览器对接下来要是用的静态资源、动态接口等域名提前进行 DNS 解析。

<link rel="dns-prefetch" href="//example.com">

四、preconenct 域名预建连

除了对域名进行解析、建连,还可以通过 preload 和 prefetch 对页面将要使用的资源提前下载。

preload 是一种声明式资源引入方式,用来强制浏览器在合适的时机加载指定资源,通常用于关键资源(如字体、脚本、样式表等)的预加载,以确保这些资源能够尽快被使用。

<link rel="preload" href="styles.css" as="style"><link rel="preload" href="main.js" as="script"><link rel="preload" href="image.jpg" as="image">

prefetch 同样是一种声明式资源请求方式,用于提示浏览器在空闲时下载未来可能用到的资源,适合作为页面未来使用的资源或者当前页面下一跳页面要使用的资源预加载。

<link rel="prefetch" href="next-page-image.jpg"><link rel="prefetch" href="next-page-script.js">

两个标签在优先级上有一定的区别:

  • preload:具有高优先级,浏览器会立即加载这些资源;

  • prefetch:具有较低优先级,只有在浏览器空闲时才会加载这些资源,确保不妨碍当前页面的正常加载;

两者在浏览器支持上各有千秋:

五、prerender 预渲染

使用 prerender 可以将目标页面上近乎所有资源(HTML、CSS、JavaScript、图像等)和内容在后台提前下载并渲染,浏览器在用户首次访问该页面之前已经完全准备好了该页面的视图。这样当用户跳转到该页面时,使用户在实际跳转到这个页面时能够立即呈现,不需要再等待加载和渲染的时间。

<link rel="prerender" href="https://example.com/next-page">

听起来 prerender 是预加载的终极方案了,但在实际性能优化方案中却很少被使用,使用 preload 有几个弊端:

  • 不能命中时候资源开销过大:因为 prerender 会对页面进行资源下载和渲染,当页面没有被用户访问时候造成的资源浪费过大;

  • 影响页面数据统计:大部分页面在执行时候会对页面进行数据上报用作后续的页面效果分析,部分页面会有展示广告等行为,如果 prerender 后用户没有访问页面,会造成数据统计上的混乱;

  • 浏览器兼容性问题:不同的浏览器对于 prerender 的实现细节可能有所不同。例如,一些浏览器可能出于性能或安全考虑,会对预渲染的资源类型进行某些限制;



六、根据用户行为 prefetch 下一跳页面

无脑对页面进行 prefetch 会造成巨大的资源浪费,但很多时候我们可以根据用户行为更精准的预测用户接下来的动作,再进行 prefetch 可以很大程度上减少资源浪费。

举个例子,在 PC 页面当用户鼠标悬停在某个商品图片上时候,我们可以大胆预测用户及大概率要点击页面,这时候可以对页面进行 prefetch。如果希望进一步细化,用户点击鼠标的动作会依次触发 mousedown、mouseup、click 事件,我们可以在 mousedown 事件中对页面进行预载,这样可以节省人点击鼠标的 200ms 左右。

function App() {  return (    <div className="App">      <h1>Product List</h1>      <div className="product-list">        <Product id="1" name="Product 1" imageUrl="https://via.placeholder.com/150" prefetchUrl="/next-page-1" />        <Product id="2" name="Product 2" imageUrl="https://via.placeholder.com/150" prefetchUrl="/next-page-2" />        <Product id="3" name="Product 3" imageUrl="https://via.placeholder.com/150" prefetchUrl="/next-page-3" />      </div>    </div>  );}
const Product = ({ id, name, imageUrl, prefetchUrl, delay=200 }) => {  const [prefetchTimeout, setPrefetchTimeout] = useState(null);
  const handleMouseOver = () => {    const timeout = setTimeout(() => {      const link = document.createElement('link');      link.rel = 'prefetch';      link.href = prefetchUrl;      link.credentials = 'include';      document.head.appendChild(link);    }, delay);
    // 防止用户快速    setPrefetchTimeout(timeout);  };
  const handleMouseOut = () => {    // 如果过度发 prefetch 请求    clearTimeout(prefetchTimeout);  };
  return (    <div className="product"         onMouseOver={handleMouseOver}         onMouseOut={handleMouseOut}>      <img src={imageUrl} alt={name} loading="lazy" />      <p>{name}</p>    </div>  );}

6.1 添加 credentials 属性,携带 cookie

安全原因 prefetch 请求默认不携带 cookie,为了让 prefetch 请求携带 cookie, 可以在 prefetch 的 link 标签中添加 credentials 属性,并将其设置为 "include"。

<link rel="prefetch" href="..." as="script" credentials="include">

6.2 服务器设置缓存

因为大部分动态页面为了给用户传输动态内容是禁用客户端缓存的,所以即使发了 prefetch 请求也无法做到用户真实点击的时候复用 prefetch 请求,反而会重新发请求造成资源浪费。

因此需要在服务端识别 prefetch 请求,设置短时间的客户端缓存,当用户很快真实访问 prefetch 的页面后可以复用缓存。

浏览器发送的 prefetch 请求会携带 HTTP Header Sec-Purpose: prefetch 或 Purpose: prefetch,服务端根据这个属性识别 prefetch 请求。

app.get('/next-page', (req, res) => {  const purposeHeader = req.headers['purpose'] || req.headers['sec-purpose'];  if (purposeHeader === 'prefetch') {    res.set('Cache-Control', 'max-age=10'); // 设置缓存策略    console.log('Prefetch request detected, setting cache.');  } else {    console.log('Regular request detected, no cache.');  }  res.send(`    <h1>Next Page Content</h1>    <p>This is the next page that was prefetched.</p>`  );});

七、页面与首屏请求并行加载

上述方案在 SSR 页面效果显著,但在 CSR 页面可能优化效果有限,主要原因是 CSR 页面内容存储在 CDN 甚至客户端本地缓存,本身加载很快,页面的渲染主要依赖动态接口的返回。





如果我们可以知道页面首屏渲染需要发起的请求,其实可以利用和上面类似的原理,在用户点击页面的瞬间同时发起异步请求,当解析执行 JavaScript 脚本发送异步请求时可以判断本地已经有缓存,直接使用结果。





原理非常类似,不再代码演示,核心还是请求:

  • 设置 credentials 请求可以携带 cookie;

  • 服务端识别 prefetch 请求,对接口设置短时间的缓存;

这样的方案最大程度利用了浏览器的特性实现起来比较简单,对 Service Worker 熟悉的话可以利用 Service 做更复杂的控制。

八、Speculation Rules API

Speculation Rules API 是一个新的 Web API,提供一种声明式的方法来指示浏览器应该对哪些链接进行预取操作,通过这个 API,开发者可以更精确地指示浏览器在何时和如何预取资源,从而显著提升网页性能和用户体验。

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8">    <title>Speculation Rules API</title>    <!-- Speculation rules -->    <script type="speculationrules">      {        "prefetch": []      }</script>  </head>  <body>    <a href="/page1.html" data-prefetch-url="/page1.html">Go to Page 1</a>    <a href="/page2.html" data-prefetch-url="/page2.html">Go to Page 2</a>    <a href="/page3.html" data-prefetch-url="/page3.html">Go to Page 3</a>
    <script>      function addPrefetchRule(url) {        const speculationRulesScript = document.querySelector('script[type="speculationrules"]');        const rules = JSON.parse(speculationRulesScript.textContent);
        // 检查 rule 是不是已经设置        if (!rules.prefetch.some(rule => rule.urls.includes(url))) {          rules.prefetch.push({            "source": "list",            "urls": [url]          });
          // 更新 speculation rules          speculationRulesScript.textContent = JSON.stringify(rules);          console.log(`Prefetch rule added for: ${url}`);        }      }
      // 鼠标 hover 时候添加      document.querySelectorAll('a[data-prefetch-url]').forEach(link => {        link.addEventListener('mouseover', () => {          const url = link.getAttribute('data-prefetch-url');          addPrefetchRule(url);        });      });</script>  </body></html>

Speculation Rules API 目前还处于早期阶段,未来可能会看到更多的浏览器开始支持这一 API,并且 API 本身也可能会引入更多的功能和配置选项。

九、页面部分内容提前返回

9.1 流式渲染简介

流式渲染(Streaming Rendering)是指在服务器上生成页面内容时,逐步将已准备好的部分内容立刻发送到客户端,而不是等待页面所有内容全部生成才开始发送,使客户端可以更快的接收数据渲染页面,而不必等待整个页面的内容完全下载,从而实现快速的页面加载和用户可视化体验。这个过程像是水管中的水一样流动起来源源不断,因此被称为流式渲染。

流式渲染实际上一个非常古老的技术,早在 HTTP 1.1 规范中就已经引入了 Transfer-Encoding: chunked 头字段,允许服务器将响应内容分批返回给客户端。服务器可以在生成响应内容的同时,将其分成小块,逐步传输给客户端,而不是等待所有内容生成完成后再返回。

在浏览器端,早期的浏览器(如 Netscape Navigator 和 IE)就已经支持对部分 HTML 内容进行解析和执行。当浏览器接收到服务器返回的部分 HTML 内容时,它可以立即开始解析和执行该内容,而不需要等待所有内容加载完成。





const http = require('http');
http  .createServer((req, res) => {    res.writeHead(200, {      'Content-Type': 'text/html',      'Transfer-Encoding': 'chunked',    });    function renderChunk(chunk) {      res.write(`<div>${chunk}</div>`);    }
    renderChunk('Loading...');
    setTimeout(() => {      renderChunk('Chunk 1');    }, 1000);
    setTimeout(() => {      renderChunk('Chunk 2');    }, 2000);
    setTimeout(() => {      renderChunk('Chunk 3');    }, 3000);
    setTimeout(() => {      renderChunk('done!');      res.write('</body></html>');      res.end();    }, 4000);  })  .listen(3000, () => {    console.log('Server listening on port 3000');  });

9.2 开启流式渲染后的新思路

页面支持流式渲染之后我们可以利用等待服务器计算生成动态内容的空档,提前返回页面部分内容,在浏览器完成关键域名的预建连、核心资源的预加载,严格来讲下面讲的很多内容其实是 HTTP 协议实现的,但思路上和流式渲染原理一致,所以放在一块来讨论。

9.3 提前返回 preconnenct、preload 标签

页面可以对静态部分做缓存,接收到用户请求后流式渲染直接返回(其实这种最适合利用 CDN 边缘渲染)。

页面静态部分 public/static.html

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>Optimized Page</title>  <!-- Preconnect to an external domain -->  <link rel="preconnect" href="https://fonts.googleapis.com">  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>    <!-- Preload a critical CSS file -->  <link rel="preload" href="/styles/main.css" as="style">    <!-- Preload an important image -->  <link rel="preload" href="/images/hero-banner.jpg" as="image"></head><body>

如果服务器 RT 过长,甚至可以反直觉的在页面顶部预载 JavaScript 文件,但不执行。

server.js

const http = require('http');const path = require('path');const fs = require('fs');
const filePath = path.join(__dirname, 'public', 'static.html');
http  .createServer((req, res) => {    res.writeHead(200, {      'Content-Type': 'text/html',      'Transfer-Encoding': 'chunked',    });
    function renderChunk(chunk) {      res.write(`<div>${chunk}</div>`);    }
    fs.readFile(filePath, 'utf8', (err, firstFragment) => {      // 返回静态部分,浏览器提前建连、加载      renderChunk(firstFragment);    });
    renderChunk('Loading...');
    setTimeout(() => {      // 复杂的服务端计算      renderChunk('done!');      res.write('</body></html>');      res.end();    }, 4000);  })  .listen(3000, () => {    console.log('Server listening on port 3000');  });

9.4 根据数据生成 preload html 片段

其实我们还可以把服务器 RT 部分细分,🙋‍♀️🌰 页面取数部分实际非常复杂,而恰好首屏呈现的部分内容取数很快,后续取数或 SSR 很慢。

  • 服务器首屏取数

  • 服务器取数 2

  • 服务器取数 3

  • 调用页面 SSR

  • 返回服务武器渲染部分

这种时候可以在调用 ssr 之前,解析首屏数据生成,如果包含图片,可以生成 preload 标签,提前返回到浏览器,甚至对首屏部分调用占位的 SSR。

const http = require('http');
http  .createServer((req, res) => {    res.writeHead(200, {      'Content-Type': 'text/html',      'Transfer-Encoding': 'chunked',    });
    function renderChunk(chunk) {      res.write(`<div>${chunk}</div>`);    }       setTimeout(async () => {      const firstData = await getFirstScreenData();      renderChunk(`        <link rel="preload" href="${firstData.imgSrc}" as="image">      `);    }, 1000);
    setTimeout(() => {      // 复杂的服务端计算      renderChunk('done!');      res.write('</body></html>');      res.end();    }, 4000);  })  .listen(3000, () => {    console.log('Server listening on port 3000');  });

用了此类技术的页面效果:





9.5 http header 返回后续域名 preconenct

除了在 HTML 中通过 link 标签支持 preconnect,足够了解 HTTP 协议后我们还可以更快一些,在 HTTP header 中设置 preconenct,这就是 HTTP Link。

HTTP/2 200 OKContent-Type: text/htmlLink: <https://example.com>; rel=preconnect, <https://fonts.googleapis.com>; rel=preconnect

server.js

app.get('/', (req, res) => {  // Set Link headers for preconnect  res.set('Link', [    '<https://example.com>; rel=preconnect',    '<https://fonts.googleapis.com>; rel=preconnect'  ].join(', '));    // Flush headers to send them immediately  res.flushHeaders();
  // Stream the HTML file  const readStream = fs.createReadStream('content');
  readStream.pipe(res);});

十、HTTP/2 push

HTTP/2 Push 是 HTTP/2 协议中的一种功能,允许服务器在响应客户端请求时,主动将多个资源推送给客户端,而无需客户端明确请求这些资源。





在 NGINX 中,http2_push 指令用于启用或禁用 HTTP/2 push。

server {    listen 443 ssl http2;    server_name localhost;
    ssl_certificate /path/to/your/certificate.crt;    ssl_certificate_key /path/to/your/private.key;
    location / {        root /path/to/your/web/content;        index index.html;               # 启用 HTTP/2 推送        http2_push_preload on;            http2_push banner.jpg;    }}

看起来怎么这么熟悉,没错,HTTP/2 push 在很多时候就是利用 HTTP Link 特性实现的。

server {    listen 443 ssl http2;    server_name localhost;
    ssl_certificate /path/to/your/certificate.crt;    ssl_certificate_key /path/to/your/private.key;
    location / {        root /path/to/your/web/content;
        # 启用 HTTP/2 推送        http2_push_preload on;
        # 发送 HTML 文档的同时,告诉客户端推送资源        add_header Link "<banner.jpg.css>; as=image; rel=preload";    }}

不过通过 Nginx 配置来完成这个工作过于不灵活,大部分时候是通过上面讲的在服务代码中实现。

十一、Early Hints

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103

在 HTTP 1xx 的状态码用来告示客户端继续进行请求或等待更详细的响应,比如在 WebSocket 交换协议期间返回的 101。

HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: Upgrade

还有一个专门用于服务器希望发送最终响应头部之前,提供一些消息头,客户端可以开始预加载资源的 103 —— Early Hints,其作用和前面提到的 http link 非常类似。

HTTP/1.1 103 Early HintsLink: </style.css>; rel=preload; as=style

server.js

app.get('/', (req, res) => {  // Send 103 Early Hints response to client  res.status(103).set({    Link: [      '</styles/main.css>; rel=preload; as=style',      '</images/example.jpg>; rel=preload; as=image',    ].join(', ')  }).end();
  // Set up final response  const readStream = fs.createReadStream('content');  res.set('Content-Type', 'text/html');
  // Stream the final response content  readStream.pipe(res);});

Early hints preconnect 已经在主流浏览器都得到普遍支持,preload Safari 还没有支持 Web  。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2196554.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C(十五)函数综合(一)--- 开公司吗?

在这篇文章中&#xff0c;杰哥将带大家 “开公司”。 主干内容部分&#xff08;你将收获&#xff09;&#xff1a;&#x1f449; 为什么要有函数&#xff1f;函数有哪些&#xff1f;怎么自定义函数以及获得函数的使用权&#xff1f;怎么对函数进行传参&#xff1f;函数中变量的…

[嵌入式Linux]—STM32MP1启动流程

STM32MP1启动流程 1.启动模式 STM32MP1等SOC支持从多种设备中启动&#xff0c;如EMMC、SD、NAND、NOR、USB、UART等。其中USB、UART是作为烧录进行启动的。 STM32MP1内部ROM中存储有一段出厂代码来进行判断从哪种设备中启动&#xff0c;上电后这段代码会被执行&#xff0c;这…

使用java函数逆序一个单链表

代码功能 定义了一个ListNode类&#xff0c;用于表示单链表的节点&#xff0c;每个节点包含一个整数值和一个指向下一个节点的引用。 在ReverseLinkedList类的main方法中&#xff0c;创建了一个包含从1到10的整数的单链表。 定义了一个printList方法&#xff0c;用于打印链表的…

基于JavaWeb开发的java springmvc+mybatis酒水商城管理系统设计和实现

基于JavaWeb开发的java springmvcmybatis酒水商城管理系统设计和实现 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承…

【JAVA基础】集合类之HashSet的原理及应用

近期几期内容都是围绕该体系进行知识讲解&#xff0c;以便于同学们学习Java集合篇知识能够系统化而不零散。 本文将介绍HashSet的基本概念&#xff0c;功能特点&#xff0c;使用方法&#xff0c;以及优缺点分析和应用场景案例。 一、概念 HashSet是 Java 集合框架中的一个重…

Spring Boot实现License生成与校验详解

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 在软件开发领域&#xff0c;License&#xff08;许可证&#xff09;机制是保护软件版权、控制软件使用范围的重要手段。通过为软件生成唯一的License&#xff0c;开发者可以确保只有合法用户才能使用软件&…

右键菜单添加 Open Tabby here

如果安装了Tabby&#xff0c;为了提高效率在鼠标右键菜单中添加Open Tabby here&#xff0c;可以通过按 win R&#xff0c;并输入regedit 回车打开注册表编辑器 计算机\HKEY_CLASSES_ROOT\Directory\Background\shell 然后在Shell下面新建项&#xff0c;名称为Tabby&#xf…

企业架构理论TOGAF从理论到实践:引领企业数字化转型的实践指南

在现代企业面临的数字化转型浪潮中&#xff0c;如何从战略层面实现技术与业务的全面融合&#xff0c;成为了众多企业的核心挑战。TOGAF&#xff08;The Open Group Architecture Framework&#xff09;不仅为企业提供了强大的理论框架&#xff0c;还通过实践验证了其在推动企业…

力扣 中等 39.组合总和

文章目录 题目介绍解法 题目介绍 解法 是216组合总和III链接的扩展 class Solution {List<List<Integer>> res new ArrayList<>();List<Integer> path new ArrayList<>();public List<List<Integer>> combinationSum(int[] can…

Windows 下安装mamba_ssm 记录,包括causal-conv1d和mamba-ssm

Windows 下安装mamba_ssm 记录 1 重要参考文献2 具体安装步骤3 一些提醒事项4 安装causal-conv1d5 安装mamba-ssm6 结果展示 1 重要参考文献 Window 下Mamba 环境安装踩坑问题汇总及解决方法 2 具体安装步骤 重点看的是这篇 Window 下Mamba 环境安装踩坑问题汇总及解决方法 …

【Redis】持久化(下)-- AOF

文章目录 AOF概念如何使用AOFAOF工作流程命令写入演示文件同步策略 AOF的重写机制概念触发重写机制AOF重写流程 启动时数据恢复混合持久化总结 AOF 概念 AOF持久化:以独立日志的方式记录每次的写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的.AOF的主要作用是解决…

工行企业网银U盾展期后有两个证书问题的解决方法

工行企业网银U盾证书快到期后&#xff0c;可以自助展期&#xff0c;流程可以根据企业网银提示页面操作。操作后&#xff0c;可能存在两个新旧两个证书并存的情况&#xff0c;致使网银转账等操作失败&#xff0c;如图&#xff1a; 其原因是新证书生成后&#xff0c;旧证书没有删…

wsl配置图形显示环境 no $display environment variable

wsl运行fsl&#xff0c;安装好之后&#xff0c;可以使用bet&#xff0c;等命令行进行操作&#xff0c;但是不能使用fsl呼出窗口。 因为 wsl并不像原生linux具有destop桌面&#xff0c;它只有命令行。所以当运行fsl的时候会报错&#xff0c; application-specific initializat…

裁掉数千人、把工作外包给 AI!一年多后,这家巨头的 CEO恳求无人搭理

“对&#xff0c;裁掉几千名员工。” “好的&#xff0c;头儿。” “很好&#xff0c;那么这个人工智能可以做那些前雇员能做的一切事情&#xff1f;” “不&#xff0c;不全是。” “等等&#xff0c;什么&#xff1f;” “你刚刚裁掉的几百人都是硬件工程师&#xff0c;…

k8s的pod的管理和优化

资源管理介绍 在kubernetes中&#xff0c;所有的内容都抽象为资源&#xff0c;用户需要通过操作资源来管理kubernetes。 kubernetes的本质上就是一个集群系统&#xff0c;用户可以在集群中部署各种服务 所谓的部署服务&#xff0c;其实就是在kubernetes集群中运行一个个的容器…

Kubernetes--深入理解Pod资源管理

文章目录 kubectl --helpapi-resourcesapi-versionskubectl explain ... API资源资源规范PodServiceConfigMapSecret 显示资源删除资源详细描述RESTful API Pod资源管理Pod的核心概念Pod资源配置了解Pod运行状况Kubectl get pods xxxxkubectl describe pods xxxkubectl logs -f…

如何彻底掌握 JavaScript 23种设计模式

设计模式是解决特定问题的常用解决方案&#xff0c;它们可以帮助开发者编写更清晰、可维护、可扩展的代码。在 JavaScript 中&#xff0c;常见的设计模式可以分为三大类&#xff1a;创建型模式、结构型模式 和 行为型模式。本文将全面介绍 JavaScript 中常见的设计模式&#xf…

性能剖析利器-Conan|得物技术

作者 / 得物技术 - 仁慈的狮子 目录 一、背景 1. 局限性 2. 向前一步 二、原理剖析 1. 系统架构 2. 工作模式 3. reporter 三、稳定性验证 四、案例分析 五、写在最后 一、背景 线上问题的定位与优化是程序员进阶的必经之路&#xff0c;常见的问题定位手段有日志排查、分布式链…

脑机接口技术的未来与现状:Neuralink、机械手臂与视觉假体的突破

近年来&#xff0c;脑机接口&#xff08;BCI&#xff09;技术发展迅速&#xff0c;不仅限于科幻小说和电影&#xff0c;已经逐步进入现实应用。特别是马斯克的Neuralink公司推出的“盲视&#xff08;Blindsight&#xff09;”设备&#xff0c;最近获得了FDA的突破性设备认定&am…

IEC104规约的秘密之八----应用任务优先级

所谓应用任务优先级&#xff0c;就是同时出现不同的应用任务时&#xff0c;优先发哪个报文。这里有一个表格&#xff0c;可以做为参考&#xff0c;一般是在子站来实现&#xff0c;子站是数据提供方&#xff0c;需要对各种任务的优先级进行排序&#xff0c;以满足应用的实际需要…