Amazon CloudFront 部署小指南(五)- 使用 Amazon 边缘技术优化游戏内资源更新发布...

news2024/11/26 1:51:47

b6edfd5811de9837dbe2421aec3a924d.gif

内容简介

游戏内资源包括玩家的装备/弹药/材料等素材,对游戏内资源的发布和更新是游戏运营商的一个常规业务流程,使用频率会十分高,所以游戏运营商希望该流程可以做到简化和可控。针对这个需求,我们设计了 3 个架构,面向游戏内资源更新发布的 3 个典型场景,来优化游戏内资源更新发布流程。3 个场景分别为:

  • 游戏内资源灰度更新

  • 游戏内资源分渠道投放

  • 游戏内资源黑白名单

该 3 个架构围绕亚马逊云科技 Amazon CloudFront 服务 — CloudFront 边缘计算服务 — WAF 服务展开实现。

场景一:游戏内资源灰度更新

游戏在运营过程中会有资源更新的需求,用一个简单模型来描述:老的资源 A 需要替换成成新的资源 B。不过这里有一个痛点,B 资源在推广到所有 CDN 之前,需要内部或者小范围确认资源的正确性。因此需要一种方式来保证 B 资源哪怕在源端更新了,只有受限的访问;大部分的玩家还是访问的还是 CDN 缓存内的资源 A。等 B 资源验证通过后,才会通过 CDN 刷新推广到所有的节点。

这个需求实现的难点在于:在客户端不做任何修改的情况下,使用相同的 URL 将少量用户请求引导资源 B;资源 A 和资源 B 不能共享缓存,以免引起资源访问冲突。我们采用 CloudFront Continuous Deployment 来实现这个需求:

8a2c1c20ef75ee97fd5cd90c392f03e7.jpeg

配置步骤如下:

  1. 创建 Staging Distribution

  2. 功能验证

  3. 调度流量

  4. 正式上线

CloudFront 持续部署功能在实现上比较直观,用户可以通过控制请求配比方式实现金丝雀式的资源更新;在成本上相比于部署 CloudFront 边缘脚本 CloudFront Function 会更低一些。

创建 Staging Distribution

在 CloudFront 生产 distribution 下,点击“create staging distribution”

d46c92737bcfda2983fe5e4dd477a767.png

可以输入 Staging Distribution 的描述,然后点击“Next”

1b3f8dacbba2e213cba45f8708a4e7ea.jpeg

创建一个新的源站。用户可以对应创建一个新的源站部署资源 B(使用相同目录结构);也可以在现有源站上将资源 B 部署到另外一个目录中,然后创建新的 Host 容器,并且在 DNS 服务器上创建指向新的 Host 容器的记录

93b79b687b464d369e8332b6ba57fa74.jpeg

c27565c44ae1f612e44ad81a127c3bba.png

*注意:我们在新的 origin 中改写了 origin path,使得客户端无需做变更。

流量配置选择“header-based ”比例先选择为 0

548fc8b589b343e3da06fe6808c8fd4b.jpeg

创建 Staging Distribution

be6257f0f8bf6a3835d5e14d6e7e4189.jpeg

至此 Staging Distribution 创建完毕,等待 10 分钟左右部署完毕

e5fd56f6f9d160df7fd8dbe99b216d80.png

功能验证

可以使用命令行工具 curl 进行验证:

resource_b 下载:

curl -H 'aws-cf-cd-resource:b' -v -o /dev/null 'https://www.company.com/resource'

左滑查看更多

resource_a 下载:

curl -H -v -o /dev/null 'https://www.company.com/resource'

左滑查看更多

通过观察下载的文件特征如字节数或者 ETAG 判断是否下载了不同内容的资源对象。

调度流量

点击‘Edit Policy’

21b4b0a012813e7b13eed3da24f0a269.png

在弹出窗口中修改流量调度策略,调度 1%的流量进行灰度发布

3a4571ad9ce4d2fce4f68ac1220370da.jpeg

063d907e8ca48f86aa043baae3a3ce49.png

正式上线

用户在源站正式将 Resource B 覆盖 Resource A 后,需要在 CloudFront 上进行缓存刷新,并删除 Staging Distribution

bfc190ca29d462c16d31511a7f95cfba.jpeg

