高可用系统架构总结

news2024/11/23 15:44:46

文章目录

  • 系统设计的一些原则
    • 海恩法则
    • 墨菲定律
  • 软件架构中的高可用设计
    • 什么是高可用
    • 故障的度量与考核
      • 解决高可用问题具体方案
    • 集群化部署
    • 负载均衡
      • 负载均衡实现
        • 内部服务
        • 外部服务
        • 数据库
      • 负载均衡算法
        • round-robin
        • ip_hash
        • hash key
      • 失败重试
      • 健康检查
        • TCP
        • HTTP
    • 隔离
      • 线程隔离
      • 进程隔离
      • 集群隔离
      • 机房隔离
      • 读写隔离
      • 动静隔离
      • 热点隔离
    • 限流
      • 限流算法
        • 漏桶算法
        • 令牌桶算法
      • nginx限流
        • ngx_http_limit_conn_module
        • ngx_http_limit_req_module
      • Tomcat限流
      • 接口限流
    • 降级
      • 降级预案
      • 页面降级
      • 页面片段降级
      • 页面异步请求降级
      • 服务功能降级
      • 读降级
      • 写降级
      • 自动降级
    • 熔断
  • 超时与重试
  • 压测与预案
    • 系统压测
      • 线下压测
      • 线上压测
    • 系统优化
    • 应急预案
  • 监控
    • 指标
    • 链路追踪
    • 日志
  • 参考文献

系统设计的一些原则

海恩法则

  • 事故的发生是量积累的结果
  • 再好的技术、在完美的规章,在实际操作层面也无法取代人自身的素质和责任心

墨菲定律

  • 任何事情都没有表面看起来那么简单
  • 所有事情的发展都会比你预计的时间长
  • 会出错的事总会出错
  • 如果你担心某种情况发生,那么它更有可能发生

软件架构中的高可用设计

什么是高可用

首先我们来了解下如何来定义一个系统可用,业界常用N个9来定义一个系统的可用情况。比如可用性为99.99%,这个99.99%就是代表的该系统在一年内可用的时间为99.99%。那么可用性为99.99%的系统不可用时间呢?一年有365天,一天有24小时,一小时有60分钟,一分钟有60秒,那么可用性为99.99%的系统一年内不可用时间大致为52.56分钟(3652460*(1-0.9999))。

高可用就是可用性指标大于等于4个9的系统。

在这里插入图片描述

故障的度量与考核

在这里插入图片描述

该评定标准一般会有SRE和各个业务方的技术负责人一起协商输出统一标准。对于出现各个等级的故障后都会进行总结,作为年底的技术输出。

解决高可用问题具体方案

  • 集群化部署
  • 负载均衡
  • 熔断
  • 限流
  • 降级
  • 隔离
  • 超时与重试
  • 回滚
  • 压测与预案

集群化部署

由于单点部署的话一旦服务挂了就直接不可用,所以需要采用集群部署,避免单点故障。

负载均衡

负载均衡实现

内部服务

保证服务集群可以进行故障转移。当服务宕机后,负载均衡进行转移,来达到高可用。对于内部调用的服务,通过RPC提供负载均衡。

外部服务

对于调用的外部服务,需要外部服务保障自身的高可用部署。同时调用方需要做重试(对于请求的节点不可用时切换其他节点)以及对第三方服务进行不可用、异常的监控。

数据库

对于服务内的数据库需保障高可用部署,以及采用的高可用方案的不适配问题,例如某些高可用方案在进行故障转移时会出现短暂不可用,这种情况也需要考虑进去。最后需要对数据库进行监控(异常、慢请求、CPU、磁盘、内存、线程池、IO)

负载均衡算法

round-robin

轮询,默认的负载均衡算法,以轮询的方式将请求转发到上游服务器,配合weight配置可以实现基于权重的轮询

ip_hash

根据客户IP进行负载均衡,享同的IP将负载均衡到同一个upstream server


upstream backend{
	ip_hash;
	server 192.168.1.101:8080 weight=1;
	server 192.168.1.102:8080 weight=2;
}

