秒杀系统的设计和思考

2023-11-01

秒杀系统的难点

首先我们先看下秒杀场景的难点到底在哪?在秒杀场景中最大的问题在于容易产生大并发请求、产生超卖现象和性能问题,下面我们分别分析下下面这三个问题:

1)瞬时大并发: 一提到秒杀系统给人最深刻的印象是超大的瞬时并发,这时你可以联想到小米手机的抢购场景,在小米手机抢购的场景一般都会有10w+的用户同时访问一个商品页面去抢购手机,这就是一个典型的瞬时大并发,如果系统没有经过限流或者熔断处理,那么系统瞬间就会崩掉,就好像被DDos攻击一样;

2)超卖:秒杀除了大并发这样的难点,还有一个所有电商都会遇到的痛,那就是超卖,电商搞大促最怕什么?最怕的就是超卖,产生超卖了以后会影响到用户体验,会导致订单系统、库存系统、供应链等等,产生的问题是一系列的连锁反应,所以电商都不希望超卖发生,但是在大并发的场景最容易发生的就是超卖,不同线程读取到的当前库存数据可能下个毫秒就被其他线程修改了,如果没有一定的锁库存机制那么库存数据必然出错,都不用上万并发,几十并发就可以导致商品超卖;

3)性能: 当遇到大并发和超卖问题后,必然会引出另一个问题,那就是性能问题,如何保证在大并发请求下,系统能够有好的性能,让用户能够有更好的体验,不然每个用户都等几十秒才能知道结果,那体验必然是很糟糕的;


一些方法

1、限流

目的: 限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务(定向到错误页或告知资源没有了)、排队或等待(比如秒杀、评论、下单)、降级(返回兜底数据或默认数据,如商品详情页库存默认有货)。

方案: 一般开发高并发系统常见的限流有:限制总并发数(比如数据库连接池、线程池)、限制瞬时并发数(如nginx的limit_conn模块,用来限制瞬时并发连接数)、限制时间窗口内的平均速率(如Guava的RateLimiter、nginx的limit_req模块,限制每秒的平均速率);其他还有如限制远程接口调用速率、限制MQ的消费速率。另外还可以根据网络连接数、网络流量、CPU或内存负载等来限流。

常见的限流算法: 令牌桶、漏桶。计数器也可以进行粗暴限流实现。
1):令牌桶算法
令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。令牌桶算法的描述如下:

  • 假设限制2r/s,则按照500毫秒的固定速率往桶中添加令牌;

  • 桶中最多存放b个令牌,当桶满时,新添加的令牌被丢弃或拒绝;

  • 当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上;

  • 如果桶中的令牌不足n个,则不会删除令牌,且该数据包将被限流(要么丢弃,要么缓冲区等待)。

2)漏桶算法:
漏桶作为计量工具(The Leaky Bucket Algorithm as a Meter)时,可以用于流量整形(Traffic Shaping)和流量控制(TrafficPolicing),漏桶算法的描述如下:

  • 一个固定容量的漏桶,按照常量固定速率流出水滴;

  • 如果桶是空的,则不需流出水滴;

  • 可以以任意速率流入水滴到漏桶;

  • 如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。

3) 令牌桶和漏桶对比:

  • 令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求;

  • 漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;

  • 令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌),并允许一定程度突发流量;

  • 漏桶限制的是常量流出速率(即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次又是2),从而平滑突发流入速率;

  • 令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率;

两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果是一样的。