759e6a8f4b0441cafe62dd58a0e31fa5.jpeg

场景二:游戏内资源分渠道投放

游戏在运营过程中会有针对不同渠道投放不同资源的需求,用一个简单模型描述:对于资源 A 和资源 B,从不同渠道进来的玩家会看到不同的资源。这里的痛点为,客户需要针对头部某个字段或者 url 中某个关键字快速匹配对应的资源。

内容概述

在这个方案构建中,我们将利用到 CloudFront Function 检查请求头部的字段,并根据匹配到的字段进行回源 URL Path 替换,此方案的好处在于,URL Path Rewrite 对于最终用户是无感知的,符合不同渠道进来的玩家对于某个相同的资源(比如资源 A),回源获取到的内容将会不同。

配置步骤如下:

  1. 创建 CloudFront Function

  2. 创建 Behavior 匹配存在不同渠道的 URL Path

  3. 实验验证及结论

创建 CloudFront Function

在此需求中,不同渠道的所获取的内容不同,意味着在源站侧(如 S3)上的路径信息不同,如用户请求的文件路径统一为/sample.file,而不同渠道在源服务上所对应的文件真实路径为/a_vendor/sapme.file 

或是/b_vendor/sample.file,我们可以根据不同渠道(携带不同的请求头信息),来对请求头值进行提取,并进行回源 URL 替换,具体 CloudFront Function 参考代码如下:

function handler(event) {
  // 获取请求头
  var request = event.request;
  var headers = event.request.headers;
  var originUrl = event.request.uri;
  
  // 检查 x-vendor-type 请求头是否存在
  if (headers['x-vendor-type']) {
    var targetObject = headers['x-vendor-type'].value


    //修改回源 URL Path 
    event.request.uri = '/' + targetObject + originUrl;
  }


  return request;
}

左滑查看更多

*注:此处 header 的值不直接取而是先进行判断的原因是,某些客户端可能不会携带 x-vendor-type 这个头,如果不增加判断直接取值,那么 header 不存在的情况将会导致 CloudFront Function 报错,在您部署代码时也可以进行相应的考虑。

CloudFront Function 代码保存完毕后,我们可以在调试界面进行调试并观察效果:

071f49643310ce291860825f5e62b7eb.png

提交调试信息后,可以看到回源路径成功被修改,如下图:

80f004c14a0fe0f481986cb67a905b57.png

调试无误后对 CloudFront 代码进行部署:

b6ea13476e01b0587b216183a9c35ad2.jpeg

创建 Behavior 匹配

存在不同渠道的 URL Path

此处,为了方便展示效果,我们在 CloudFront 中的 Behavior 根据需求,进行路径匹配,此处的匹配以“/abtest-demo*”进行展示。

d1a929fc5154b8d770256e294216e810.jpeg

由于此处仅做 URL 改写,不同渠道针对相同 URL 将会拿到不同的内容,此处您还需要在 Behavior 中针对不同的请求头进行缓存上的区分,您可以自定义 Cache Policy,并将 x-vendor-object 请求头作为 Cache Key 的一部分,以进行缓存区分:

1a02a27601f4fd96d85b9e24726942b4.jpeg

自定义 Cache Policy 后,在 Behavior 中进行应用:

3c4d62f77b706f0f6cead9c7b9d4ee07.jpeg

在 origin policy 中,需要将自定义的请求头进行透传,以便 CloudFront Function 可以进行请求头的检查,您可以自定义 Origin Policy,也可以选择 AllViewer 将自定义请求头进行透传。

由于该改写逻辑运行的 event type 是 Viewer Request,您需要在 Behavior 定义中在正确的 event 中应用上述部署的 CloudFront Function 逻辑。

44d2fe195707a786066095791b94cfd2.jpeg

实验验证及结论

在源服务侧,我们分别针对 A 和 B 渠道存放不同版本的文件,以供调试,此处示例文件对应关系如下:

渠道 A :a_vendor

渠道 B :b_vendor

携带对应的请求头,多次请求后并观测效果:

//在请求头中携带 A 渠道特殊标识,回源真实路径为/a_vendor/example.file
% curl -v http://cloudfront-function.xxxxxxx.com/example.file -H 'x-vendor-type: a_vendor' 2>&1 | egrep 'X-Cache|This content'
< X-Cache: Hit from cloudfront
This content is for a vendor!


