spring boot项目一次性能测试的总结
满足标准:并发大于等于100 ,平均响应时间小于等于3秒
项目在压测过程中并发数只有50,在并发数100的情况下有很多请求链接是失败的
我们该如何入手去处理这些问题并提高并发数呢?
1、首先从压测结果入手,对不满足标准的链接url进行单独压测,并在100并发数的条件下,查看聚合报告显示的当前压测链接的平均响应时间和错误率,并将结果输出本地中以查看有多少链接出现错误,出现的错误是什么,比如:403、401或500 等。
2、拿出日志,并根据具体报错信息,优化你的代码。
基本上到这一步,所有的问题一般都能解决了。
在本次压测中,大部分失败的请求都是500错误,同时错误主要集中在微服务之间的调用逻辑上,还有一部分是代码响应超时上。在并发量较高的情况下,就会出现处理失败的请求。
本次压测出现问题的原因
1、并发较高的情况下,使用shiro获取上下文中的用户信息时有时为空,这时就会导致错误链接,后台会报空指针异常
原因分析:在访问接口时,需要做登录认证,认证时,需要将用户信息存至上下文,存上下文时会负载均衡调用远程feign接口,导致调用失败,熔断。
这种情况目前处理方案
代码中做非空校验,让其返回200。并不能在压测链接中添加响应断言条件。这种是治标不治本,归其原因还是shiro的上下文信息无法处理高并发请求导致获取不到用户信息,导致压测时错误率升高。
2、并发较高的情况下,openfeign产生了服务降级
准确的说是 openfeign整和了ribbon 和hixtry 而 openfeign启用了hixtry后 并添加了fallback 注解,从而出现在服务端超时或报错的情况下出现了服务降级的情况。
深入剖析一下 openfeign中的服务降级和hixtry中的服务降级 有什么区别与联系?
- openfeign是一个声明式的服务调用客户端,它可以通过注解的方式来调用其他微服务的接口.hixtry是一个用于实现熔断器模式的库,它可以在服务出现故障时,提供一个备用的响应,从而避免级联失败.
- openfeign和hixtry可以结合使用,实现服务调用的容错和熔断。openfeign可以通过配置feign.hystrix.enabled=true来启用hixtry的支持然后可以在FeignClient注解中指定fallback或fallbackFactory属性,来定义当远程调用失败或超时时,应该使用哪个类来处理请求的回退逻辑。
- openfeign中的服务降级和hixtry中的服务降级的区别在于,openfeign中的服务降级是针对客户端的,即当客户端调用服务端失败或超时时,客户端会执行fallback类中的方法来返回一个默认的结果。而hixtry中的服务降级是针对服务端的,即当服务端出现异常或错误时,服务端会执行@HystrixCommand注解中指定的fallbackMethod来返回一个默认的结果。
- openfeign中的服务降级和hixtry中的服务降级的联系在于,它们都是基于hixtry的熔断机制来实现的,即当某个服务在一定时间内达到一定次数的失败率时,会触发熔断器打开,从而拒绝请求,并执行回退逻辑。它们都可以通过配置文件或注解来设置熔断器的相关参数,如超时时间、错误阈值、恢复时间等。
查看日志报错:
2023-09-05 18:36:07.219 [http-nio-0.0.0.0-8982-exec-34] ERROR c.e.p.cloud.base.exception.GlobalExceptionHandler - could not acquire a semaphore for execution com.netflix.hystrix.exception.HystrixRuntimeException: BaseUserRemote#updateSysUser(SysUser) could not acquire a semaphore for execution and no fallback available.
2023-09-05 18:36:07.219 [http-nio-0.0.0.0-8982-exec-34] 错误 c.e.p.cloud.base.exception.GlobalExceptionHandler - 无法获取用于执行的信号量 com.netflix.hystrix.exception.HystrixRuntimeException:BaseUserRemote#updateSysUser(SysUser) 无法获取用于执行的信号量,并且没有可用的后备。
来分析一下错误的原因:
这个异常信息表示您的程序在调用 BaseUserRemote#updateSysUser(SysUser) 方法时无法获取一个信号量(semaphore)。信号量是一种计数器,用来控制同时访问某个特定资源的操作数量。 如果信号量的值为 0,那么没有许可可用,请求获取信号量的线程会被阻塞,直到有其他线程释放信号量。
出现这个异常的可能原因有以下几种:
- 您的程序设置了信号量的初始值过小,导致可用的许可不足以满足并发请求的需求。 这种情况下,您可以检查您的程序中创建信号量的代码,看是否有相关的设置,并根据实际需求进行调整。
- 您的程序在获取信号量后没有正确地释放信号量,导致信号量被占用,无法被其他线程获取。 这种情况下,您可以检查您的程序中使用信号量的代码,看是否有正确地调用 release() 方法,并使用 try-finally 语句来保证释放操作的执行。
- 您的程序在获取信号量时没有设置超时时间,导致线程一直等待信号量,无法继续执行。 这种情况下,您可以检查您的程序中使用信号量的代码,看是否有正确地调用 tryAcquire() 方法,并设置合理的超时时间和时间单位。
hystrix为每个依赖提供一个小的线程池(或信号量),如果线程池已满调用将被立即拒绝,加速失败判定时间。hystrix还提供了两种隔离策略,分别是THREAD和SEMAPHORE。THREAD模式下,每个请求在单独的线程上执行,并受到线程池大小的限制;SEMAPHORE模式下,每个请求在调用线程上执行,并受到信号量计数的限制。隔离策略可以通过execution.isolation.strategy参数来设置,默认值是THREAD。
hixtry和ribbon的超时时间设置对压测时总是熔断有什么影响,主要取决于以下几个因素:
- 压测的流量和响应时间,如果压测的流量过大或者响应时间过长,可能导致请求堆积或者超时,触发熔断器的阈值,从而拒绝后续的请求
- hixtry和ribbon的隔离策略,hixtry有两种隔离策略,分别是THREAD和SEMAPHORE。THREAD模式下,每个请求在单独的线程上执行,并受到线程池大小的限制;SEMAPHORE模式下,每个请求在调用线程上执行,并受到信号量计数的限制。不同的隔离策略对压测的性能和稳定性有不同的影响。
- hixtry和ribbon的超时时间设置,hixtry和ribbon都有自己的超时时间设置,分别控制执行命令、执行fallback、建立连接、读取数据等方面的超时时间。不同的超时时间设置对压测的成功率和失败率有不同的影响。
- hixtry和ribbon的重试机制,hixtry和ribbon都有自己的重试机制,分别控制是否对所有操作都重试、对同一个服务器或者下一个服务器的最大重试次数等方面的重试策略。不同的重试机制对压测的效率和效果有不同的影响
一般来说,要避免压测时总是熔断,需要根据实际情况合理地设置hixtry和ribbon的超时时间,保证在压测流量范围内,请求能够及时得到响应或者降级处理,不会因为等待过久或者失败过多而触发熔断器打开
# 设置实例HystrixCommandKey的此属性值,使用信号量策略
hystrix.command.HystrixCommandKey.execution.isolation.strategy=SEMAPHORE
# 设置 Hystrix 信号量隔离策略的最大并发请求数
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=100
# 设置 Hystrix 信号量隔离策略的最大并发回退请求数
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=50
# 设置 Hystrix 熔断器开关,true 表示开启熔断器
hystrix.command.default.circuitBreaker.enabled=true
# 设置 Hystrix 熔断器的请求阈值,即在一个统计窗口内最少请求数
hystrix.command.default.circuitBreaker.requestVolumeThreshold=20
# 设置 Hystrix 熔断器的错误率阈值,即触发熔断的错误百分比
hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
# 设置 Hystrix 熔断器的休眠时间窗,即熔断后多久尝试恢复,默认为 5 秒
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=5000
高并发一下如何设置 hixtry 和 ribbon的超时时间?
-
一般来说,hixtry的超时时间包括以下几个方面:
- execution.isolation.thread.timeoutInMilliseconds:执行命令的超时时间,单位为毫秒,默认为1000
- execution.timeout.enabled:是否启用执行超时,默认为true
- fallback.isolation.thread.timeoutInMilliseconds:执行fallback的超时时间,单位为毫秒,默认为1000
- fallback.enabled:是否启用fallback,默认为true
-
一般来说,ribbon的超时时间包括以下几个方面:
- ribbon.ConnectTimeout:建立连接的超时时间,单位为毫秒,默认为1000
- ribbon.ReadTimeout:读取数据的超时时间,单位为毫秒,默认为5000
- ribbon.OkToRetryOnAllOperations:是否对所有操作都重试,默认为false
- ribbon.MaxAutoRetries:对同一个服务器的最大重试次数,默认为0
- ribbon.MaxAutoRetriesNextServer:切换到下一个服务器的最大重试次数,默认为1
-
hixtry还有一个fallback机制,当请求失败或者被拒绝时,可以执行一个备选方案,返回一个默认值或者友好提示。fallback也需要一定的资源来执行,所以hixtry也对fallback的并发请求数做了限制
-
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests是一个配置参数,它表示每个命令允许的最大并发请求数。如果超过这个数目,请求将被拒绝,并触发降级逻辑
-
当你使用100并发进行压测时,可能有以下几种情况:
- 如果你使用的是THREAD模式,并且线程池大小小于100,那么一部分请求会被线程池拒绝,并触发fallback。如果fallback的并发请求数超过了hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests的值(默认为10),那么一部分fallback也会被信号量拒绝,并报信号量阻塞的错误
- 如果你使用的是SEMAPHORE模式,并且hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests的值小于100(默认为10),那么一部分请求会被信号量拒绝,并触发fallback。如果fallback的并发请求数也超过了hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests的值(默认为10),那么一部分fallback也会被信号量拒绝,并报信号量阻塞的错误
- 如果你使用的是任何一种模式,并且请求的失败率超过了hystrix.command.default.circuitBreaker.errorThresholdPercentage的值(默认为50%),那么熔断器会打开,后续的请求都会直接被拒绝,并触发fallback。如果fallback的并发请求数超过了hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests的值(默认为10),那么一部分fallback也会被信号量拒绝,并报信号量阻塞的错误
-
当你设置了hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=100时,就相当于把fallback的并发请求数限制放宽了,让所有的fallback都能执行成功,不会报信号量阻塞的错误](about:blank#)12。但这并不意味着你解决了压测中出现的问题,只是把错误从信号量阻塞转移到了其他地方(如线程池拒绝、熔断器打开等)](about:blank#)12。
根据上述分析,我们解决此问题 从两点出发:1、设置hixtry 的超时时间 2、设置ribbon的超时时间 3、设置fallback的数量
实际场景分析:
当在进行压测时,发生了60个请求连接失败并触发了服务降级,这可能是由于服务端在高并发情况下无法处理这些请求而导致的。服务降级是为了保护服务端的稳定运行而进行的一种策略,当服务端无法及时响应请求或出现错误时,Hystrix会触发服务降级来保护服务端资源不过载。这样会导致某些请求被降级,返回默认响应。
要解决这种情况,首先需要确认为什么这60个请求触发了服务降级,而其他请求并没有报错或被降级。可能的原因包括:
-
服务端资源限制:服务端可能存在资源限制,如线程池容量不足、内存限制或者数据库连接池不够。你可以检查服务端的资源配置,并根据实际情况进行调整和优化。
-
请求过于频繁:这60个请求可能在短时间内同时发起,导致高并发情况下服务端无法处理这些请求。你可以考虑限制或调整客户端请求的频率,以免过多的请求同时到达服务端。
在OpenFeign和Hystrix的配置方面,你可以采取一些措施来改善这个问题:
-
调整线程池配置:在Hystrix的配置中,你可以增加线程池的核心线程数、最大线程数等参数来提高服务端的并发处理能力。
-
调整Hystrix的超时时间:可根据实际情况适当调整Hystrix的超时时间,避免过长的等待时间导致服务降级。
-
优化服务端性能:通过代码优化、缓存技术等方式提高服务端的性能和并发处理能力,以应对高并发请求。
-
使用负载均衡:使用负载均衡器对请求进行分流,将请求均匀分配到多个服务实例上,分散负载压力。
需要注意的是,在进行配置调整之前,一定要通过监控和分析来了解系统的瓶颈和性能状况,并找到具体的问题所在。同时,也可以适用开源性能测试工具,如JMeter、Gatling等进行压力测试,用于定位问题和验证配置的效果。
综上所述,通过优化服务端资源和配置OpenFeign和Hystrix的相关参数,可以增加系统的并发处理能力,减少触发服务降级的情况。但并发测试需要综合考虑系统的硬件资源和业务逻辑,建议结合具体场景来进行调整和优化。
在高并发情况下,Hystrix发生服务降级的条件包括:
- 请求超时:配置的超时时间内未收到响应。
- 请求阈值和错误比例:请求的数量超过阈值,并且错误的比例超过配置的阈值。
- 熔断器打开状态:当熔断器处于打开状态时,所有请求都将被熔断。
这些条件可以通过配置Hystrix的参数来控制。使用OpenFeign集成Hystrix时,可以通过在Feign客户端接口的方法上添加@HystrixCommand注解来设置相关参数。
为了满足100个并发数并避免服务降级的情况,你可以根据以下几个方面进行配置:
-
超时时间:适当增加超时时间,确保服务端有足够的时间进行处理,并保证请求在指定超时时间内得到响应。可以在@HystrixCommand注解的commandProperties属性中设置
execution.isolation.thread.timeoutInMilliseconds
参数。 -
请求阈值和错误比例:根据实际情况,调整请求阈值和错误比例的参数,使得请求超过阈值和错误比例的发生概率较低。可以在@HystrixCommand注解的commandProperties属性中设置
circuitBreaker.requestVolumeThreshold
和circuitBreaker.errorThresholdPercentage
参数。 -
熔断时间:调整熔断器的关闭时间,确保熔断器在一段时间后能够逐渐关闭,允许部分请求通过。可以在@HystrixCommand注解的commandProperties属性中设置
circuitBreaker.sleepWindowInMilliseconds
参数。
需要注意的是,并发数受到多个因素的影响,包括服务端的资源和处理能力、网络传输速度等。当高并发情况下,确保系统的可用性和性能需要综合考虑各个环节的优化。除了Hystrix的参数配置,还可以采取负载均衡、集群部署、合理设计数据库访问、缓存策略等措施来提升系统的并发处理能力。
最重要的是根据具体的业务场景进行测试和调优,逐步优化系统的性能和可用性,以满足高并发场景下的需求。
熔断策略的本质
-
熔断并不是服务报错,而是一种主动的保护机制,用于避免服务因为故障或者延迟而造成的雪崩效应]。雪崩效应是指当一个服务不可用或者响应缓慢时,会导致调用方的资源耗尽,从而影响其他服务的正常运行,最终导致整个系统崩溃。
-
熔断的原理是通过监控服务的调用情况,当发现服务出现异常或者超时的比例或次数达到一定的阈值时,就会触发熔断器打开,切断对该服务的调用,并返回一个默认的结果或者提示信息 。这样可以保证调用方不会因为等待故障服务而浪费资源,也可以减轻故障服务的压力,让其有机会恢复正常 。
-
熔断的优势是可以提高系统的可用性和稳定性,因为它可以防止故障服务影响整个系统的运行,也可以让故障服务快速恢复 。熔断并不会影响高并发的需求,反而可以让系统在高并发下更加健壮和鲁棒 。
-
服务降级是指当服务不可用或者响应缓慢时,为了保证系统的可用性和稳定性,采取一些措施来减少服务的质量或者功能,从而避免系统崩溃或者雪崩效应。
-
熔断的目的是为了保护系统在高并发下不至于崩溃,而不是为了满足所有用户的数据需求。当系统的处理能力达到极限时,必须采取一些措施来减少负载,否则会导致系统无法正常运行,甚至崩溃 。
-
熔断的策略是根据服务的重要性和可用性来制定的,一般来说,对于核心业务和关键服务,不会轻易触发熔断,而对于非核心业务和次要服务,可以适当降低服务质量,或者提供一些默认的结果或提示信息 。
-
熔断的效果是让系统在高并发下更加稳定和可靠,因为它可以防止故障服务影响其他正常服务,并且可以让故障服务快速恢复。虽然熔断会让部分用户无法获取到他们想要的数据,但这是一种权衡和妥协的结果,相比于让整个系统崩溃,熔断是一种更好的选择 。
-
对于那些降级的服务,会给用户返回一些默认的结果或者提示信息,以便让用户知道服务目前的状态,不再继续等待或者重试.具体的返回内容取决于服务的类型和业务场景,一般有以下几种方式:
- 返回空值或者null,表示服务没有返回任何数据。
- 返回缓存数据或者静态数据,表示服务返回了一些过期或者固定的数据。
- 返回友好的错误提示或者异常信息,表示服务出现了故障或者异常。
- 返回降级页面或者功能,表示服务只提供了部分或者简化的页面或功能。
-
举例说明:
- 如果一个电商网站的商品详情页出现了延迟或者故障,可以给用户返回一个空白页或者一个提示“商品信息暂时无法显示,请稍后再试”的页面。
- 如果一个新闻网站的最新新闻列表出现了延迟或者故障,可以给用户返回一些缓存的新闻列表或者一些静态的新闻列表
- 如果一个社交网站的用户评论功能出现了延迟或者故障,可以给用户返回一个错误提示或者一个异常信息,比如“评论失败,请重试”或者“评论功能暂时不可用,请稍后再试”
- 如果一个视频网站的高清视频播放功能出现了延迟或者故障,可以给用户返回一个降级的视频播放功能,比如只提供标清视频播放。
如何解决
综上分析,
1、高并发情况下出现了服务降级无非就是 服务器压力过大,或者超过了熔断的阈值导致了降级。如果服务端还能承受那就调整熔断的阈值。
2、如果不能承受就修改在降级后响应给用户数据,来保证高并发。
在使用jmeter进行压测时,错误的请求链接是如何产生的,比如100个请求同时进来,为啥会有链接成功,也有部分链接报错,这是什么原理呢?实际上并发小的情况下 代码并不会报错,这是为什么
在使用 JMeter 进行压测时,错误的请求链接是由于多种原因导致的,比如网络延迟、服务器负载、请求参数、代码逻辑等。当有 100 个请求同时进来时,可能会有以下几种情况发生:
- 部分请求成功,部分请求失败。这可能是因为服务器的处理能力不足以应对高并发的压力,导致部分请求超时或被拒绝。或者是因为请求参数不合法或不一致,导致部分请求无法正常处理。或者是因为代码逻辑存在缺陷或异常,导致部分请求出现错误。
- 所有请求都失败。这可能是因为网络连接断开或不稳定,导致所有请求无法到达服务器。或者是因为服务器崩溃或宕机,导致所有请求无法得到响应。或者是因为请求参数或代码逻辑存在严重的问题,导致所有请求都无法正常处理。
- 所有请求都成功。这可能是因为网络连接良好,服务器性能强大,请求参数合法,代码逻辑正确,导致所有请求都能够正常处理。
实际上,并发小的情况下,代码并不会报错,这可能是因为以下几个原因:
- 并发小的情况下,服务器的压力较小,可以及时响应每个请求,不会出现超时或拒绝的情况。
- 并发小的情况下,请求参数较少或较简单,可以满足代码逻辑的要求,不会出现非法或异常的情况。
- 并发小的情况下,代码逻辑较少或较简单,可以正确地处理每个请求,不会出现缺陷或错误的情况。
如果请求参数一致,为什么还要错误的链接
压测时请求的参数都是一致的,为什么还会出现部分请求成功,部分请求失败的情况,这可能是因为以下几个原因:
- 请求的参数虽然一致,但是请求的时间不一致。不同的请求可能会在不同的时间点发送,而服务器的状态和负载可能会随着时间而变化。例如,如果服务器在某个时间点出现了高峰或异常,那么在这个时间点发送的请求就有可能失败,而在其他时间点发送的请求就有可能成功。
- 请求的参数虽然一致,但是请求的环境不一致。不同的请求可能会经过不同的网络路径或设备,而网络和设备的状况可能会影响请求的结果。例如,如果网络出现了延迟或丢包,那么部分请求就有可能超时或丢失,而其他请求就有可能正常到达服务器。
- 请求的参数虽然一致,但是请求的处理不一致。不同的请求可能会被分配到不同的服务器或线程来处理,而服务器或线程的性能和资源可能会影响请求的结果。例如,如果某个服务器或线程出现了负载过高或内存不足,那么由它处理的请求就有可能失败,而由其他服务器或线程处理的请求就有可能成功。
压测过程中,如果并发高的情况下,有的请求报500错误,有的请求是成功的。如果并发小的情况下 所有的请求都是成功的,这说明了什么?既然有请求成功,为什么还会报500错误呢?500错误是代码错误啊,既然是请求成功的为啥还会报代码错误呢?
压测过程中,如果并发高的情况下,有的请求报 500 错误,有的请求是成功的。如果并发小的情况下 所有的请求都是成功的,这说明了以下几点:
- 服务器的处理能力有限,不能同时满足高并发的压力,导致部分请求失败。
- 代码逻辑存在缺陷或异常,不能正确地处理高并发的情况,导致部分请求出错。
- 网络或设备存在问题,不能稳定地传输高并发的数据,导致部分请求丢失或超时。
既然有请求成功,为什么还会报 500 错误呢?500 错误是服务器内部错误,表示服务器在处理请求时出现了意料之外的情况,无法完成请求。这可能是由于以下几种原因:
- 服务器资源不足,如 CPU、内存、磁盘等,导致服务器无法正常运行或响应请求。
- 服务器配置不当,如线程数、连接数、超时时间等,导致服务器无法处理高并发的请求。
- 代码逻辑错误,如空指针、数组越界、类型转换等,导致服务器抛出异常或崩溃。
- 数据库操作错误,如 SQL 语句、事务处理、连接池等,导致服务器无法访问或操作数据库。
既然是请求成功的为什么还会报代码错误呢?这可能是由于以下几种原因:
- 请求成功的只是指请求能够到达服务器,并不一定表示请求能够得到正确的响应。服务器在处理请求时可能会遇到代码错误,导致返回 500 错误。
- 请求成功的只是指请求能够得到响应,并不一定表示响应能够满足预期。服务器在返回响应时可能会遇到代码错误,导致返回错误的数据或格式。
- 请求成功的只是指部分请求能够正常处理,并不一定表示所有请求都能够正常处理。服务器在处理高并发的请求时可能会遇到代码错误,导致部分请求失败。
如何使用jmeter进行压测
压测完整步骤
对app服务端压测分为两个步骤:
1、使用fildder工具进行抓包
2、根据抓取的信息在jmeter上创建测试计划,并填写抓取信息。(这里可通过fildder 导出jmx脚本供jmeter使用)
Fiddler是一款可以抓取HTTP/HTTPS/FTP请求的工具,它可以通过代理的方式拦截和修改网络流量,从而获取app应用的请求链接和请求头等信息。要使用Fiddler抓取app应用的请求,您需要做以下几个步骤:
- 在电脑上安装Fiddler,并设置为允许远程连接和解密HTTPS请求。
- 在手机上设置网络代理为电脑的IP地址和Fiddler的端口号(默认为8888)。
- 在手机上安装Fiddler的根证书,并设置为信任。(如果是http协议此步骤可省略)
- 在手机上打开app应用,进行操作,然后在电脑上的Fiddler中查看抓取到的请求和响应。
具体的操作方法和截图,您可以参考以下链接:
- 十六、Fiddler抓包工具详细教程 — 抓取移动端App请求
- Fiddler如何对手机抓包?
- 全网最详细,Fiddler抓包实战 - 手机APP端https请求(超详细)
JMeter是一款可以进行性能测试和压力测试的工具,它可以根据Fiddler抓取到的请求信息来模拟用户并发访问app应用。要使用JMeter进行压测,您需要做以下几个步骤:
- 在电脑上安装JMeter,并启动JMeter GUI。
- 在JMeter中创建一个测试计划,并添加线程组、HTTP请求、断言、监听器等元件。
- 在HTTP请求中填写Fiddler抓取到的请求链接、请求方法、请求参数、请求头等信息。
- 在线程组中设置线程数、循环次数、启动时间等参数。
- 在监听器中选择要查看的结果报告或图表。
- 点击运行按钮,开始压测,并观察结果。
如果您要抓取的协议是HTTP协议,那么Fiddler的操作方法和上述操作基本一致,只是不需要安装和信任Fiddler的根证书,也不需要设置解密HTTPS请求。您只需要在手机上设置网络代理为电脑的IP地址和Fiddler的端口号(默认为8888),然后在手机上打开app应用,进行操作,就可以在电脑上的Fiddler中查看抓取到的HTTP请求和响应。
JMeter的操作方法也和我之前回答的基本一致,只是不需要在HTTP请求中填写SSL管理器或Keystore配置元件。您只需要在HTTP请求中填写Fiddler抓取到的请求链接、请求方法、请求参数、请求头等信息,然后在线程组中设置线程数、循环次数、启动时间等参数,就可以开始压测。
如果您想要简便的操作方式,您可以尝试使用Fiddler的导出功能,将抓取到的请求导出为JMeter脚本文件(.jmx格式),然后在JMeter中直接打开该文件,就可以看到已经配置好的测试计划。
jmeter中结构树
测试计划-》线程组-》控制器-》Http Request-》(请求头、提取器、响应断言)
jmeter中,常用的监听器
View Result Tree ( 结果查看树)、Aggregate Report(聚合报告)、Asserssion Result(断言结果)
聚合报告中各个参数
聚合报告是一种常用的性能测试结果分析工具,它可以显示每个请求的统计信息,如响应时间、吞吐量、错误率等。
聚合报告的各个参数的含义如下:
- Label:请求的名称,就是脚本中Sampler的名称。
- Samples:总共发给服务器的请求数量,如果模拟10个用户,每个用户迭代10次,那么总的请求数为:10*10 =100次。
- Average:默认情况下是单个Request的平均响应时间,当使用了Transaction Controller(事务控制器)时,也可以用Transaction的时间,来显示平均响应时间,单位是毫秒。
- Median:中位数,50%用户的响应时间小于该值,注意它与Average平均响应时间的区别。
- 90% Line:90%用户的响应时间小于该值,表示有90%的请求耗时都在这个时间之内。
- 95% Line:95%用户的响应时间小于该值,表示有95%的请求耗时都在这个时间之内。
- 99% Line:99%用户的响应时间小于该值,表示有99%的请求耗时都在这个时间之内。
- Min:最小的响应时间。
- Max:最大的响应时间。
- Error%:错误率=错误请求的数量/请求的总数。
- Throughput:默认情况下表示每秒完成的请求数(Request per Second)。
- Received KB/sec:每秒从服务器端接收到的数据量。
- Sent KB/sec:每秒发送到服务器端的数据量。
结果树报告
spring boot默认参数配置
这是因为在springboot项目中,内置的tomcat服务器就已经设置了并发的参数。主要有四个参数比较重要,如下是默认配置
server.tomcat.accept-count=100 # 设置请求队列的最大长度 server.tomcat.max-connections=10000 # 设置最大连接数 server.tomcat.max-threads=200 # 设置最大工作线程数 server.tomcat.min-spare-threads=10 # 设置最小空闲线程数
这四个参数是指 Spring Boot 内置 tomcat 的配置参数,分别是:
- server.tomcat.accept-count:设置请求队列的最大长度,即当所有可用线程都被占用时,可以放入队列中等待的请求的个数。
- server.tomcat.max-connections:设置最大连接数,即 tomcat 可以同时处理的最大请求数。
- server.tomcat.max-threads:设置最大工作线程数,即 tomcat 可以同时运行的最大线程数。
- server.tomcat.min-spare-threads:设置最小空闲线程数,即 tomcat 在运行时保持的最小空闲线程数。
这四个参数的含义可以用一个生活中的案例来类比,例如:
假设有一个快餐店,它有一个柜台和一个厨房。柜台负责接收顾客的订单,厨房负责制作食物。我们可以把这个快餐店看作是一个 tomcat 服务器,把顾客看作是请求,把柜台和厨房看作是线程。
那么,这四个参数就相当于:
- server.tomcat.accept-count:柜台后面有一个等候区,可以容纳一定数量的顾客排队等待。当柜台和厨房都忙不过来时,新来的顾客就会进入等候区。如果等候区也满了,那么新来的顾客就会被拒绝服务。这个等候区的容量就相当于请求队列的最大长度。
- server.tomcat.max-connections:快餐店有一个门槛,限制了同时进入店内的顾客数量。当店内已经达到门槛限制时,新来的顾客就不能进入店内,只能在门外等待。这个门槛限制就相当于最大连接数。
- server.tomcat.max-threads:快餐店有一定数量的员工,包括柜台和厨房的工作人员。每个员工可以同时为一个顾客提供服务,例如接单或制作食物。当所有员工都在忙时,新来的顾客就要等待空闲的员工。这个员工数量就相当于最大工作线程数。
- server.tomcat.min-spare-threads:快餐店为了保证服务质量和效率,会保持一定数量的空闲员工,以应对突发的高峰期或异常情况。这些空闲员工可以随时接手新来的顾客或替换出现问题的员工。这个空闲员工数量就相当于最小空闲线程数。
在使用过程中,如何配置这四个参数取决于您的应用程序的性能需求和实际情况。一般来说,您可以参考以下的原则:
- server.tomcat.accept-count:建议设置为一个较大的值,以免在高并发情况下拒绝过多的请求。但是也不能设置过大,以免造成内存溢出或响应延迟。
- server.tomcat.max-connections:建议设置为一个较大的值,以免在高并发情况下拒绝过多的请求。但是也不能设置过大,以免超过服务器或网络设备的承载能力。
- server.tomcat.max-threads:建议根据服务器的 CPU 核心数和应用程序的业务逻辑来设置一个合理的值。一般来说,可以设置为 CPU 核心数的 2 倍或 4 倍。如果设置过小,会导致线程不足,无法处理所有的请求。如果设置过大,会导致线程切换开销过大,影响性能。
- server.tomcat.min-spare-threads:建议设置为一个较小的值,以免浪费资源。但是也不能设置为 0,以免在高并发情况下无法及时响应请求。
机器的配置是影响这四个参数的重要因素,主要包括 CPU、内存、网络等方面。一般来说,机器的配置越高,就可以支持更高的并发数和更快的响应速度。但是,机器的配置并不是唯一的决定因素,还需要考虑应用程序的代码质量、业务逻辑、缓存策略、数据库优化等方面。
也就是说,当100个请求同时进来后,当前配置能处理的最大并发数 = max-threads + accept-count(队列数)
请求的超时时间是如何影响并发的呢?
如果在请求响应中超时,那么一般来说就会占用一定的资源,增加了服务器的负载,所以必要的请求超时时间的设置也是必不可少的。
链接服务器的超时时间是指客户端在发送请求后,等待服务器响应的最大时间。如果在这个时间内,客户端没有收到服务器的响应,那么客户端就会认为请求失败,抛出一个超时异常。
链接服务器的超时时间是如何影响并发的呢?一般来说,链接服务器的超时时间越短,就可以支持更高的并发数,但是也会增加请求失败的风险。链接服务器的超时时间越长,就可以降低请求失败的风险,但是也会占用更多的资源,限制并发数。
为什么会这样呢?我们可以用一个生活中的例子来类比,例如:
假设有一个银行,它有一个柜台和一个后台系统。柜台负责接收客户的业务请求,后台系统负责处理业务逻辑。我们可以把这个银行看作是一个客户端,把后台系统看作是一个服务器。
那么,链接服务器的超时时间就相当于柜台等待后台系统响应的最大时间。如果在这个时间内,柜台没有收到后台系统的响应,那么柜台就会认为业务失败,向客户道歉并结束服务。
如果链接服务器的超时时间设置得很短,比如 1 分钟,那么柜台就可以快速地处理每个客户的业务请求,不会占用太多的资源,可以支持更多的客户同时办理业务。但是,如果后台系统处理业务逻辑需要花费较长的时间,或者出现了网络延迟或故障等情况,那么柜台就有可能在 1 分钟内没有收到后台系统的响应,导致业务失败。
如果链接服务器的超时时间设置得很长,比如 10 分钟,那么柜台就可以降低业务失败的风险,即使后台系统处理业务逻辑需要花费较长的时间,或者出现了网络延迟或故障等情况,柜台也可以等待更久地收到后台系统的响应。但是,如果柜台处理每个客户的业务请求需要花费较长的时间,那么柜台就会占用更多的资源,无法支持更多的客户同时办理业务。
因此,在设置链接服务器的超时时间时,需要根据实际情况和需求来进行权衡和调整。一般来说,可以参考以下的原则:
- 链接服务器的超时时间应该设置为一个合理的值,既不能过短也不能过长。过短会导致请求失败率过高,影响用户体验和服务质量。过长会导致资源浪费和性能下降,影响并发能力和服务效率。
- 链接服务器的超时时间应该根据服务器的处理能力和网络状况来动态调整。如果服务器处理能力强大且网络状况良好,那么可以适当缩短超时时间。如果服务器处理能力不足或网络状况不稳定,那么可以适当延长超时时间。
- 链接服务器的超时时间应该根据请求类型和优先级来区分设置。如果请求类型比较简单或优先级比较高,那么可以设置较短的超时时间。如果请求类型比较复杂或优先级比较低,那么可以设置较长的超时时间。
在spring boot项目中,有很多可能的超时时间需要配置:
1、zuul网关
#默认1000
zuul.host.socket-timeout-millis=2000
#默认2000
zuul.host.connect-timeout-millis=4000
2、ribbon
ribbon:OkToRetryOnAllOperations: false #对所有操作请求都进行重试,默认falseReadTimeout: 5000 #负载均衡超时时间,默认值5000ConnectTimeout: 3000 #ribbon请求连接的超时时间,默认值2000MaxAutoRetries: 0 #对当前实例的重试次数,默认0MaxAutoRetriesNextServer: 1 #对切换实例的重试次数,默认1
3、熔断器Hixtry
hystrix:command:default: #default全局有效,service id指定应用有效execution:timeout:#如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据enabled: trueisolation:thread:timeoutInMilliseconds: 1000 #断路器超时时间,默认1000msfeign.hystrix.enabled: true
- 如果hystrix.command.default.execution.timeout.enabled为true,则会有两个执行方法超时的配置,一个就是ribbon的ReadTimeout,一个就是熔断器hystrix的timeoutInMilliseconds, 此时谁的值小谁生效
- 如果hystrix.command.default.execution.timeout.enabled为false,则熔断器不进行超时熔断,而是根据ribbon的ReadTimeout抛出的异常而熔断,也就是取决于ribbon
- ribbon的ConnectTimeout,配置的是请求服务的超时时间,除非服务找不到,或者网络原因,这个时间才会生效
- ribbon还有MaxAutoRetries是单个实例的重试次数,MaxAutoRetriesNextServer对切换实例的次数(是切换次数,不是重试次数), 如果ribbon的ReadTimeout超时,或者ConnectTimeout连接超时,会进行重试操作
- 由于ribbon的重试机制,通常熔断的超时时间需要配置的比ReadTimeout长,ReadTimeout比ConnectTimeout长,否则还未重试,就熔断了
- 为了确保重试机制的正常运作,理论上(以实际情况为准)建议hystrix的超时时间为:(1 + MaxAutoRetries)*(1+ MaxAutoRetriesNextServer) * ReadTimeout.
如下合适的配置:
ribbon:OkToRetryOnAllOperations: false #对所有操作请求都进行重试,默认falseReadTimeout: 10000 #负载均衡超时时间,默认值5000ConnectTimeout: 2000 #ribbon请求连接的超时时间,默认值2000MaxAutoRetries: 0 #对当前实例的重试次数,默认0MaxAutoRetriesNextServer: 1 #切换实例的次数,默认1hystrix:command:default: #default全局有效,service id指定应用有效execution:timeout:enabled: trueisolation:thread:timeoutInMilliseconds: 20000 #断路器超时时间,默认1000ms
4、 配置Http会话超时
- 可以通过两种方式为Spring Boot应用程序配置HTTP会话超时。
application.properties中配置会话超时
最简单的方法是在你的application.properties中加入参数server.servlet.session.timeout。比如说
server.servlet.session.timeout=60s
还要注意的是,Tomcat不允许你将超时时间设置得少于60秒。
- 以程序方式配置会话超时
假设我们想让我们的HttpSession只持续两分钟。为了实现这一点,我们可以在我们的WebConfiguration类中添加一个EmbeddedServletContainerCustomizer Bean,内容如下。
@Configuration
public class WebConfiguration {@Beanpublic EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer() {return new EmbeddedServletContainerCustomizer() {@Overridepublic void customize(ConfigurableEmbeddedServletContainer container) {container.setSessionTimeout(2, TimeUnit.MINUTES);}};}
使用Java 8和lambda表达式的捷径写法。
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer() {return (ConfigurableEmbeddedServletContainer container) -> {container.setSessionTimeout(2, TimeUnit.MINUTES);};}
在应用程序启动期间,Spring Boot自动配置检测到EmbeddedServletContainerCustomizer,并调用customize(…)方法,传递对Servlet容器的引用。
5、配置接口访问超时
一、配置文件方式
在配置文件application.properties中加了spring.mvc.async.request-timeout=120000,意思是设置超时时间为120000ms即120s
spring.mvc.async.request-timeout=120000
二、配置Config配置类
还有一种就是在config配置类中加入:
public class WebMvcConfig extends WebMvcConfigurerAdapter {@Overridepublic void configureAsyncSupport(final AsyncSupportConfigurer configurer) {configurer.setDefaultTimeout(20000);configurer.registerCallableInterceptors(timeoutInterceptor());}@Beanpublic TimeoutCallableProcessingInterceptor timeoutInterceptor() {return new TimeoutCallableProcessingInterceptor();}
}
6、Nginx的设置
如果服务端使用到Nginx做了反向代理转发请求,就需要在Nginx的配置文件nginx.conf中设置超时时间,否则会返回“java.io.IOException: 你的主机中的软件中止了一个已建立的连接”这样的异常提示。
未设置时Nginx响应时间默认60秒,这里将http头部的keepalive_timeout 、client_header_timeout 、client_body_timeout 、send_timeout 、以及server代码块中的proxy_read_timeout 均配置为120秒。
http {include mime.types;default_type application/octet-stream;client_max_body_size 100m;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;sendfile on;
#tcp_nopush on;keepalive_timeout 120; #连接超时时间,服务器将会在这个时间后关闭连接
send_timeout 120; #发送超时时间
client_header_timeout 120; #请求头的超时时间
client_body_timeout 120; #请求体的读超时时间
#gzip on;
#业务系统的配置
server {listen 9092;server_name localhost;location / {proxy_pass http://127.0.0.1:8811/mywebsev/;proxy_read_timeout 120; # 等候后端服务器响应时间 秒}
}
bytes_sent “KaTeX parse error: Expected 'EOF', got '#' at position 21: …referer" ' #̲ …http_user_agent” “$http_x_forwarded_for”';
```nginx
#access_log logs/access.log main;sendfile on;
#tcp_nopush on;keepalive_timeout 120; #连接超时时间,服务器将会在这个时间后关闭连接
send_timeout 120; #发送超时时间
client_header_timeout 120; #请求头的超时时间
client_body_timeout 120; #请求体的读超时时间
#gzip on;
#业务系统的配置
server {listen 9092;server_name localhost;location / {proxy_pass http://127.0.0.1:8811/mywebsev/;proxy_read_timeout 120; # 等候后端服务器响应时间 秒}
}
相关文章:
spring boot项目一次性能测试的总结
满足标准:并发大于等于100 ,平均响应时间小于等于3秒 项目在压测过程中并发数只有50,在并发数100的情况下有很多请求链接是失败的 我们该如何入手去处理这些问题并提高并发数呢? 1、首先从压测结果入手,对不满足标准…...
10分钟设置免费海外远程桌面
前言 本教程将向您介绍如何使用 Amazon Lightsail 服务的免费套餐轻松搭建属于您的远程桌面。依托于 Amazon 全球可用区,您可以在世界各地搭建符合您配置需求的远程桌面。 本教程需要先拥有亚马逊云科技海外账户。现在注册亚马逊云科技账户可以享受12个月免费套餐…...
基于复旦微的FMQL45T900全国产化ARM核心模块(100%国产化)
TES745D是一款基于上海复旦微电子FMQL45T900的全国产化ARM核心板。该核心板将复旦微的FMQL45T900(与XILINX的XC7Z045-2FFG900I兼容)的最小系统集成在了一个87*117mm的核心板上,可以作为一个核心模块,进行功能性扩展,能…...
2023.9.11 关于传输层协议 UDP和TCP 详解
目录 UDP协议 TCP协议 TCP十大核心机制 确认应答 超时重传 连接管理(三次握手 四次挥手) 滑动窗口 流量控制 拥塞控制 延时应答 捎带应答 面向字节流 粘包问题 TCP 中的异常处理 经典面试题 对比 TCP 和 UDP 如何使用 UDP 实现可靠传…...
thinkphp8路由
thinkphp8已出来有好一段时间了。这些天闲来无事,研究了下tp8的路由。默认情况下,tp8的路由是在route\app.php的文件里。但在实际工作中,我们并不会这样子去写路由。因为这样不好管理。更多的,是通过应用级别去管理路由。假如项目…...
Python统计pdf中英文单词的个数
之前的文章提供了批量识别pdf中英文的方法,详见【python爬虫】批量识别pdf中的英文,自动翻译成中文上。以及自动pdf英文转中文文档,详见【python爬虫】批量识别pdf中的英文,自动翻译成中文下。 本文实现python统计pdf中英文字符的个数。 文章目录 一、要统计字符的pdf…...
Kindle电子书下载功能关闭怎么办,借助calibre和cpolar搭建私有的网络书库公网访问
Kindle中国电子书店停运不要慌,十分钟搭建自己的在线书库随时随地看小说! 文章目录 Kindle中国电子书店停运不要慌,十分钟搭建自己的在线书库随时随地看小说!1.网络书库软件下载安装2.网络书库服务器设置3.内网穿透工具设置4.公网…...
ubuntu、linux in window安装docker教程
1、首先进入管理员权限。 2、更新软件源。 sudo apt update 3、安装一些依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common 4、为系统添加Docker的密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-k…...
clickhouse学习之路----clickhouse的特点及安装
clickhouse学习笔记 反正都有学不完的技术,不如就学一学clickhouse吧 文章目录 clickhouse学习笔记clickhouse的特点1.列式存储2. DBMS 的功能3.多样化引擎4.高吞吐写入能力5.数据分区与线程级并行 clickhouse安装1.关闭防火墙2.CentOS 取消打开文件数限制3.安装依…...
STM32 驱动
led 驱动 led头文件 #ifndef _LED_H #define _LED_Hvoid LED_Init(void); void LED_ON(void); void LED_OFF(void); void LED_Turn(void);#endifled代码 #include "stm32f10x.h" void LED_Init(void) {//START CLOCKRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO…...
JavaScript系列从入门到精通系列第五篇:JavaScript中的强制类型转换包含强制类型转换之Number,包含强制类型转换之String
文章目录 前言 一:强制类型转换 1:强制类型转换为String (一):方式一:调用被转换类型的toString()方法 (二):方式二:调用String函数 2:强制类型转换为Number (一):方式一&…...
动力节点老杜JavaWeb笔记(全)
Servlet 关于系统架构 系统架构包括什么形式? C/S架构B/S架构C/S架构? Client / Server(客户端 / 服务器)C/S架构的软件或者说系统有哪些呢? QQ(先去腾讯官网下载一个QQ软件,几十MB,然后把这个客户端软件安装上去,然后输入QQ号以及密码,登录之后,就可以和你的朋友聊…...
【微信小程序开发】宠物预约医疗项目实战-注册实现
【微信小程序开发】宠物预约医疗项目实战-注册实现 第二章 宠物预约医疗项目实战-注册实现 文章目录 【微信小程序开发】宠物预约医疗项目实战-注册实现前言一、打开项目文件二、编写wxss代码2.1 什么是wxss2.2 配置主程序全局样式 三. 在sign文件下的wxml文件中编写如下代码并…...
聚观早报 | 飞书签约韵达速递;蔚来首颗自研芯片“杨戬”量产
【聚观365】9月22日消息 飞书签约韵达速递 蔚来首颗自研芯片“杨戬”10月量产 靳玉志接任华为车 BU CEO 亚马逊发布全新Alexa语音助手 OpenAI推出图像生成器DALL-E 3 飞书签约韵达速递 近日,国内物流服务公司韵达快递宣布全员上飞书。飞书解决方案副总裁何斌表…...
zookeeper + kafka
Zookeeper 概述 Zookeeper是一个开源的分布式服务管理框架。存储业务服务节点元数据及状态信息,并负责通知再 ZooKeeper 上注册的服务几点状态给客户端 Zookeeper 工作机制 Zookeeper从设计模式角度来理解: 是一个基于观察者模式设计的分布式服务管理框架&…...
wordpress添加评论过滤器
给wordpress添加评论过滤器,如果用户留言包含 "http" (可以为任意字符串) 就禁止提交评论。 function filter_comment_content($comment_data) {$comment_contents $comment_data["comment_content"]; //获取评论表单的内容字段if (stripos($…...
工具篇 | Gradle入门与使用指南
介绍 1.1 什么是Gradle? Gradle是一个开源构建自动化工具,专为大型项目设计。它基于DSL(领域特定语言)编写,该语言是用Groovy编写的,使得构建脚本更加简洁和强大。Gradle不仅可以构建Java应用程序&#x…...
Wireshark TS | MQ 传输缓慢问题
问题背景 应用传输慢是一种比较常见的问题,慢在哪,为什么慢,有时候光从网络数据包分析方面很难回答的一清二楚,毕竟不同的技术方向专业性太强,全栈大佬只能仰望,而我们能做到的是在专注于自身的专业方向之…...
flink集群与资源@k8s源码分析-回顾
本章是分析系列最后一章,作为回顾,以运行架构图串联起所有分析场景 1 启动集群,部署集群(提交k8s),新建作业管理器组件 2 构建和启动flink master组件 3 提交作业,N/A...
学习心得09:C++新特性
现在语言越来越复杂,关键字也越来越多。所以我提出了关键字自动加标识的想法。 这些新特性也都是有用的,一般人也用不上。在这方面,我的主张是:除非你确实需要用到新特性,否则尽量不要用。保证了代码的可维护。 C很复杂…...
前端框架vBean admin
文章目录 引言I 数据库表设计1.1 用户表1.2 角色表1.3 菜单表II 接口引言 文档:https://doc.vvbin.cn/guide/introduction.html http://doc.vvbin.cn 仓库:https://github.com/vbenjs/vue-vben-admin git clone https://github.com/vbenjs/vue-vben-admin-doc 在线体验demo:…...
云原生周刊:Grafana Beyla 发布 | 2023.9.18
开源项目推荐 Komiser Komiser 是一个与云无关的开源资源管理器。它与多个云提供商(包括 AWS、Azure、Civo、Digital Ocean、OCI、Linode、腾讯和 Scaleway)集成,构建云资产库存,并帮助您在资源层面分解成本。 kr8s 这是一个用…...
C++ std::unique_lock 用法
文章目录 1.创建 std::unique_lock 对象2.自动加锁和解锁3.延迟加锁与手动加解锁4.尝试加锁5.配合条件变量使用6.小结参考文献 std::unique_lock 是 C11 提供的一个用于管理互斥锁的类,它提供了更灵活的锁管理功能,适用于各种多线程场景。 1.创建 std::u…...
Pytorch C++ 前端第二部分:输入、权重和偏差
本教程分为两部分 第 2.1 部分 – 基础知识速成课程。第 2.2 部分 – 使用 C++ 构建神经网络如果您已经了解神经网络的基础知识,那么无需阅读 Part-2.1 的内容,理解 Part-2.2 应该没有问题。我们试图通过动画 GIF 来可视化方程,从而使其简短而有趣。但请注意,我们根据在解释…...
面试题:RocketMQ 如何保证消息不丢失,如何保证消息不被重复消费?
文章目录 1、消息整体处理过程Producer发送消息阶段手段一:提供SYNC的发送消息方式,等待broker处理结果。手段二:发送消息如果失败或者超时,则重新发送。手段三:broker提供多master模式,即使某台broker宕机…...
uniapp打包安卓后在安卓屏上实现开机自启动
实现开机自启动(使用插件) 打开插件地址安卓开机自启动 Fvv-AutoStart - DCloud 插件市场 使用方法 选择你要开启自启动的项目 在项目的manifest.json中app-plus下写入以下代码 注意需要替换 android_package_name 为自己的,不然无法进行安卓apk打包 "nativePlugins&q…...
浅谈KNX总线智能照明控制系统在北京南站房中的应用
安科瑞 华楠 摘要:本文简要介绍了i-bus EIB/KNX智能建筑控制系统的基本原理及在北京南站房中的成功应用。阐述了这一系统强大的系统功能、灵活的控制方式节能效果。 关键词:i-bus智能建筑控制;控制系统;节能 1、工程概况 北京新…...
深入了解Java的核心库
掌握Java的核心库是成为一名优秀的Java开发者的关键。Java提供了丰富的核心库和API,包括集合框架、输入输出、多线程、异常处理等等。熟悉并掌握这些库的使用,可以提高编程效率和代码质量。在本文中,我们将深入讨论Java的核心库,并…...
嵌入式:驱动开发 Day9
作业:通过platform总线驱动实现 a.应用程序通过阻塞的io模型来读取number变量的值 b.number是内核驱动中的一个变量 c.number的值随着按键按下而改变(按键中断) 例如number0 按下按键number1 ,再次按下按键number0 d.在按下按键的时候需要同时…...
【ComfyUI】安装 之 window版
文章目录 序言步骤下载comfyUI配置大模型和vae下载依赖组件启动 生成图片解决办法 序言 由于stable diffusion web ui无法做到对流程进行控制,只是点击个生成按钮后,一切都交给AI来处理。但是用于生产生活是需要精细化对各个流程都要进行控制的。 故也…...
禅城网站设计/拉新人拿奖励的app
特征脸方法是90年代初期由Turk和Pentland提出的目前最流行的算法之一,具有简单有效的特点,也称为基于主成分分析(principal component analysis,简称PCA)的人脸识别方法。特征子脸技术的基本思想是:从统计的观点,寻找人脸图像分布的基本元素&…...
穆棱市城乡建设局网站/黑帽seo优化软件
servlet生命周期 为简洁,本例使用注解方式来测试,代码部分很简单,只需要新建一个serlet,继承自HttpServlet,重写init,doGet,doPost,destory方法即可,使用注解WebServlet注解分别测试存在loadOnStartup 和不…...
深圳建设工程交易网站官网/百度广告大全
题意:给了一个矩阵图,要求使用回路把图中的树全部吃掉的方案树,没有树的点不能走,吃完了这个点也就没有了,走到哪吃到哪 用插头dp搞 #include <iostream> #include <algorithm> #include <cstdio> #include <…...
绵阳的网站建设/可以免费打开网站的软件
laravel给我们提供了多渠道的消息通知功能,包括邮件,短信,数据库,slack等通知方式。本文主要分析基于数据库的消息通知的底层实现。为了方便,本文将需要接受通知消息的模型称为接收者。 ps:阅读本文前,请不了解Eloquent关联关系的读者先点击e…...
wordpress隐藏菜单/推广公司品牌
一、在上一篇博客中,我们已经安装配置成功Maven,并且建立一个基于Maven的web项目,并且导入mahout依赖。 问题:在网上找到的两个例子ChartTwo与Collaborative Filtering中均没有用Maven建立项目,直接用Mahout。那我们这里为啥要用…...
在家帮别人做网站赚钱/外包公司是什么意思
文件系统类型 在windows中我们常见的磁盘格式有fat16、fat32和ntfs。但是windows的文件管理显得有些赘余,为打开一个文件需要打开n个地方,在一个角落里找。而且windows本身对于其他系统的文件格式就更差了,没有听说在windows里打开ext3或者ma…...