4)过载保护: 对于一个应用系统来说一定会有极限并发/请求数,即总有一个TPS/QPS阀值,如果超了阀值则系统就会不响应用户请求或响应的非常慢,因此我们最好进行过载保护,防止大量请求涌入击垮系统。apiGateway可以设计过载保护策略,设置一段时间允许的连接数。
5)分布式限流:

  • 分布式限流出现的原因:当应用为单点应用时,只要应用进行了限流,那么应用所依赖的各种服务也都得到了保护。但线上业务出于各种原因考虑,多是分布式系统,单节点的限流仅能保护自身节点,但无法保护应用依赖的各种服务,并且在进行节点扩容、缩容时也无法准确控制整个服务的请求限制。而如果实现了分布式限流,那么就可以方便地控制整个服务集群的请求限制,且由于整个集群的请求数量得到了限制,因此服务依赖的各种资源也得到了限流的保护。在这里插入图片描述
    在这里插入图片描述

  • 既然要达到分布式全局限流的效果,那自然需要一个第三方组件来记录请求的次数。其中 Redis 就非常适合这样的场景。每次请求时将方法名进行md5加密后作为Key 写入到 Redis 中,超时时间设置为 2 秒,Redis 将该 Key 的值进行自增。当达到阈值时返回错误。写入 Redis 的操作用 Lua 脚本来完成,利用 Redis 的单线程机制可以保证每个 Redis 请求的原子性。

  • 假设将应用部署到多台机器,应用级限流方式只是单应用内的请求限流,不能进行全局限流。因此我们需要分布式限流和接入层限流来解决这个问题。分布式限流最关键的是要将限流服务做成原子化,而解决方案可以使使用Redis+lua或者nginx+lua技术进行实现,通过这两种技术可以实现的高并发和高性能。首先我们来使用redis+lua实现时间窗内某个接口的请求数限流,实现了该功能后可以改造为限流总并发/请求数和限制总资源数。
    Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。Lua本身就是一种编程语言,也可以使用它实现复杂的令牌桶或漏桶算法。Lua 脚本功能是 Reids在 2.6 版本的最大亮点, 通过内嵌对 Lua 环境的支持, Redis 解决了长久以来不能高效地处理 CAS (check-and-set)命令的缺点, 并且可以通过组合使用多个命令, 轻松实现以前很难实现或者不能高效实现的模式。 Lua脚本是类似Redis事务,有一定的原子性,不会被其他命令插队,可以完成一些Redis事务性的操作。这点是关键。知道原理了,我们就写一个脚本把判断库存扣减库存的操作都写在一个脚本丢给Redis去做,那到0了后面的都Return False了。

2、流量削峰

目的: 针对于秒杀场景来说,流量往往在一个特定时间点有个高度集中的流量洪峰,这个瞬时对于资源的消耗是很大的,这时往往对于服务的稳定性带来了极大的挑战,如果按照流量洪峰预估系统资源,则可能存在极大的资源浪费。所以协调好处理流量洪峰和资源利用率,最好的方式就是设计错峰方案进行流量削峰。削峰目的:让服务处理请求更加平缓,节省服务器资源。针对于削峰来说,本质上是延缓用户请求的发送,减少和过滤一些无效请求。

方案: 一般采用以下方式:排队、答题、分层过滤
算法:
1)消息队列: 消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,有消息系统来确保信息的可靠专递,消息发布者只管把消息发布到MQ中而不管谁来取,消息使用者只管从MQ中取消息而不管谁发布的,这样发布者和使用者都不用知道对方的存在。典型的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作,作为消息放入消息队列。

流量削峰首先想到的就是队列,将同步的请求转换成异步请求,将流量峰值通过消息队列平缓推送过去。在高并发分布式环境下,由于来不及同步处理,通过使用消息队列,可以异步处理请求,从而缓解系统的压力。在业务发展初期这些逻辑可能放在一起同步执行,随着业务订单量增长,需要提升系统服务的性能,这时候可以将一些不需要立即生效的操作拆分出来异步执行,比如发短信通知等,这种场景就可以使用消息队列MQ。本质还是通过异步来解决同步的系统压力,所以我们在做架构设计的时候有一个原则:能异步的就尽量不要同步。

2)答题: 一般的电商系统秒杀时会有一个答题流程,主要是为了增加购买的复杂度,首先可以防止一些机器参与秒杀的场景,起到防止作弊的目的。还可以拉大请求时间缓解请求,控制流量达到削峰的目的。这样请求经过一层层的漏斗过滤,会尽量将少的数据请求到后端了。
3)分层过滤: 针对于秒杀场景来说,跟本质的做法是过滤无效请求,分层过滤是采用漏斗方式进行请求处理的。 请求流程:

  • 大部分流量在用户浏览器或者cdn上获取,这一层可以拦截大量数据读取。
  • 前台读系统主要是一些缓存cache,比如采用nginx+lua等方式拦截无效请求。
  • 业务系统主要做好限流,排队等操作。对数据做合理分片。
  • 在最后的数据层做好数据强一致校验,比如保证库存的准确性(不能为负数)。
    在这里插入图片描述