//在请求头中携带 B 渠道特殊标识,回源真实路径为/a_vendor/example.file
% curl -v http://cloudfront-function.xxxxxxx.com/example.file -H 'x-vendor-type: b_vendor' 2>&1 | egrep 'X-Cache|This content'
< X-Cache: Hit from cloudfront
This content is for b vendor!


//在请求头中不携带渠道特殊标识,回源真实路径为/example.file
% curl -v http://cloudfront-function.xxxxxxx.com/example.file 2>&1 | egrep 'X-Cache|This content' 
< X-Cache: Hit from cloudfront
This content is for general usage without vendor!

左滑查看更多

通过以上的演示,我们成功的验证了以下三个设置需求:

  1. 您可以清楚的看到,针对相同的 URL path   为/example.file,通过不同的 x-vendor-type 指定内容,我们成功的改写了回源 URL,并根据获取到了不同渠道所对应的内容。

  2. 如果客户端不是通过渠道发起的请求,不携带特殊标识头,也可以成功拿到内容。

  3. 在命中缓存的情况下,由于 Cache Policy 将 x-vendor-type 作为缓存的一部分,在 URL 相同的情况下,请求依然可以按照预期命中到各自对应缓存。

场景三:游戏内资源黑白名单

场景描述

游戏在运营过程中会有不同玩家有不同访问行为的需求,用一个简单模型描述:对于玩家 A 需要放在白名单中,对于玩家 B 需要放置在黑名单中。

用一个更具体的场景描述:假设需要通过 WAF web ACL 去匹配出 user-agent 中包含 “PostmanRuntime/x.xx.x” 的请求,并且拒绝该请求的访问。

对于上述场景,可以通过检查请求 header 重的 User-Agent 来实现。对于请求来说,通常会经过几个链路:客户端→公网→Amazon CDN 接入点→ 原站。那么将检查 header 的压力放在 CDN 处是比较好的选择,可以有效的减少原站的压力。在 CDN 侧检测也有几种方式。最先想到的是在 CDN 上用 edge function/lambda 来实现。这里会带来的挑战是需要是维护代码。另外一种比较好的方式是利用 WAF 对于规则来进行检查。WAF 在配置 Web ACL 的时候,需要配置允许和阻止的条件。通常包含的条件有:

  • 请求是否表现为包含恶意脚本允许或阻止请求 → 跨站点脚本匹配条件

  • 请求源自的 IP 地址允许或阻止请求 →IP 匹配条件

  • 请求源自的国家/地区允许或阻止请求 →  地理匹配条件

  • 请求是否超过指定长度允许或阻止请求 → 大小约束条件

  • 请求是否表现为包含恶意 SQL 代码允许或阻止请求 →SQL 注入匹配条件

  • 出现在请求中的字符串允许或阻止请求 →字符串匹配条件

  • 出现在请求中的正则表达式模式允许或阻止请求 → 正则表达式匹配条件

默认情况下,Amazon WAF 过滤器不检查 HTTP 请求参数是否存在。要检查 HTTP 请求参数是否存在,可以采取下面两种自定义规则中的任意一种:

  • 使用字符串匹配规则

  • 使用正则表达式匹配规则

环境准备

在测试之前我们需要做如下步骤:

1. 进入 Amazon Website Service Console 界面,选择 WAF 服务,然后在左边导航栏选择 WAF ACLs。

2. 创建一个 Rule,根据业务需求命名。然后保护的对象可以是 CDN 也可以是负载均衡器之类的对外服务。资源部分可以现在就填写,也可以等待 Rule 创建完毕后再绑定。

dba413162bb6d86b0d80411e7ea5d5d1.png

3. 完成 Web ACL 的信息录入之后,在第二部我们选择自定义规则。

a9e5477ef4b9ee3032a50c25a2fc568d.png

4. 在自定义规则中,我们选择 Rule Builder。并且设置好 Rule 的名字。

5. 在 inspect 中,选择 All headers,header content 选择默认的所有 keys and values,当然可以根据业务需求只监控特定的 header 和 content。

8a7dcf936dcdea1890e49d8b139697bf.jpeg

字符串匹配规则

