Tinkoff Gadling JDBC - 启用日志跟踪时的错误响应时间

问题描述 投票:0回答:1

目前我正在寻找Tinkoff 的 JDBC 插件中的 Gattle,当我启用

TRACE
日志时,响应时间更高,即从 1500 毫秒到 25 秒。

这是我的加特林

logback.xml
设置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
        </encoder>
        <immediateFlush>false</immediateFlush>
    </appender>

    <!-- uncomment and set to DEBUG to log all failing HTTP requests -->
    <!-- uncomment and set to TRACE to log all HTTP requests -->
    <logger name="io.gatling.http.engine.response" level="TRACE" />
    <!-- uncomment to log WebSocket events -->
    <!-- <logger name="io.gatling.http.action.ws.fsm" level="TRACE" /> -->

    <!-- uncomment to log SSE events -->
    <!-- <logger name="io.gatling.http.action.sse.fsm" level="TRACE" /> -->
    <!-- <root level="TRACE"> -->
    <root level="TRACE">
        <appender-ref ref="CONSOLE" />
    </root>

</configuration>

用于连接定义

object Actions_test {

    // database connection
    val database_URL: JdbcProtocolBuilder = DB
            .url("mariadb")
            .username("user")
            .password("pw@2024")
            .maximumPoolSize(10)
            .connectionTimeout(10.second)

    // large query
    def callingJDBC(): QueryActionBuilder = 
      jdbc("simple Call")
        .query("""your-large-query-here
               """.stripMargin)
        .check(simpleCheck(x => x.length > 2000)
      )        
}

适用场景:

class DebugTest extends Simulation {

  val scn = scenario("test")
    .exec(Actions_test.callingJDBC())
    .exitHere

  setUp(
    scn.inject(
      rampUsers(1000).during(500)
    ),
  )
  .protocols(Actions_test.database_URL)
  .maxDuration(10.minute)

}

如何正确配置此插件的日志记录?请帮助我。

scala jdbc gatling
1个回答
0
投票

TL;博士

将日志级别设置为跟踪不是您经常要做的事情,除非您确实需要查看正在执行的程序的大量详细信息。将应用程序的根记录器级别设置为

TRACE
并不是一个好主意,因为您将看到来自许多组件(http 客户端、db 客户端、gatting、akka 等)的内容。更好的方法可能是将根记录器级别设置为
WARN
INFO
并将某些特定记录器设置为
TRACE
。正如 gatting logback 虚拟配置中所解释的那样

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
        </encoder>
        <immediateFlush>false</immediateFlush>
    </appender>

    <!-- uncomment and set to DEBUG to log all failing HTTP requests -->
    <!-- uncomment and set to TRACE to log all HTTP requests -->
    <!--<logger name="io.gatling.http.engine.response" level="TRACE" />-->

    <!-- uncomment to log WebSocket events -->
    <!--<logger name="io.gatling.http.action.ws.fsm" level="DEBUG" />-->

    <!-- uncomment to log SSE events -->
    <!--<logger name="io.gatling.http.action.sse.fsm" level="DEBUG" />-->

    <root level="WARN">
        <appender-ref ref="CONSOLE" />
    </root>

</configuration>

不确定您的确切目标是什么,或者为什么您想在

TRACE
水平上取得良好的表现。 Logback 有附加程序,在本例中您使用的是 ConsoleAppender

顾名思义,

ConsoleAppender
附加在控制台上,或者更准确地说附加在 System.outSystem.err 上,前者是默认目标。 System.outSystem.err 都是
java.io.PrintStream
类型。因此,它们被包装在一个缓冲 I/O 操作的
OutputStreamWriter
中。

这意味着每次记录消息时记录器都会执行一次 I/O 操作。您可以将属性 immediateFlush 设置为

false
(默认为 true)来缓冲消息。这个来自OutputStreamAppender

物业名称 类型 描述
immediateFlush
boolean
immediateFlush
的默认值为
'true'
。立即刷新输出流可确保日志记录事件立即写出,并且在应用程序在未正确关闭附加程序的情况下退出时不会丢失。另一方面,将此属性设置为“false”可能会使记录吞吐量增加四倍(您的里程可能会有所不同)。同样,如果立即刷新设置为“假”并且应用程序退出时附加程序未正确关闭,则尚未写入磁盘的日志记录事件可能会丢失。

当您从日志级别

INFO
更改为
TRACE
时,您将增加记录器必须写入的消息量。所以,看到性能下降是可以接受的。

Apache commons loggins 库,您可以阅读以下日志级别消息的最佳实践

消息优先级/级别