3、服务熔断:

目的: 一般在微服架构中,有一个组件角色叫熔断器。顾名思义,熔断器起的作用就是在特定的场景下关掉当前的通路,从而起到保护整个系统的效果。在微服务架构中,一般我们的独立服务是比较多的,每个独立服务之间划分责任边界,并通过约定协议接口来进行通信。当我们的调用链路复杂依赖多时,很可能会发生雪崩效应。当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用。

4、服务降级:

目的: 服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的fallback(退路)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。
与熔断区别: 触发原因不同,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;

5、缓存加速和提前扩容

在HTTP请求的资源,请求可以分为静态请求和动态请求。

  • 静态请求:静态请求是指在不同请求中访问到的数据都相同的静态文件。例如:图片、视频、网站中的文件(html、css、js)、软件安装包、apk文件、压缩包文件等。
    CDN加速的本质是缓存加速,将您服务器上存储的静态内容缓存在CDN节点上,当您访问这些静态内容时,无需访问服务器源站,就近访问CDN节点即可获取相同内容,从而达到加速的效果,同时减轻服务器源站的压力。
  • 动态请求:动态请求是指在不同请求中访问到的数据不相同的动态内容。例如:网站中的文件(asp、jsp、php、perl、cgi)、API接口、数据库交互请求等。当客户端访问这些动态内容时,每次都需要访问用户的服务器,由服务器动态生成实时的数据并返回给客户端。因此CDN的缓存加速不适用于加速动态内容,CDN无法缓存实时变化的动态内容。对于动态内容请求,CDN节点只能转发回源站服务器,没有加速效果。
  • 全站加速:如果用户的网站或App应用有较多动态内容,例如需要对各种API接口进行加速,则需要使用全站加速。全站加速能同时加速动态和静态内容,加速方式如下:
    静态内容使用CDN加速。动态内容通过路由优化、传输优化等动态加速技术以最快的速度访问您的服务器源站获取数据。从而达到全站加速的效果。

实践方案:

从整个秒杀系统的架构其实和一般的互联网系统架构本身没有太多的不同,核心理念还是通过缓存、异步、限流来保证系统的高并发和高可用。下面从一笔秒杀交易的流程来描述下秒杀系统架构设计的要点:
高并发的处理:
1)对于大促时候的秒杀活动,一般运营会配置静态的活动页面,配置静态活动页面主要有两个目的一方面是为了便于在各种社交媒体分发,另一方面是因为秒杀活动页的流量是大促期间最大的,通过配置成静态页面可以将页面发布在公有云上动态的横向扩展;

2)将秒杀活动的静态页面提前刷新到CDN节点,通过CDN节点的页面缓存来缓解访问压力和公司网络带宽,CDN上缓存js、css和图片;

3)将活动H5页面部署在公有云的web server上,使用公有云最大的好处就是能够根据活动的火爆程度动态扩容而且成本较低,同时将访问压力隔离在公司系统外部;

4)在提供真正商品秒杀业务功能的app server上,需要进行交易限流、熔断控制,防止因为秒杀交易影响到其他正常服务的提供,我们在限流和熔断方面使用了hystrix,在核心交易的controller层通过hystrix进行交易并发限流控制,当交易流量超出我们设定的限流最大值时,会对新交易进行熔断处理固定返回静态失败报文。

5)服务降级处理,除了上面讲到的限流和熔断控制,我们还设定了降级开关,对于首页、购物车、订单查询、大数据等功能都会进行一定程度的服务降级,例如我们会对首页原先动态生成的大数据页面布局降级为所有人看到的是一样的页面、购物车也会降级为不在一级页面的tabbar上的购物车图标上显示商品数量、历史订单的查询也会提供时间周期较短的查询、大数据商品推荐也会提供一样的商品推荐,通过这样的降级处理能够很好的保证各个系统在大促期间能够正常的提供最基本的服务,保证用户能够正常下单完成付款。