对于字符串匹配规则,Web ACL 提供如下几种方式:

  • Exact matches string:严格匹配字符串

  • Start swith string:匹配字符串开头

  • Ends with string:匹配字符串结尾

  • Contains string/word:包含某个字符串

根据需求,使用 Start with string 即可,设置如下:

07c5df01f8f3719306b8860f08187349.jpeg

正确表达式匹配规则

正则表达式规则,Web ACL 提供两种匹配方式:

regex pattern set:正则表达式集合,可以提前设置,在面板中选取即可

regular expression:正则表达式,临时设置

这里我们选择第二种方式,其设置参考如下

59c6ce77bd3446d973667b6e10c9393e.jpeg

最终规则的 Json 格式参考

{
  "Name": "StringMatch",
  "Priority": 0,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "StringMatch"
  },
  "Statement": {
    "OrStatement": {
      "Statements": [
        {
          "ByteMatchStatement": {
            "FieldToMatch": {
              "Headers": {
                "MatchScope": "ALL",
                "MatchPattern": {
                  "All": {}
                },
                "OversizeHandling": "CONTINUE"
              }
            },
            "PositionalConstraint": "STARTS_WITH",
            "SearchString": "PostmanRuntime",
            "TextTransformations": [
              {
                "Type": "NONE",
                "Priority": 0
              }
            ]
          }
        },
        {
          "RegexMatchStatement": {
            "FieldToMatch": {
              "Headers": {
                "MatchScope": "ALL",
                "MatchPattern": {
                  "All": {}
                },
                "OversizeHandling": "CONTINUE"
              }
            },
            "TextTransformations": [
              {
                "Type": "NONE",
                "Priority": 0
              }
            ],
            "RegexString": "/PostmanRuntime[ \\/]+([0-9\\.]+)/gi"
          }
        }
      ]
    }
  }
}

左滑查看更多

规则测试

规则建立好后,我们需要将它运用在保护的资源中。假设源站是一个网站,前面为一个 CDN,它只是返回一个 text=ok。

测试如下(User-Agent 的值为 X-UnrealEngine-Agent):

7a3297c099be1ff99fe1b4658fc1baf3.jpeg

当请求头,包含了 

PostmanRuntime/x.xx.x,可以看到请求被 block

b6a57a695a90bcac5c1bde3b3bbf5e06.jpeg

在后台的界面中,也可以统计到过去 5 分钟的 WAF 的表现情况

144d042c25b2e5d1ff0eb7b553a727b5.jpeg

可以通过以上实验,WAF 对于 CDN 的保护提供了十分灵活的配置规则,可以满足各种不同场景的需求。更进一步,它解放了 CDN 去做规则匹配和检查的压力,让 CDN 去做它更擅长的业务。

总结

通过亚马逊云科技 CloudFront 服务 — CloudFront 边缘计算服务 — WAF 服务,游戏运营商可以在不改动客户端的情况下,完成游戏内资源在预设条件下的更新发布,提高了业务部署的敏捷性和简易性。

亚马逊云科技 CloudFront 

部署小指南系列文章

Amazon CloudFront 部署小指南(一)- 快速构建 CDN 内容分发:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-one/

Amazon CloudFront 部署小指南 (二)- 进阶部署:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-two/

Amazon CloudFront 部署小指南 (三)- 持续部署:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-three/

Amazon CloudFront 部署小指南(四)- CloudFront Function 基础与诊断:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-four/

Amazon CloudFront 部署小指南(六)- Lambda@Edge 基础与诊断:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-six/

本篇作者

b783fcdcbafc13378d04523d519fd578.jpeg

叶明

亚马逊云科技边缘产品架构师,负责 CloudFront 和 Global Accelerator 服务在中国和全球的市场拓展,专注于互联网用户访问云上服务的感受的优化以及数据洞察。在互联网基础设施领域有丰富的实践经验。

a799db5f6f258445cf528b4b9f3690c7.jpeg

万曦

亚马逊云科技解决方案架构师,负责基于亚马逊云科技的云计算方案的咨询和架构设计。坚实的 Amazon Builder 文化拥抱者。拥有超过 12 年的游戏研发经验,参与过数个游戏项目的管理和开发,对于游戏行业有深度理解和见解。

7ec66f9a2bf33c10f4d6ac3667de4cd4.jpeg