hash key

对某一个key进行哈希或者使用一致性哈希算法进行负载均衡。

Hash算法存在的问题是,若添加或者删除一台服务器的时候,会导致很多key被重新负载均衡到不同的服务器,而引起后端的问题。

若是使用一致性哈希算法,当添加/删除一台服务器时,只有少数key将被重新负载均衡到不同的服务器。

失败重试

upstream backend{
	server 192.168.1.101:8080 max_fails=2 fail_timeout=10s weight=1;
	server 192.168.1.102:8080 max_fails=2 fail_timeout=10s weight=2;
}

若是fail_timeout秒内失败了max_fails次,则认为上游服务器不可用|不存活,将摘掉上游服务器,fail_timeout秒之后会再次将服务器加入到存活列表进行重试。

健康检查

时刻关注服务的健康状态,若是服务不可用了,将会把请求转发到其他存活的服务上,以提高可用性。

Nginx可以集成nginx_upstream_check_module模块来进行主动健康检查。支持TCP心跳和HTTP心跳。

TCP


upstream backend{
	server 192.168.1.101:8080 weight=1;
	server 192.168.1.102:8080 weight=2;
	check interval=3000 rise=1 fall=3 timeout=2000 type=tcp;
}

  • interval: 检测间隔时间,此处配置了每隔3s检测一次。
  • fall: 检测失败多少次后,上游服务器被标识为不存活。
  • rise: 检测成功多少次后,上游服务器被标识为存活,并可以处理请求。

HTTP


upstream backend{
	server 192.168.1.101:8080 weight=1;
	server 192.168.1.102:8080 weight=2;
	check interval=3000 rise=1 fall=3 timeout=2000 type=tcp;
	check_http_send ”HEAD /status HTTP/1.0\r\n\r\n“
	check_http_expect_alive http_2xx http_3xx;
}

  • check_http_send: 即检查时发的HTTP请求内容。
  • check_http_expect_alive: 当上游服务器返回匹配的响应状态码时,则认为上游服务器存活。 请勿将检查时间设置过短,以防心跳检查包过多影响上游服

所以我们可以看到某些厂在自己的容器平台上会有 【健康检查】的功能就是根据nginx来做的改造。需要用户配置健康检查的path、频率、首次探测等待时间、每次探测超时时间、端口、探测失败阈值。

隔离

线程隔离

线程隔离指的是线程池隔离,一个请求出现问题不会影响到其他线程池。

进程隔离

把项目拆分成一个一个的子项目,互相物理隔离(部署在不同的机器上)。

集群隔离

将集群隔离开,使互相不影响。

机房隔离

分不同的机房进行部署,杭州机房;北京机房;上海机房,因为可能出现某机房网络问题,这样可以防止某机房出现网络问题导致整个系统无法使用。

读写隔离

互联网项目中大多是读多写少,读写分离,扩展读的能力,提高性能,提高可用性。常见的mysql读写分离就是这个原理。 但是在使用读写分离时还要考虑数据的延迟问题,事务失效问题。

动静隔离

将静态资源放入nginx,CDN,从而达到动静隔离,防止页面加载大量静态资源。

热点隔离

  • 将热点业务独立成系统或服务进行隔离,如秒杀,抢购。

  • 读热点一般使用多级缓存。同时需要考虑缓存与数据库一致性问题。

  • 写热点一般使用缓存加消息队列的方式。同时需要考虑数据延时问题是否会对业务有影响。

限流

限流主要是针对有突发流量的场景,如秒杀、抢购。若是不做限流,当突发大流量,服务可能会被冲垮。

限流算法

漏桶算法

漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。

令牌桶算法

令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

nginx限流

Nginx接入层限流可以使用Nginx自带的两个模块:

  • 连接数限流模块ngx_http_limit_conn_module

  • 漏桶算法实现的请求限流模块ngx_http_limit_req_module

ngx_http_limit_conn_module

针对某个key对应的总的网络连接数进行限流