确保日志消息的内容和严重性适当非常重要。建议遵循以下准则:

  • fatal - 导致提前终止的严重错误。预计这些将立即在状态控制台上可见。
  • error - 其他运行时错误或意外情况。预计这些将立即在状态控制台上可见。
  • 警告 - 使用已弃用的 API、API 使用不当、“几乎”错误、其他不希望或意外的运行时情况,但不一定是“错误”。预计这些将立即在状态控制台上可见。
  • info - 有趣的运行时事件(启动/关闭)。预计这些会立即在控制台上可见,因此要保守并保持在最低限度。
  • debug - 有关系统流程的详细信息。希望这些仅写入日志。
  • trace - 更详细的信息。希望这些仅写入日志。

话虽这么说,如果您确实需要将日志级别设置为

TRACE
,您可以尝试使用logback配置并使用不同的appenders,而不是使用gadling提供的默认配置。


我使用以下文件在本地重新创建了您在问题中详细说明的案例

  • build.sbt
ThisBuild / scalaVersion := "2.13.11"

lazy val GatlingSettings = inConfig(Gatling)(Defaults.testSettings)

lazy val root = (project in file("."))
  .enablePlugins(GatlingPlugin)
  .settings(
    name := "stackoverflow-pocs-secondary",
    libraryDependencies ++= Seq(
      "ch.qos.logback"              % "logback-classic"           % "1.4.14",
      "com.typesafe.scala-logging" %% "scala-logging"             % "3.9.5",
      "io.gatling.highcharts"       % "gatling-charts-highcharts" % "3.10.3",
      "io.gatling"                  % "gatling-test-framework"    % "3.10.3",
      "ru.tinkoff"                 %% "gatling-jdbc-plugin"       % "0.10.3",
      "org.postgresql"              % "postgresql"                % "42.7.1"
    ),
    GatlingSettings,
    run / fork := true
  )
  • project/plugins.sbt
addSbtPlugin("io.gatling" % "gatling-sbt" % "4.7.0")
  • src/gatling/BasicSimulation.scala
import io.gatling.core.Predef._
import ru.tinkoff.load.jdbc.Predef._
import ru.tinkoff.load.jdbc.actions.actions._
import ru.tinkoff.load.jdbc.protocol.JdbcProtocolBuilder

import scala.concurrent.duration.DurationInt

class BasicSimulation extends Simulation {

  val scn = scenario("test")
    .exec(ActionsTest.callingJDBC())
    .exitHere
  setUp(scn.inject(rampUsers(800).during(30)))
    .protocols(ActionsTest.database_URL)
    .maxDuration(10.minute)

}

object ActionsTest {
  val database_URL: JdbcProtocolBuilder = DB
    .url("jdbc:postgresql://localhost:5432/postgres")
    .username("admin")
    .password("admin")
    .maximumPoolSize(10)
    .connectionTimeout(10.second)
  def callingJDBC(): QueryActionBuilder =
    jdbc("simple Call")
      .query("select * from dummy_random_data")
      .check(simpleCheck(x => x.length > 2000))
}
  • src/gatling/resources/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
        </encoder>
        <immediateFlush>false</immediateFlush>
    </appender>

    <appender name="ASYNC-CONSOLE" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="CONSOLE"/>
        <queueSize>16384</queueSize>
        <maxFlushTime>MAX_FLUSH_TIME</maxFlushTime>
        <neverBlock>false</neverBlock>
    </appender>

    <root level="WARN">
        <appender-ref ref="CONSOLE"/>
        <!-- <appender-ref ref="ASYNC-CONSOLE"/> -->
    </root>

</configuration>
  • docker-compose.yaml
version: '3.1'
services:
  db:
    image: postgres:15.4-alpine3.18
    restart: always
    environment:
      - POSTGRES_PASSWORD=admin
      - POSTGRES_USER=admin
      - POSTGRES_DB=postgres
    ports:
      - "5432:5432"

然后我们需要运行以下命令来首先启动数据库,创建表并用一些数据填充它

# start the database
docker compose up -d

# create the table
docker exec -it stackoverflow-pocs-secondary-db-1 psql postgresql://admin:admin@localhost:5432/postgres -c 'create table dummy_random_data (                                                                                                            ─╯
  id serial not null,
  dummy_string text not null
) ;'

# fill with dummy data
docker exec -it stackoverflow-pocs-secondary-db-1 psql postgresql://admin:admin@localhost:5432/postgres -c 'insert into dummy_random_data(dummy_string) select md5(i::text) from generate_series(1, 100000) s(i);'

最后我们可以运行加特林模拟

sbt Gatling/test

您可以使用不同的 logback 配置多次运行加特林模拟。您应该能够看到每次将根日志级别设置为

TRACE
都会对性能产生一些影响

© www.soinside.com 2019 - 2024. All rights reserved.