Tomcat 下部署若依單體應用可觀測最佳實踐

實現目標

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

版本信息

  • Tomcat (9.0.81)
  • Springboot(2.6.2)
  • JDK (>=8)
  • DDTrace (>=1.0)

特別說明:如果是 Springboot 項目,Tomcat 大版本需與 Springboot 內置的 Tomcat 大版本一致,否則可能會存在啟動異常。

若依的單體應用

  • 下載源碼

若依的單體應用:RuoYi: 🎉 基于SpringBoot的權限管理系統 易讀易懂、界面簡潔美觀。 核心技術采用Spring、MyBatis、Shiro沒有任何其它重度依賴。直接運行即可用 - Gitee.com

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 安裝文檔:主機安裝 - 觀測云文檔

DataKit 開啟 DDTrace 采集器

DDTrace 采集器用于采集應用鏈路信息,參考 DDTrace 采集器接入文檔:DDTrace - 觀測云文檔

DataKit 開啟 Log 采集器

Log 采集器用于采集日志信息,參考 Log 采集器接入文檔:日志采集 - 觀測云文檔

需要調整以下信息:

 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 采集器接入文檔:StatsD - 觀測云文檔

DataKit 開啟 RUM 采集器

RUM 采集器: RUM(Real User Monitor)采集器用于收集網頁端或移動端上報的用戶訪問監測數據。參考RUM 采集器接入文檔:RUM - 觀測云文檔

重啟 DataKit

重啟 DataKit:服務管理 - 觀測云文檔

DDTrace

下載 dd-trace-java,盡量下載最新版本:Releases · GuanceCloud/dd-trace-java · GitHub

創建 RUM

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

Tomcat

下載 Tomcat

下載對應版本的 Tomcat:Apache Tomcat? - Apache Tomcat 9 Software Downloads

配置 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

日志

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

鏈路信息

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

指標信息

RUM 看板

會話重放

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711072.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711072.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711072.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Redis筆記】Redis消息隊列方案

Reids消息隊列&#xff08;Message Queue&#xff09; 消息隊列 是指利用 高效可靠 的 消息傳遞機制 進行與平臺無關的 數據交流&#xff0c;并基于數據通信來進行分布式系統的集成。 消息隊列具有 低耦合、可靠投遞、廣播、流量控制、最終一致性 等功能。 常見的消息隊列 有 …

ensp路由器將不同網絡連通在一起

1.拓撲結構信息如下 二層交換機&#xff1a;lsw2,lsw3,lsw5,lsw6 不進行ip配置&#xff0c;只是定義vlan&#xff0c;和主機標注的保持一致&#xff0c;向下連接pc用access&#xff0c;向上連接路由交換機用trunk lsw2配置信息如下圖 定義vlan&#xff0c;設置各個連接口的方式…

tcpdump 常用用法

簡要記錄下tcpdump用法 監控某個ip上的某個端口的流量 tcpdump -i enp0s25 tcp port 5432 -nn -S 各個參數作用 -i enp0s25 指定抓包的網卡是enp0s25 -nn 顯示ip地址和數字端口 &#xff0c;如果只 -n 則顯示ip&#xff0c;但是端口為services文件中的服務名 如果一個…

用python寫一個自動化部署工具

效果 起因 現在springboot項目的自動化部署已經非常普遍&#xff0c;有用Jenkins的&#xff0c;有用git鉤子函數的&#xff0c;有用docker的…等等。這段時間在玩python&#xff0c;想著用python實現自動化部署&#xff0c;即能鍛煉下編碼能力&#xff0c;又方便運維。于是開始…

每日學習總結20240228

每日總結 20240228 1.獲取系統命令執行結果 #include <stdio.h>#define TRUE 1 #define FALSE 0int get_system_cmd_result(const char *command, char *buffer, int bufferLen) {FILE *pipe popen(command, "r");if (pipe NULL) {return FALSE;}while (f…

HTML-表格、表單和CSS初識,選擇器,書寫規范

&#xff11;. 表格標簽 &#xff11;.&#xff11;創建表格 表格標簽是一種用來處理&#xff0c;顯示表格式數據的常用標簽。 注意&#xff1a; &#xff11;. tr 用于定義表格中的一行&#xff0c;必須嵌套在 table標簽中&#xff0c;在 table中包含幾對 tr&#xff0c;就有…

實用指南:SOLIDWORKS數據失真問題的解決之道

在數據處理和模擬計算的過程中&#xff0c;數據失真是一個常見的挑戰。數據失真指的是由于計算機或人為操作導致的原始數據與計算結果或實際情況之間的偏差。特別是在使用SOLIDWORKS這類工程設計軟件時&#xff0c;數據失真可能由多種因素引起&#xff0c;如軟件版本老舊、設置…

AI大模型-啟航

文章目錄 什么是大模型&#xff1f;&#xff08;大體現在參數量巨大&#xff09;大模型將會改變那些行業&#xff08;大模型有哪些作用&#xff1f;&#xff09;如何搞數據訓練模型&#xff1f;LangChain帶來的技術變革LangChain架構 什么是大模型&#xff1f;&#xff08;大體…

