动态

详情 返回 返回

Tomcat 下部署若依單體應用可觀測最佳實踐 - 动态 详情

實現目標

  • 採集指標信息
  • 採集鏈路信息
  • 採集日誌信息
  • 採集 RUM 信息
  • 會話重放 即用户訪問前端的一系列過程的會話錄製信息,包括點擊某個按鈕、操作界面、停留時間等,有助於客户真是意圖、操作復現

版本信息

  • Tomcat (9.0.81)
  • Springboot(2.6.2)
  • JDK (>=8)
  • DDTrace (>=1.0)
特別説明:如果是 Springboot 項目,Tomcat 大版本需與 Springboot 內置的 Tomcat 大版本一致,否則可能會存在啓動異常。

若依的單體應用

  • 下載源碼

若依的單體應用:https://gitee.com/y_project/RuoYi/tree/master

git clone https://gitee.com/y_project/RuoYi.git
  • 移除內部 tomcat

調整項目根目錄的 pom.xml

......
    <dependencyManagement>
        <dependencies>

            <!-- SpringBoot的依賴配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.5.15</version>
                <type>pom</type>
                <scope>import</scope>
                <!-- 移除內部 tomcat -->
                <exclusions>
                    <exclusion>
                        <artifactId>spring-boot-starter-tomcat</artifactId>
                        <groupId>org.springframework.boot</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
......
  • war 輸出

調整 ruoyi-admin 模塊下的 pom.xml 文件

<packaging>war</packaging>
  • 調整日誌

ruoyi-admin/src/main/resources 新增 logback-spring.xml,原文如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日誌存放路徑 -->
    <property name="log.path" value="/home/root/ruoyi/logs" />
    <!-- 日誌輸出格式 -->
    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - [%method,%line] %X{dd.service} %X{dd.trace_id} %X{dd.span_id} - %msg%n" />

    <!-- 控制枱輸出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 系統日誌輸出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!-- 循環政策:基於時間創建日誌文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日誌文件名格式 -->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日誌最大的歷史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 過濾的級別 -->
            <level>INFO</level>
            <!-- 匹配時的操作:接收(記錄) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配時的操作:拒絕(不記錄) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-error.log</file>
        <!-- 循環政策:基於時間創建日誌文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日誌文件名格式 -->
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日誌最大的歷史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 過濾的級別 -->
            <level>ERROR</level>
            <!-- 匹配時的操作:接收(記錄) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配時的操作:拒絕(不記錄) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 用户訪問日誌輸出  -->
    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-user.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滾 daily -->
            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日誌最大的歷史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 系統模塊日誌級別控制  -->
    <logger name="com.ruoyi" level="info" />
    <!-- Spring日誌級別控制  -->
    <logger name="org.springframework" level="warn" />

    <root level="info">
        <appender-ref ref="console" />
    </root>

    <!--系統操作日誌-->
    <root level="debug">
        <appender-ref ref="file_info" />
        <appender-ref ref="file_error" />
    </root>

    <!--系統用户操作日誌-->
    <logger name="sys-user" level="info">
        <appender-ref ref="sys-user"/>
    </logger>
</configuration> 
  • 編譯

進入項目根目錄執行以下命令進行編譯:

mvn clean package

如果沒有安裝 Maven,則需要先安裝 Maven 再進行編譯。

