杭州网站建设优化案例,电子商务网站数据库怎么做,鹤壁建设网站推广渠道,网页设计尺寸1440满足标准#xff1a;并发大于等于100 #xff0c;平均响应时间小于等于3秒
项目在压测过程中并发数只有50#xff0c;在并发数100的情况下有很多请求链接是失败的
我们该如何入手去处理这些问题并提高并发数呢#xff1f;
1、首先从压测结果入手#xff0c;对不满足标准…满足标准并发大于等于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.enabledtrue来启用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.HystrixRuntimeExceptionBaseUserRemote#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.strategySEMAPHORE
# 设置 Hystrix 信号量隔离策略的最大并发请求数
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests100
# 设置 Hystrix 信号量隔离策略的最大并发回退请求数
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests50
# 设置 Hystrix 熔断器开关true 表示开启熔断器
hystrix.command.default.circuitBreaker.enabledtrue
# 设置 Hystrix 熔断器的请求阈值即在一个统计窗口内最少请求数
hystrix.command.default.circuitBreaker.requestVolumeThreshold20
# 设置 Hystrix 熔断器的错误率阈值即触发熔断的错误百分比
hystrix.command.default.circuitBreaker.errorThresholdPercentage50
# 设置 Hystrix 熔断器的休眠时间窗即熔断后多久尝试恢复默认为 5 秒
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds5000
高并发一下如何设置 hixtry 和 ribbon的超时时间 一般来说hixtry的超时时间包括以下几个方面 execution.isolation.thread.timeoutInMilliseconds执行命令的超时时间单位为毫秒默认为1000execution.timeout.enabled是否启用执行超时默认为truefallback.isolation.thread.timeoutInMilliseconds执行fallback的超时时间单位为毫秒默认为1000fallback.enabled是否启用fallback默认为true 一般来说ribbon的超时时间包括以下几个方面 ribbon.ConnectTimeout建立连接的超时时间单位为毫秒默认为1000ribbon.ReadTimeout读取数据的超时时间单位为毫秒默认为5000ribbon.OkToRetryOnAllOperations是否对所有操作都重试默认为falseribbon.MaxAutoRetries对同一个服务器的最大重试次数默认为0ribbon.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.maxConcurrentRequests100时就相当于把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% Line90%用户的响应时间小于该值表示有90%的请求耗时都在这个时间之内。95% Line95%用户的响应时间小于该值表示有95%的请求耗时都在这个时间之内。99% Line99%用户的响应时间小于该值表示有99%的请求耗时都在这个时间之内。Min最小的响应时间。Max最大的响应时间。Error%错误率错误请求的数量/请求的总数。Throughput默认情况下表示每秒完成的请求数Request per Second。Received KB/sec每秒从服务器端接收到的数据量。Sent KB/sec每秒发送到服务器端的数据量。
结果树报告 spring boot默认参数配置
这是因为在springboot项目中内置的tomcat服务器就已经设置了并发的参数。主要有四个参数比较重要如下是默认配置
server.tomcat.accept-count100 # 设置请求队列的最大长度 server.tomcat.max-connections10000 # 设置最大连接数 server.tomcat.max-threads200 # 设置最大工作线程数 server.tomcat.min-spare-threads10 # 设置最小空闲线程数
这四个参数是指 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-millis2000
#默认2000
zuul.host.connect-timeout-millis40002、ribbon
ribbon:OkToRetryOnAllOperations: false #对所有操作请求都进行重试,默认falseReadTimeout: 5000 #负载均衡超时时间默认值5000ConnectTimeout: 3000 #ribbon请求连接的超时时间默认值2000MaxAutoRetries: 0 #对当前实例的重试次数默认0MaxAutoRetriesNextServer: 1 #对切换实例的重试次数默认13、熔断器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抛出的异常而熔断,也就是取决于ribbonribbon的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.timeout60s
还要注意的是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-timeout120000意思是设置超时时间为120000ms即120s
spring.mvc.async.request-timeout120000二、配置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; # 等候后端服务器响应时间 秒}
}