九、GG bond的邏輯運算

描述 GG bond想要鍛煉自己的邏輯能力&#xff0c;于是輸入了兩個整型變量x和y&#xff0c;分別判斷它們的與、或、非關系&#xff0c;你能幫他輸出x與y&#xff0c;x或y&#xff0c;非x&#xff0c;非y的值嗎&#xff1f; 輸入描述&#xff1a; 輸入兩個整數x和y&#xff0c…

Vue+SpringBoot打造不良郵件過濾系統

目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊2.1 系統用戶模塊2.2 收件箱模塊2.3 發件箱模塊2.4 垃圾箱模塊2.5 回收站模塊2.6 郵箱過濾設置模塊 三、實體類設計3.1 系統用戶3.2 郵件3.3 其他實體 四、系統展示五、核心代碼5.1 查詢收件箱檔案5.2 查詢回收站檔案5.3 新…

Linux學習-etcdctl安裝

etcdctl3.5下載鏈接 1. 先通過上面鏈接下載gz包2. 解壓 [rootk8s-master ~]# tar xf etcd-v3.5.11-linux-amd64.tar.gz [rootk8s-master etcd-v3.5.11-linux-amd64]# ls Documentation etcd etcdctl etcdutl README-etcdctl.md README-etcdutl.md README.md READMEv2-e…

圖像分割 - 查找圖像的輪廓(cv2.findContours函數)

1、前言 輪廓,是指圖像中或者物體的外邊緣線條。在簡單的幾何圖形中,圖形的輪廓是由平滑的線條構成,容易被識別。但不規則的圖形或者生活中常見的物體輪廓復雜,識別起來比較困難 2、findContours函數 這里先介紹函數的參數,具體的含義會在下面實驗中闡述 opencv 提供的輪…

『大模型筆記』自用的“科技文章翻譯 GPT”和它的 Prompt

自用的“科技文章翻譯 GPT”和它的 Prompt 你是一位精通簡體中文的專業翻譯,尤其擅長將專業學術論文翻譯成淺顯易懂的科普文章。請你幫我將以下英文段落翻譯成中文,風格與中文科普讀物相似。規則: - 翻譯時要準確傳達原文的事實和背景。 - 即使上意譯也要保留原始段落格式,…

每天一個數據分析題(一百八十四)

在下列哪種情況下線性回歸模型不適合代替邏輯回歸模型&#xff1f; A. 預測的目標變量是連續型的并且分布范圍不受限制 B. 預測的目標變量是二元的并且服從二項分布 C. 自變量與因變量之間的關系可以假設為線性關系 D. 需要預測客戶的具體購買金額 題目來源于CDA模擬題庫 …

React入門之React_渲染基礎用法和class實例寫法

渲染元素 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>04元素渲染</title><script src&…

什么是RPC?談談你對RPC的理解

RPC&#xff08;Remote Procedure Call&#xff0c;遠程過程調用&#xff09;是一種計算機通信協議。它允許一臺計算機&#xff08;客戶端&#xff09;通過網絡調用另一臺計算機&#xff08;服務器&#xff09;上的程序&#xff0c;并等待該程序的結果返回。RPC抽象了網絡通信的…

go mod中如何解決 xxx/yyy/lib@v1.1.0: unrecognized import path

需要檢查的幾個地方 這個錯誤通常出現在 Go 模塊系統無法找到指定版本的模塊時。有幾種可能的原因和解決方法&#xff1a; 模塊未被發布或標記&#xff1a; 確保 xxx/yyy/lib 模塊的版本 v1.1.0 已經被正確地發布或標記。你可以在對應的 GitLab 倉庫中查看是否存在 v1.1.0 標簽…

2024-2-29-網絡編程作業

1>TCP 源代碼: 服務器端&#xff1a; #include <myhead.h> #define SER_IP "10.168.1.111" #define SER_PORT 8888 #define MAXSIZE 128 int main(int argc, char const *argv[]) {int sfd socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in sin;sin…

代碼隨想錄算法訓練營|day47

第九章 動態規劃 198.打家劫舍213.打家劫舍II337.打家劫舍III代碼隨想錄文章詳解 198.打家劫舍 dp[i]表示偷第i家及之前所能獲取的最大金額 偷第i家&#xff1a;dp[i] dp[i-2]nums[i]&#xff0c;不偷第i家&#xff1a;dp[i] dp[i-1] func rob(nums []int) int {if len(num…

RDD簡介與基礎編程

1. 什么是RDD&#xff1f; RDD&#xff08;Resilient Distributed Dataset&#xff09;叫做彈性分布式數據集&#xff0c;是Spark中最基本的數據處理模型。在代碼中&#xff0c;RDD是一個抽象類&#xff0c;他代表著一個彈性的、不可變的、可分區的、里面的元素可并行計算的集…