可以按照IP来限制IP维度的总连接数,或者按照服务域名来限制某个域名的总连接数。


http{
	limit_conn_zone $binary_remote_addr zone=addr:10m;
	limit_conn_log_level error;
	limit_conn_status 503;
    ...
    server{
		location /limit{
			limit_conn addr 1;
		}
    }
    ...
}

  • limit_conn: 要配置存放key和计数器的共享内存区域和指定key的最大连接数。此处指定的最大连接数是1,表示Nginx最多同时并发处理1个连接。

  • limit_conn_zone: 用来配置限流key及存放key对应信息的共享内存区域大小。此处的key是binaryremoteaddr”,表示IP地址,也可以使用binary_remote_addr”,表示IP地址,也可以使用binaryr​emotea​ddr”,表示IP地址,也可以使用server_name作为key来限制域名级别的最大连接数。

  • limit_conn_status: 配置被限流后返回的状态码,默认返回503。

  • limit_conn_log_level: 配置记录被限流后的日志级别,默认error级别。

ngx_http_limit_req_module

漏桶算法实现,用于对指定key对应的请求进行限流,比如,按照IP维度限制请求速率。配置示例如下


limit_conn_log_level error;
limit_conn_status 503;
...
server{
	location /limit{
		limit_req zone=one burst=5 nodelay;
    }
}

  • limit_req: 配置限流区域、桶容量(突发容量,默认为0)、是否延迟模式(默认延迟)。

  • limit_req_zone: 配置限流key、存放key对应信息的共享内存区域大小、固定请求速率。此处指定的key是“$binary_remote_addr”,表示IP地址。固定请求速率使用rate参数配置,支持10r/s和60r/m,即每秒10个请求和每分钟60个请求。不过,最终都会转换为每秒的固定请求速率(10r/s为每100毫秒处理一个请求,60r/m为每1000毫秒处理一个请求)。

  • limit_conn_status: 配置被限流后返回的状态码,默认返回503。

  • limit_conn_log_level: 配置记录被限流后的日志级别,默认级别为error。

Tomcat限流

对于一个应用系统来说,一定会有极限并发/请求数,即总有一个TPS/QPS阈值,如果超了阈值,则系统就会不响应用户请求或响应得非常慢,因此我们最好进行过载保护,以防止大量请求涌入击垮系统。对于这些参数的配置需要经过压力测试后才能得出一个较好的数据,并且每次有重大功能上线时还需要再次压测看是否需要调整参数。这不是一件简单的事情。


<Connector port="8080" protocol="HTTP/1.1"
	connectionTimeout="20000"
	redirectPort="8443" maxThreads="800" maxConnections="2000" acceptCount="1000"/>

  • acceptCount:等待队列,如果Tomcat的线程都忙于响应,新来的连接会进入队列排队,如果超出排队大小,则拒绝连接;默认值为100

  • maxConnections:可以创建的瞬时最大连接数,超出的会排队等待;

  • maxThreads:Tomcat能启动用来处理请求的最大线程数,即同时处理的任务个数,默认值为200,如果请求处理量一直远远大于最大线程数,则会引起响应变慢甚至会僵死。

接口限流

接口的限流主要是针对些核心、QPS高的接口进行限流,限制某个接口的请求频率,以此来保护整个服务不被压垮。可以设置每个实例接口的QPS也可以设置所有实例总和的QPS。

降级