[INFO] --- spring-boot:2.5.15:repackage (default) @ ruoyi-admin ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for ruoyi 4.7.7:
[INFO] 
[INFO] ruoyi .............................................. SUCCESS [  0.179 s]
[INFO] ruoyi-common ....................................... SUCCESS [  4.622 s]
[INFO] ruoyi-system ....................................... SUCCESS [  0.770 s]
[INFO] ruoyi-framework .................................... SUCCESS [  0.950 s]
[INFO] ruoyi-quartz ....................................... SUCCESS [  0.388 s]
[INFO] ruoyi-generator .................................... SUCCESS [  0.378 s]
[INFO] ruoyi-admin ........................................ SUCCESS [  4.554 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  12.287 s
[INFO] Finished at: 2023-10-13T16:30:12+08:00
[INFO] ------------------------------------------------------------------------

DataKit

  • 安裝 DataKit
  • 開啓採集器

安裝 DataKit

參考 DataKit 安裝文檔:https://docs.guance.com/datakit/datakit-install/

DataKit 開啓 DDTrace 採集器

DDTrace 採集器用於採集應用鏈路信息,參考 DDTrace 採集器接入文檔:https://docs.guance.com/integrations/ddtrace/

DataKit 開啓 Log 採集器

Log 採集器用於採集日誌信息,參考 Log 採集器接入文檔:https://docs.guance.com/integrations/logging/

需要調整以下信息:

 logfiles = [
    "/home/liurui/ruoyi/logs/*.log",
  ]
  ## Add service tag, if it's empty, use $source.
  service = "ruoyi"

  ## Grok pipeline script name.
  pipeline = "ruoyi.p"
  • logfiles:需要採集的日誌文件路徑
  • service: 服務名稱
  • pipeline: 日誌解析

Pipeline 配置

Pipeline 用於數據治理,這裏主要是將日誌信息進行提取,以便與鏈路信息關聯。

datakit/pipeline/ 目錄下創建 ruoyi.p 文件,內容如下:

grok(_, "%{TIMESTAMP_ISO8601:time} %{NOTSPACE:thread_name} %{LOGLEVEL:status}%{SPACE}%{NOTSPACE:class_name} - \\[%{NOTSPACE:method_name},%{NUMBER:line}\\] %{DATA:service_name2} %{DATA:trace_id} %{DATA:span_id} - %{GREEDYDATA:msg}")

default_time(time,"Asia/Shanghai")

DataKit 開啓 StatsD 採集器

StatsD 採集器用於採集指標信息,參考StatsD 採集器接入文檔:https://docs.guance.com/integrations/statsd/

DataKit 開啓 RUM 採集器

RUM 採集器: RUM(Real User Monitor)採集器用於收集網頁端或移動端上報的用户訪問監測數據。參考RUM 採集器接入文檔:https://docs.guance.com/integrations/rum/

重啓 DataKit

重啓 DataKit:https://docs.guance.com/datakit/datakit-service-how-to/#manag...

DDTrace

下載 dd-trace-java,儘量下載最新版本:https://github.com/GuanceCloud/dd-trace-java/releases

創建 RUM

  • 登陸觀測雲
  • 選擇 用户訪問檢測,選擇 應用列表,點擊 新建應用
  • 應用名稱 填寫 ruoyi-admin應用 ID 可以自定義,也可以點擊 隨機生成 按鈕
  • 應用類型 選擇 web,右邊 SDK 配置 有幾個類型,這裏我們選擇 CDN 同步載入複製對應的腳本內容,後續會用到
  • 點擊 創建 按鈕,完成創建。

Tomcat

下載 Tomcat

下載對應版本的 Tomcat:https://tomcat.apache.org/download-90.cgi

配置 DDTrace

在 Tomcat bin 目錄下新增腳本 setenv.sh 文件。

export CATALINA_OPTS="-javaagent:/home/root/agent/dd-java-agent-1.14.0-guance.jar \
                      -Ddd.tags=env:test \
                      -Ddd.jmxfetch.enabled=true \
                      -Ddd.jmxfetch.statsd.host=localhost \
                      -Ddd.jmxfetch.statsd.port=8125 \
                      -Ddd.jmxfetch.tomcat.enabled=true\
                      -Dlogging.config=classpath:logback-spring.xml"
  • javaagent: 指定 ddtace 目錄
  • Dlogging.config: 指定應用的日誌以 logback 日誌輸出。如果應用內部使用的是 log4j,指定對應的文件即可。

部署應用

將已經打包好的應用 RuoYi/ruoyi-admin/target/ruoyi-admin.war 複製到 Tomcat 的 webapps 下。

啓動 Tomcat

執行 bin/startup.sh

apache-tomcat-9.0.81/bin$ ./startup.sh 
Using CATALINA_BASE:   /home/root/middleware/apache-tomcat-9.0.81
Using CATALINA_HOME:   /home/root/middleware/apache-tomcat-9.0.81
Using CATALINA_TMPDIR: /home/root/middleware/apache-tomcat-9.0.81/temp
Using JRE_HOME:        /home/root/middleware/jdk/jdk-11.0.18
Using CLASSPATH:       /home/root/middleware/apache-tomcat-9.0.81/bin/bootstrap.jar:/home/root/middleware/apache-tomcat-9.0.81/bin/tomcat-juli.jar
Using CATALINA_OPTS:   -javaagent:/home/root/agent/dd-java-agent-1.14.0-guance.jar                       -Ddd.tags=env:test                       -Ddd.jmxfetch.enabled=true                       -Ddd.jmxfetch.statsd.host=localhost                       -Ddd.jmxfetch.statsd.port=8125                       -Ddd.jmxfetch.tomcat.enabled=true                      -Dlogging.config=classpath:logback-spring.xml
Tomcat started.

加入 RUM

Tomcat 啓動完成後,自動解壓 war 應用,進入到 /webapps/ruoyi-admin/WEB-INF/classes/templates 目錄下,調整 include.html,將上一步複製的腳本代碼粘貼到 head

<head th:fragment=header(title)>
...
<script src="https://static.guance.com/browser-sdk/v3/dataflux-rum.js" type="text/javascript"></script>
<script>
  window.DATAFLUX_RUM &&
    window.DATAFLUX_RUM.init({
      applicationId: 'APP_ID',
      datakitOrigin: 'http://localhost:9529', // 協議(包括://),域名(或IP地址)[和端口號]
      env: 'production',
      version: '1.0.0',
      service: 'browser',
      sessionSampleRate: 100,
      sessionReplaySampleRate: 70,
      trackInteractions: true,
      traceType: 'ddtrace', // 非必填,默認為ddtrace,目前支持 ddtrace、zipkin、skywalking_v3、jaeger、zipkin_single_header、w3c_traceparent 6種類型
      allowedTracingOrigins: ['http://localhost:8080','http://localhost:8080/ruoyi-admin'],  // 非必填,允許注入trace採集器所需header頭部的所有請求列表。可以是請求的origin,也可以是是正則
    });
    window.DATAFLUX_RUM && window.DATAFLUX_RUM.startSessionReplayRecording()
</script>
...
</head>
  • applicationId:複製過來的就不需要調整。
  • datakitOrigin: 用於接收 RUM 數據上報的 DataKit 地址
  • allowedTracingOrigins: 與後端 APM 串聯,前端調用 API 接口,會在對應的接口新增 Trace 所需的 Header 信息

效果

訪問 http://localhost:8080/ruoyi-admin,默認用户名:admin,密碼:admin123

1

日誌

2

進入日誌詳情,可以查看到當前日誌對應的鏈路信息

3

鏈路信息

4

也可以通過鏈路查看日誌和指標信息

5

指標信息

6

RUM 看板

7

會話重放

8

Add a new 评论

Some HTML is okay.