超卖的处理:
我们日常的下单过程中防止超卖一般是通过在数据库上实施乐观锁来完成,使用乐观锁虽然比for update这种悲观锁方式性能要好很多,但是还是无法满足秒杀的上万并发需求,通过实时库存的扣减在缓存中进行,异步扣减数据库中的库存,保证缓存中和数据库中库存的最终一致性。秒杀本来就是读多写少,使用Redis集群,主从同步、读写分离或哨兵机制。

在这个方案中我们使用的分布式缓存是redis,使用了codis集群方案稳定性和高可用方面还是比较有保证的,因为redis是单线程写,所以也不用担心线程安全的问题,redis自身就能够保证数据的强一致性,在下单的事务中包含了实时扣减缓存中的库存和异步发送队列,由队列处理器再异步从队列中取出订单根据订单信息扣减库存系统数据库中的商品数量。

性能的处理:
1):水平扩容和nginx 负载均衡结合。
2):库存预热: 开始秒杀前你通过定时任务或者运维同学提前把商品的库存加载到Redis中去,让整个流程都在Redis里面去做,然后等秒杀介绍了,再异步的去修改库存就好了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

秒杀系统的设计和思考 的相关文章

  • 如何让Spring RabbitMQ创建一个新的队列?

    根据我对rabbit mq的 有限 经验 如果您为尚不存在的队列创建新的侦听器 则会自动创建该队列 我正在尝试将 Spring AMQP 项目与rabbit mq 一起使用来设置侦听器 但出现错误 这是我的 xml 配置
  • 如何在Java 8中实现Elvis运算符?

    我有一个经典的 Elvis 运算符 案例 其中我调用每个可能返回 null 的方法并将它们链接在一起 thing nullableMethod1 a nullableMethod2 b nullableMethod3 在 Java 8 中
  • 使用 AbstractTableModel 获取 JTable 中选定的行

    我有一个JTable using AbstractTableModel我在哪里有一个JCheckBox在第一列中用于选择行 现在 我需要从已检查的表中获取选定的行 现在 我按顺序从第一行遍历到最后一行并获取所有选择的行 如下所示 List
  • 实现与扩展:何时使用?有什么不同?

    请用易于理解的语言进行解释或提供某些文章的链接 extends is for 延伸一类 implements is for 实施一个接口 接口和常规类之间的区别在于 在接口中您不能实现任何声明的方法 只有 实现 接口的类才能实现方法 C 中
  • 如何测试调用父类的受保护(不需要的)方法的方法?

    我陷入了一个非常奇怪的情况 我有一些需要测试的特定代码 这里是 public class A The real method of real class is so big that I just don t want to test it
  • 使用除 SINGLE_TABLE 之外的任何其他 Hibernate 继承策略时 JVM 崩溃

    好吧 这可能不太可能 但还是这样吧 在Java JRE 1 6 0 26 b03 中我有两个类 SuperControl及其子类SubControl 它们都需要是持久对象 我正在使用 Hibernate Annotations 来实现这一点
  • 在 TestNG 中运行多个类

    我正在尝试自动化一个场景 其中我想登录一次应用程序 然后进行操作而无需再次重新登录 考虑一下 我有在特定类的 BeforeSuite 方法中登录应用程序的代码 public class TestNGClass1 public static
  • 要打乱的键值(整数、字符串)列表的最佳结构

    我需要在 Java 中实现一个结构 它是一个键值列表 类型为整数 字符串 并且我想对其进行洗牌 基本上 我想做类似的事情 public LinkedHashMap
  • 尝试在java中的Arraylist中查找对象的所有出现

    我有一个 Java ArrayList 我需要查找其中出现的所有特定对象 ArrayList indexOf Object 方法只找到一次出现 所以看来我还需要其他东西 我认为你不需要太花哨 以下应该可以正常工作 static
  • Java 唤醒休眠线程

    我阅读了其他帖子 但没有找到我正在寻找的确切答案 所以我希望有人能给出一些澄清 我有一个将运行一段时间的程序 我有一些在后台运行的线程来执行各种任务 为了简单起见 让我们考虑 3 个线程 ThreadA每 10 秒执行一次任务 其中Thre
  • 以编程方式设置 Logback Appender 路径

    我正在尝试以编程方式设置 Logback 附加程序路径 滚动文件附加器 http logback qos ch apidocs ch qos logback core rolling RollingFileAppender html准确地说
  • 从关卡堆栈中获取相对比例的数学

    为这个可怕的标题道歉 我花了 10 分钟试图用一句话来解释这一点 但失败了 虽然提示这个问题的应用程序是用Java Android 编写的 但我认为它非常通用并且适用于任何语言 欢迎使用伪代码 或简单的英语 回复 我不确定是否应该标记所有通
  • Java 泛型:如何为泛型类型指定类类型?

    我有一个 POJO 指定为 MyClass u where U是泛型类型参数 我正在尝试编写一个接受类引用的实用方法Class u
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 如何从 Google Custom Search API 获取超过 100 个结果

    我正在尝试使用 Google Custom Search API 在 Java 中进行研究 因此 我需要为每个查询提供一个大的结果集 然而 我似乎仅限于前 100 个结果 这比我需要的要少得多 我使用这样的列表方法 list setStar
  • 如何通过子 POJO 的属性过滤复合 ManyToMany POJO?

    我有两个像这样的房间实体 Entity public class Teacher implements Serializable PrimaryKey autoGenerate true public int id ColumnInfo n
  • 为什么现在()? (客观化)

    为什么我想要异步加载 Objectify 实体 异步加载到底意味着什么 根据客观化有关加载的文档 https code google com p objectify appengine wiki BasicOperations Loadin
  • 我们可以有虚假中断吗?

    我正在创建一个任务轮询器 每分钟都会查找任务 它看起来像这样 public class Poller private final ExecutorService e Executors newSingleThreadExecutor pub
  • scala中的协变类型参数需要在java接口中保持不变

    我有一个看起来像这样的特征 一些进一步的信息可以在我自己提出了这个相关问题 https stackoverflow com questions 3695990 inheritance and automatic type conversio
  • 编写自定义 Eclipse 调试器

    EDIT 一定有某种方法可以解决这个问题 而无需编写全新的调试器 我目前正在研究在现有 java 调试器之上构建的方法 如果有人对如何获取 Java 调试器已有的信息 有关堆栈帧 变量 原始数据等 有任何想法 那将非常有帮助 我想要做的是我