当访问量剧增、服务出现问题(如响应时间长或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的。

降级预案

在降级前需要对系统进行梳理,判断系统是否可以丢卒保帅,从而整理出哪些可以降级,哪些不能降级。

  • 一般: 比如,有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级。

  • 警告: 有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警。

  • 错误: 比如,可用率低于90%,或者数据库连接池用完了,或者访问量突然猛增到系统能承受的最大阈值,此时,可以根据情况自动降级或者人工降级。

  • 严重错误: 比如,因为特殊原因数据出现错误,此时,需要紧急人工降级。

降级按照是否自动化可分为:自动开关降级和人工开关降级。
降级按照功能可分为:读服务降级和写服务降级。
降级按照处于的系统层次可分为:多级降级。

降级的功能点主要从服务器端链路考虑,即根据用户访问的服务调用链路来梳理哪里需要降级。

页面降级

在大型促销或者抢购活动时,某些页面占用了一些稀缺服务资源,在紧急情况下可以对其整个降级。

页面片段降级

比如,商品详情页中的商家部分因为数据错误,此时,需要对其进行降级。

页面异步请求降级

比如,商品详情页上有推荐信息/配送至等异步加载的请求,如果这些信息响应慢或者后端服务有问题,则可以进行降级。

服务功能降级

比如,渲染商品详情页时,需要调用一些不太重要的服务(相关分类、热销榜等),而这些服务在异常情况下直接不获取,即降级即可。

读降级

比如,多级缓存模式,如果后端服务有问题,则可以降级为只读缓存,这种方式适用于对读一致性要求不高的场景。

写降级

比如,秒杀抢购,我们可以只进行Cache的更新,然后异步扣减库存到DB,保证最终一致性即可,此时可以将DB降级为Cache。

自动降级

当服务中错误出现次数到达阀值(99.99%),对服务进行降级,发出警告。

熔断

熔断机制也是很重要的。 熔断机制说的是系统自动收集所依赖服务的资源使用情况和性能指标,当所依赖的服务不可用或者调用失败次数达到某个阈值的时候就迅速失败,让当前系统立即切换依赖其他备用服务。 比较常用的是流量控制和熔断降级框架是 Netflix 的 Hystrix 和 alibaba 的 Sentinel。

超时与重试

一旦用户请求超过某个时间的得不到响应,就抛出异常。这个是非常重要的,很多线上系统故障都是因为没有进行超时设置或者超时设置的方式不对导致的。我们在读取第三方服务的时候,尤其适合设置超时和重试机制。如果不进行超时设置可能会导致请求响应速度慢,甚至导致请求堆积进而让系统无法在处理请求。重试的次数一般设为 3 次,再多次的重试没有好处,反而会加重服务器压力(部分场景使用失败重试机制会不太适合,因为可能产生重复请求,而服务端又没做幂等处理就会产生脏数据)。常见的重试如下:

  • 代理层超时与重试: nginx

  • web容器超时与重试

  • 中间件|服务间超时与重试

  • 数据库连接超时与重试

  • nosql超时与重试

  • 业务超时与重试

  • 前端浏览器ajax请求超时与重试

压测与预案

系统压测

压测一般指性能压力测试,用来评估系统的稳定性和性能,通过压测数据进行系统容量评估,从而决定是否需要进行扩容或缩容。

线下压测

通过如JMeter、Apache ab压测系统的某个接口(如查询库存接口)或者某个组件(如数据库连接池),然后进行调优(如调整JVM参数、优化代码),实现单个接口或组件的性能最优。

线下压测的环境(比如,服务器、网络、数据量等)和线上的完全不一样,仿真度不高,很难进行全链路压测,适合组件级的压测,数据只能作为参考。

线上压测

线上压测的方式非常多,按读写分为读压测、写压测和混合压测按数据仿真度分为仿真压测和引流压测按是否给用户提供服务分为隔离集群压测和线上集群压测

读压测是压测系统的读流量,比如,压测商品价格服务。写压测是压测系统的写流量,比如下单。写压测时,要注意把压测写的数据和真实数据分离,在压测完成后,删除压测数据。只进行读或写压测有时是不能发现系统瓶颈的,因为有时读和写是会相互影响的,因此,这种情况下要进行混合压测。

仿真压测是通过模拟请求进行系统压测,模拟请求的数据可以是使用程序构造、人工构造(如提前准备一些用户和商品),或者使用Nginx访问日志,如果压测的数据量有限,则会形成请求热点。而更好的方式可以考虑引流压测,比如使用TCPCopy复制;也可以考虑使用流量拷贝来拷贝线上流量,然后测试环境构造出和线上一样的环境(硬件、数据、示例等),最后将拷贝的流量来对测试环境进行压测,这是个很复杂的事,需要单独的压测平台来支持。

系统优化

拿到压测报告后,接下来会分析报告,然后进行一些有针对性的优化,如硬件升级、系统扩容、参数调优、代码优化(如代码同步改异步)、架构优化(如加缓存、读写分离、历史数据归档)等。

不要直接复用别人的案列,一定要根据压测结果合理调整自己的案例。

在进行系统优化时,要进行代码走查,发现不合理的参数配置,如超时时间、降级策略、缓存时间等。在系统压测中进行慢查询排查,包括Redis、MySQL等,通过优化查询解决慢查询问题。

在应用系统扩容方面,可以根据去年流量、与运营业务方沟通促销力度、最近一段时间的流量来评估出是否需要进行扩容,需要扩容多少倍,比如,预计GMV增长100%,那么可以考虑扩容2~3倍容量。

应急预案

在系统压测之后会发现一些系统瓶颈,在系统优化之后会提升系统吞吐量并降低响应时间,容灾之后的系统可用性得以保障,但还是会存在一些风险,如网络抖动、某台机器负载过高、某个服务变慢、数据库Load值过高等,为了防止因为这些问题而出现系统雪崩,需要针对这些情况制定应急预案,从而在出现突发情况时,有相应的措施来解决掉这些问题。

应急预案可按照如下几步进行:首先进行系统分级,然后进行全链路分析、配置监控报警,最后制定应急预案。

监控

首先这部分不属于高可用系统架构的部分,它应该是监控体系的一部分,而之所以放在这里主要还是因为软件的生命周期中维护的时间更长,所以在系统前期的架构设计中还是要考虑开发、维护中的监控。同时这里对于监控不会介绍很多,只会基于监控的三大数据进行简单概括。

从上面的步骤我们知道如果没有监控,那么系统维护人员面对系统就像个瞎子一样,不知道系统的情况。即使前期做了再完备的设计、开发人员的技术水平多高,但是在软件的维护过程中依然会存在问题 。所以详细、全面、合理的监控是必不可少的。它可以帮助维护人员知道异常的出现,可以帮助维护人员知道系统的变化。一个全面、完善的监控体系是业务保障的关键。

没有什么系统的一步到位的,所以更加需要有监控来帮助系统完善自身的问题。

指标

我们需要对系统的业务、性能进行指标暴露、采集、监控。我们可以根据指标变化分析出系统某个东西的变化情况,同时可以根据指标值发出告警。

指标大体可以分为容器(tomcat)、中间件、数据库、http、池(数据库连接池、http连接池)等,每项指标又可以有QPS、响应时间、异常率、慢请求率等。这些都是些基础的指标数据,在系统的不断维护、迭代中会增加更多的指标数据以及报表展示。这是一个不断优化的过程。

链路追踪

链路追踪主要用来分析一个执行过程的耗时以及具体性能问题出现在哪个地方。同时链路ID(这块需要链路追踪系统进行改造兼容)也可以作为串联日志的中间层来把日志和链路进行串联。由于链路的数据非常的完整,所以链路数据是非常有价值的数据,可以进行链路分析来帮助业务更加轻松的维护系统。

日志

日志作为开发人员常用的排查问题数据存在一个非常难受的点就是无法将一个执行的全部日志一次性查出来,所以可以在日志中添加traceId来把日志数据进行串联。好的、完善的日志是排查问题的关键。所以日志的重构存在于软件维护的整个过程。日志的级别设置非常关键,因为我们经常会对日志进行分析,将error级别的日志进行告警通知相应服务的维护人员。

参考文献

高可用设计原则

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

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

相关文章

华秋观察 | 通讯产品 PCB 面临的挑战,一文告诉你

印制电路板是电子产品的关键电子互联件&#xff0c;被誉为“电子产品之母”。随着电子产品相关技术应用更快发展、迭代、融合&#xff0c;PCB作为承载电子元器件并连接电路的桥梁&#xff0c;为满足电子信息领域的新技术、新应用的需求&#xff0c;行业将迎来巨大的挑战和发展机…

rocky9脚本py格式

在linux7上编写/root/CreateFile.py的python3脚本&#xff0c;创建20个文件/root/test/File01至/root/test/File20&#xff0c;如果文件存在&#xff0c;则先删除再创建&#xff1b;每个文件的内容同文件名&#xff0c;如File01文件的内容为”File01” 先在root目录下建立所需…

使用单片机遇到的几个问题及解决方案1

1.为什么我跟着视频学习的过程中&#xff0c;我没有找到“端口"的选项呢&#xff1f;我甚至没有出现“其他插口”。 想要找到设备管理器最快的方法就是&#xff1a; 首先如果把输入法调为大写形式&#xff0c;然后按下“WINX”&#xff0c;再按“M”就会出现一个设备管理…

python制作炸弹人游戏,一起来爆破消灭敌人吧

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 《炸弹人》是HUDSON出品的一款ACT类型游戏&#xff0c;经典的第一作登陆在FC版本&#xff0c;游戏于1983年发行。 游戏具体操作是一个机器人放置炸弹来炸死敌人&#xff0c;但也可以炸死自己&#xff0c;还有些增强威力…

K8S之服务Service(十三)

1、Service概念&#xff1a; Kubernetes中的 Pod是有生命周期的&#xff0c;它们可以被创建&#xff0c;也可以被销毁&#xff0c;然而一旦被销毁pod生命就永远结束&#xff0c;这个pod就不存在了&#xff0c;通过ReplicaSets能够动态地创建和销毁Pod&#xff08;例如&#xff…

【计算思维题】少儿编程 蓝桥杯青少组计算思维 数学逻辑思维真题详细解析第8套

少儿编程 蓝桥杯青少组计算思维题真题及解析第8套 1、下列哪个选项填到填到下图空缺处最合适 A、 B、 C、 D、 答案:D 考点分析:主要考查小朋友们的观察能力,从给定的图中可以看到,图中的线条都是有实现和虚

【C++ 学习 ⑨】- 万字详解 string 类(上)

目录 一、为什么学习 string 类&#xff1f; 二、标准库中的 string 类 三、C STL容器是什么&#xff1f; 四、string 类的成员函数 4.1 - 构造函数 4.2 - 赋值运算符重载 4.3 - 容量操作 4.4 - 遍历及访问操作 4.4.1 - operator[] 和 at 4.4.2 - 迭代器 4.5 - 修改…

Node.js 使用踩坑

重装电脑后&#xff0c;重装node.js 出现一个问题&#xff1a; npm install 会报错 按提示操作后 而npm run serve 会报xlsx和echart的错误&#xff0c;提示引用不对之类的&#xff0c;但是公司项目固定的&#xff0c;不可以随便改&#xff0c;而且之前是没问题的。 此时需要找…

华为OD机试真题B卷 Java 实现【数组拼接】,附详细解题思路

一、题目描述 现在有多组整数数组&#xff0c;需要将它们合并成一个新的数组。 合并规则&#xff0c;从每个数组里按顺序取出固定长度的内容合并到新的数组中&#xff0c;取完的内容会删除掉&#xff0c;如果该行不足固定长度或者已经为空&#xff0c;则直接取出剩余部分的内…

Anaconda教程,Python版本控制

Anaconda教程,Python版本控制 文章目录 Anaconda教程,Python版本控制1&#xff1a;Anaconda安装1.1&#xff1a;Windows1.2&#xff1a;Linux1.3&#xff1a;MacOS 2&#xff1a;Anaconda使用2.1&#xff1a;创建一个新的环境2.2&#xff1a;安装 Python 包2.3&#xff1a;激活…

hash模式下路由跳转页面不刷新

mode为hash时&#xff0c;纯粹页面&#xff0c;路由跳转过之后跳转上一级重复路由页面不会重新渲染 举个例子&#xff1a;当我在注册页面->注册状态页面->注册页面&#xff0c;在这个期间我从注册状态页面进行缓存的数据想要在注册页面使用&#xff0c;然而注册页面不会…

【YOLO系列】YOLO v5(网络结构图+代码)

文章目录 推理转换onnx网络架构SPP VS SPPFAutoAnchorLoss 参考 【YOLO系列】YOLO v3&#xff08;网络结构图代码&#xff09; 【YOLO 系列】YOLO v4-v5先验知识 【YOLO系列】YOLO v4&#xff08;网络结构图代码&#xff09; 我是在自己笔记本上配置的YOLO v5环境。首先&#x…

饼状图使用属性时,使用驼峰命名法

饼状图是使用D3.js等JavaScript库来绘制的&#xff0c;而JavaScript中的属性名通常采用驼峰式命名法&#xff0c;即第一个单词的首字母小写&#xff0c;后面单词的首字母大写&#xff0c;例如fontSize、fontWeight等。而CSS中的属性名采用连字符命名法&#xff0c;即单词之间用…

Top 5 Best Open Source Projects on GitHub 2023

这里介绍Github上 5 个增长最快的开源项目&#xff0c;它们为原有的解决方案提供了更加具有成本效益的替代方案&#xff0c;并为开发者、数据分析师和企业提供了高可用的工具产品。利用开源的优势&#xff0c;这5个项目拓展了强大而有效的解决方案&#xff0c;是值得收藏、分享…

比ureport好用的报表系统-VeryReport报表系统

随着数据时代的到来&#xff0c;数据成为企业管理和决策的重要依据。然而&#xff0c;在处理海量数据的同时&#xff0c;如何快速准确地生成各种形式的报表却成为了一个痛点。手工制作报表费时费力、容易出错&#xff1b;而传统的报表工具又复杂难用&#xff0c;无法满足不同用…

基于jsp+mysql+Spring+mybatis+Springboot的SpringBoot婚纱影楼摄影预约网站

运行环境: 最好是java jdk 1.8&#xff0c;我在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以&#xff0c;如果编译器的版本太低&#xff0c;需要升级下编译器&#xff0c;不要弄太低的版本 tomcat服务器环…

Linux下快速创建大文件的4种方法总结

1、使用 dd 命令创建大文件 dd 命令用于复制和转换文件&#xff0c;它最常见的用途是创建实时 Linux USB。dd 命令是实际写入硬盘&#xff0c;文件产生的速度取决于硬盘的读写速度&#xff0c;根据文件的大小&#xff0c;该命令将需要一些时间才能完成。 假设我们要创建一个名…

SAP从入门到放弃系列之CRP-part2

标准的生产处理流程如下&#xff1a; 在标准的流程里&#xff0c;MRP为无限产能方式&#xff0c;所以在MRP或者MPS之后&#xff0c;需要进行CRP计算&#xff0c;然后调整。 测试数据准备&#xff1a; 1、参考复制part1文章中的ZW01CRP工作中心复制到新的ZW01CRP2。 2、为物…

springboot 连接 kafka集群(kafka版本 2.13-3.4.0)

springboot 连接 kafka集群 一、环境搭建1.1 springboot 环境1.2 kafka 依赖 二、 kafka 配置类2.1 发布者2.1.1 配置2.1.2 构建发布者类2.1.3 发布消息 2.2 消费者2.2.1 配置2.2.2 构建消费者类2.2.3 进行消息消费 一、环境搭建 1.1 springboot 环境 JDK 11 Maven 3.8.x spr…

SpringCloud Alibaba Nacos--下

SpringCloud Alibaba Nacos-下 Nacos 配置中心实例 示意图 在Nacos Server 加入配置 进入到Nacos Server加入配置&#xff0c; 特别提醒: 文件后缀.yaml 别忘了. Data ID: e-commerce-nacos-config-client-dev.yaml 创建Nacos 配置客户端模块e-commerce-nacos-config-client…