王骏兴

亚马逊云科技边缘产品架构师,负责亚马逊云科技 Edge 服务领域在中国的技术推广。在 CDN 内容分发以及 WAF 领域拥有多年实战经验,专注于边缘服务设计以及体验优化。

bc19f81ae56a9bc6ba8bb2e3ede91962.gif

26e59c5bdfdd213910a76eac3da13034.gif

听说,点完下面4个按钮

就不会碰到bug了!

0531c7f488fc5f08beaa481d94a8fcd5.gif

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

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

相关文章

电商3D产品渲染简明教程

3D 渲染让动作电影看起来更酷&#xff0c;让建筑设计变得栩栩如生&#xff0c;现在还可以帮助营销人员推广他们的产品。 从最新的《阿凡达》电影到 Spotify 的上一次营销活动&#xff0c;3D 的应用让一切变得更加美好。 在营销领域&#xff0c;3D 产品渲染可帮助品牌创建产品的…

玩机搞机--【开机出现您的设备内部出现了问题,请联系你的制造商了解详情】故障解决思路

很多友友在玩机过程中经常会遇到下图所示故障。大多数都是刷了第三方系统或者内核或者面具导致的。正常来说。这个提示可以无视的&#xff0c;不影响正常的手机使用。但强迫症例外。究其原因。一般是内核校验原因。解决方法也分为多种。今天就为大家解析下这个提示的解决思路 &…

如何微调优化你的ChatGPT提示来提高对话质量

ChatGPT会话质量很大程度上取决于微调优化提示的艺术。本文旨在阐明微调提示的复杂性&#xff0c;以确保你可以充分发挥ChaGPT这一颠覆性工具的潜力。 与ChatGPT对话的关键部分是“提示”。即&#xff1a;你输入的问题或陈述&#xff0c;它决定了人工智能的响应。类似于引导对…

分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测

分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测 目录 分类预测 | Matlab实现基于MIC-BP最大互信息系数数据特征选择算法结合BP神经网络的数据分类预测效果一览基本介绍研究内容程序设计参考资料 效果一览 基本介绍 Matlab实现基于…

详解Redis三大集群模式,轻松实现高可用!

1. Redis集群简介 1.1 什么是Redis集群 Redis集群是一种通过将多个Redis节点连接在一起以实现高可用性、数据分片和负载均衡的技术。它允许Redis在不同节点上同时提供服务&#xff0c;提高整体性能和可靠性。根据搭建的方式和集群的特性&#xff0c;Redis集群主要有三种模式&…

消息队列相关面试题

巩固基础&#xff0c;砥砺前行 。 只有不断重复&#xff0c;才能做到超越自己。 能坚持把简单的事情做到极致&#xff0c;也是不容易的。 消息队列有哪些作用 1.解耦&#xff1a;使用消息队列来作为两个系统直接的通讯方式&#xff0c;两个系统不需要相互依赖了 2.异步&#…

leetcode169. 多数元素

题目 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#x…

SpringCloud实用篇6——elasticsearch搜索功能

目录 1 DSL查询文档1.1 DSL查询分类1.2 全文检索查询1.2.1 使用场景1.2.2 基本语法1.2.3 示例1.2.4 总结 1.3 精准查询1.3.1 term查询1.3.2 range查询1.3.3 总结 1.4.地理坐标查询1.4.1 矩形范围查询1.4.2 附近查询 1.5 复合查询1.5.1 相关性算分1.5.2 算分函数查询1&#xff0…

PolarDB-X 针对跑批场景的思考和实践

背景 金融行业和运营商系统&#xff0c;业务除了在线联机查询外&#xff0c;同时有离线跑批处理&#xff0c;跑批场景比较注重吞吐量&#xff0c;同时基于数据库场景有一定的使用惯性&#xff0c;比如直连MySQL分库分表的存储节点做本地化跑批、以及基于Oracle/DB2等数据库做E…

基于comsol进行共振薄膜声学超材料的模态分析

研究背景&#xff1a; 从声学超材料出现到薄膜型和薄板型声学超材料局域共振隔声机理的广泛研究&#xff0c;其负等效质量和负等效密度特性打破了传统吸隔声材料质量定律的限制&#xff0c;为低频吸隔声提供了新途径。由吸声系数理论模型可知&#xff0c;薄膜型结构的吸声性能…