随机推荐

  • ctfshow-Misc入门 图片篇(1-49)

    八神出的misc入门系列 misc50及之后的题解 我这里很多题的解法是非预期 建议不懂的师傅去看八神师傅的出题思路及预期解 misc5 23 图片篇 图片篇 基础操作 misc1 misc2 misc3 misc4 图片篇 信息附加 mi
  • 机器学习之交叉验证汇总及其Python代码

    交叉验证是什么 在模型建立中 通常有两个数据集 训练集 train 和测试集 test 训练集用来训练模型 测试集是完全不参与训练的数据 仅仅用来观测测试效果的数据 一般情况下 训练的结果对于训练集的拟合程度通常还是挺好的 但是在测试集总的
  • UE4添加自定义配置文件信息

    创建一个UObject子类 将需要配置的变量实现在其中 UClass中的两个设置可以自己更改 变量宏需添加config pragma once include CoreMinimal h include UObject Object h i
  • 网站logo服务器更换显示以前,网站更换logo

    网站更换logo 内容精选 换一换 将unslider插件放入底板中 所有页面统一使用同一个底板 此时只要修改底板中unslider插件的图片 就能实现此效果 在站点编辑的 页面管理 中将首页复制为底板 复制为底板设置其他页面使用此底板 在
  • Data OnLine集合

    这里写自定义目录标题 目标 集合 目标 记录线上可用的数据集合 集合 中国诗词 诗词周历 古诗文网 另外一个诗词
  • Unity 屏幕自适应之锚点

    大家有没有这样的情况 自己在使用 Unity 制作 UI 界面时明明设计好了各个图标的大小 但是在实际运行时却出现了问题 原本场景里面是这样 最大化运行后是这样的 是不是不太好看 和自己当初设定的完全不一样 没事 小问题 那么我们该如何解决
  • 定制自己的printf函数——以stm32串口打印为例

    printf这个函数相信学习过编程的人应该都用过 这是一个用来向终端打印数据的函数 这个函数不仅在调试软件代码的时候经常有使用 单片机开发时也经常用于串口打印调试 所以 在此就如何让单片机使用printf来调试代码 开始接下来的学习 在此
  • .NET基础知识快速通关(8)

    NET 总结 Edison Zhou 此系列文章为我在2015年发布于博客园的 NET基础拾遗系列 它十分适合初中级 NET开发工程师在面试前进行一个系统的复习 因此我将其搬到公众号分享与你 本文为第八篇 我们会对 NET的委托相关考点进行
  • Mysql查询当天,本周,本月所有数据记录

    Mysql查询当天 本周 本月所有数据记录 一 查询当天的记录 select from create time where TO DAYS create time TO DAYS NOW 注意 这里的create time是数据库中的时间字
  • centos6安装python2.7

    下载python安装包 1 wget https www python org ftp python 2 7 12 Python 2 7 12 tgz 2 tar zxvf Pyhon 2 7 12 tgz 3 cd Python 2 7
  • 创建src目录

    在一个功能包里单独创建src目录可以先进入这个功能包 然后使用命令 mkdir src 然后使用命令 ls 发现功能包里有了src 还有一种就是在要创建的目录名前面加上路径名 则会在指定的路径名下创建的src 同时要确保这个路径下没有要创建
  • js 去除字符串首尾指定字符

    abc trim abc 这是去除首尾空格的办法 那么有没办法去除首尾指定的字符 肯定有 方法很多 下面通过正则表达式实现 例如 我想去掉首尾逗号 let str abc cde fff str str replace s s g 结果 a
  • ESP32S3学习——i2c,点亮0.96寸oled

    芯片 esp32s3 开发环境 espidfv4 4 一 官网相关资料 哎嘿嘿 中文的I2C 驱动程序 ESP32 S3 ESP IDF 编程指南 v4 4 2 文档 1 概述 ESP32 S3 有两个 I2C 控制器 也称为端口 负责处理
  • 使用CFimagehost源码搭建免费的PHP图片托管私人图床,无需数据库支持

    文章目录 1 前言 2 CFImagehost网站搭建 2 1 CFImagehost下载和安装 2 2 CFImagehost网页测试 2 3 cpolar的安装和注册 3 本地网页发布 3 1 Cpolar临时数据隧道 3 2 Cpol
  • 【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】驱动移植

    一 环境介绍 RK3588主板搭载Android12操作系统 内核是Linux5 10 使用ST的六轴传感器LSM6DSR芯片 二 芯片介绍 LSM6DSR是一款加速度和角速度 陀螺仪 六轴传感器 还内置了一个温度传感器 该芯片可以选择I2
  • SAP 账号人员信息

    视图USER ADDR 转载于 https www cnblogs com CtrlS p 10482779 html
  • Python中的网络通信

    概述 在我们平时生活工作中 常常会接触到网络通信的内容 不管你是普通的用户 还是通信行业内的开发人员 都无法避免与网络通信打交道 我在初步学习python的过程中 对python的网络通信问题做了总结 所以写下这篇文章作为记录 也希望能给其
  • JVM 内存分析工具 - MAT

    文章目录 1 简介 2 使用 2 1 准备 MAT 2 2 准备堆转储文件 Heap Dump 2 3 分析堆转储文件 2 3 1 Histogram 2 3 2 Leak Suspects 2 3 3 内存快照对比 MAT Memory
  • python span函数_如何使用python selenium单击span元素

    我不知道还有没有其他的元素 您可以使用css选择器选择范围 driver find element by css selector span click 我认为这是你代码中唯一的跨度标记 可能不是 作为一个非常 散弹枪 的解决方案 您可以单
  • 秒杀系统的设计和思考

    秒杀系统的难点 首先我们先看下秒杀场景的难点到底在哪 在秒杀场景中最大的问题在于容易产生大并发请求 产生超卖现象和性能问题 下面我们分别分析下下面这三个问题 1 瞬时大并发 一提到秒杀系统给人最深刻的印象是超大的瞬时并发 这时你可以联想到小