JavaScript之BOM+window对象+定时器+location,navigator,history对象

一.BOM概述 BOM即浏览器对象模型,它提供了独立于内容而与窗口进行交互的对象 BOM的顶级对象是window 二.window对象的常见事件 1.窗口加载事件window.onload window.onload function(){} 或者 window.addEventListener("onload" , function(){}); window.onlo…

简单易用且高效的跨平台开发工具:Xojo 2023 for Mac

Xojo for Mac是Mac平台上一个跨平台的针对桌面、Web、移动和Raspberry Pi的快速应用程序开发软件。与其他多平台开发工具相比&#xff0c;Xojo for Mac为开发人员提供了显着的生产率提高。 Xojo for Mac具有拖放功能&#xff0c;使您能够快速创建用户界面设计&#xff0c;然后…

构造函数——初始化列表

初始化列表的引入。 #include<iostream> using namespace std;//栈类 typedef int DataType; class Stack { public://默认构造&#xff1a;Stack(size_t capacity ){cout << "Stack()" << endl;_array (DataType*)malloc(sizeof(DataType) * ca…

MSDN镜像和版本的区别

重装系统 前言 装系统本质上就是运行U盘内放好的windows安装包&#xff0c;目前U盘有三种格式化方式&#xff0c;分别是FAT32 exFAT NTFS ,后面两个方式很挑主板&#xff0c;老旧主板胡总和老旧电脑无法识别&#xff0c;选用FAT32种方式进行格式化&#xff0c;几乎所有的设备都…

连锁酒店(民宿)多商户全开源版 (多店模块版),支持创建多个小程序

手边酒店多商户小程序支持创建多个小程序&#xff0c;更合适平台型或者连锁酒店使用。后台支持一键入住&#xff0c;一键退款、退押金、钟点房支持微信支付、模板消息。客服实时收到新的订单信息&#xff0c;可以在手机端处理订单。支持按日期维护房价和房间数量&#xff0c;支…

分布式 - 消息队列Kafka:Kafka消费者和消费者组

文章目录 1. Kafka 消费者是什么&#xff1f;2. Kafka 消费者组的概念&#xff1f;3. Kafka 消费者和消费者组有什么关系&#xff1f;4. Kafka 多个消费者如何同时消费一个分区&#xff1f; 1. Kafka 消费者是什么&#xff1f; 消费者负责订阅Kafka中的主题&#xff0c;并且从…

最新版本的Anaconda环境配置、Cuda、cuDNN以及pytorch环境一键式配置流程

本教程是最新的深度学习入门环境配置教程&#xff0c;跟着本教程可以帮你解决入门深度学习之前的环境配置问题。同时&#xff0c;本教程拒绝琐碎&#xff0c;大部分以图例形式进行教程。这里我们安装的都是最新版本~ 文章目录 一、Anaconda的安装1.1 下载1.2 安装1.3 环境配置…

STM32CubeMX之freeRTOS互斥量

这是大哥保护小弟的故事 高中低等级的任务 互斥量就是谁要敢插我小弟的队&#xff0c;我就要打他&#xff0c;不能让其他人插我小弟的队 互斥量的使用是默认开启的不用手动开启&#xff01; 最高优先级任务&#xff1a;延时&#xff08;10ms&#xff09;再上厕所 中间&#x…

2023年录屏软件哪个好用,Camtasia Studio2023安装激活教程最新激活密钥

2023年录屏软件哪个好用&#xff0c;电脑Windows10系统自带录屏不是挺香吗&#xff0c;干嘛还需要安装录屏软件&#xff01;系统自带的录屏功能有一定局限限&#xff0c;想要录制其他文件、软件内容根本不好用&#xff1b;与其费时费力研究系统自带&#xff0c;不如选择好用的录…

matlab解微分方程:方向场

在微分方程中&#xff0c;常见的形式是&#xff1a; x ′ f ( x , t ) xf(x,t) x′f(x,t) 方向场的每一个矢量可以形象地刻画一阶微分方程的解。在方向场中的每个点处&#xff0c;都会出现一条其斜率等于通过该点的微分方程解的矢量。给定一个初值&#xff0c;微分方程对应一条…