JVM進階(七)——從GC日志分析堆內存
751
2025-03-31
論文系統(tǒng)Step1:從日志記錄中提取特定信息
前言
論文數(shù)據(jù)需要,需要實現(xiàn)從服務器日志中提取出用戶的特定交互行為信息。日志內容如下:
自己需要獲取“請求數(shù)據(jù)包一行的信息”及“OUTSTR”下一行的信息。
思路
考慮使用正則表達式提取特定信息。
示例代碼:
Pattern pattern = Pattern.compile("請求數(shù)據(jù)包信息:\"(.+?)\"");
Matcher matcher = pattern.matcher("請求數(shù)據(jù)包信息:\"index.html\"");
if(matcher.find())
System.out.println(matcher.group(1));
考慮到日志中數(shù)據(jù)格式特點,利用上述方式并不可行。不過還是應該考慮使用正則解決以上問題。
初步處理后的文檔內容如下:
分析以上信息,需要進一步進行處理,將每個用戶的信息進行單獨抽取并存入到數(shù)據(jù)庫中。 作為實驗,先單獨獲取一用戶的數(shù)據(jù)。但是由于服務端返回數(shù)據(jù)無任何用戶標識,而且返回信息無任何交易標識,仍需添加。需要對日志做進一步的處理操作。添加信息如下:
通過將json格式的字符串轉換為json對象。并獲取到指定信息,如下所示:
為了提取出每個用戶的交互序列,實現(xiàn)方法如下:將日志中的交互序列按照用戶ID分別建立相應的文件夾。將同一用戶的請求與輸出信息輸出到同一用戶ID的文件內。內容如下:
文件內容如下:
通過分析分類后的文件內容,可以發(fā)現(xiàn),由于存在某些耗時交易,故會出現(xiàn)多個請求、輸出交叉顯示的情況。
針對這種情況,在服務端返回信息中加入了uid,tx_code信息,如下所示:
那么就需要將服務端返回信息與請求信息進行配對操作。
考慮到交易的混合,服務端返回信息的混合,必須假設一種理想情況之下的處理。否則,處理起來過于費勁。
前提:客戶端的請求與服務端的響應按照線性順序出現(xiàn),一一對應。
Ti、To到底存放什么類型的數(shù)據(jù)?Json中的key還是json對象?
只是單純存儲key的話,Ti、To基本上毫無用處,無法完成基于內容的行為預測與預警。
存儲json對象的話,數(shù)據(jù)量會非常龐大,應給與調整。到底應該進行怎樣的數(shù)據(jù)調整?只提取“重點信息”。例如交易金額,藥品種類。
還是應該結合系統(tǒng)說明文檔來做,將事件的輸入、輸出自動添加進(重點考慮輸入輸出內容)。
這樣問題的思路就很清晰了。
考慮將交易時間寫入數(shù)據(jù)表中,便于得出交易序列。同時可考慮將時間因素添加進去,做服務推薦(協(xié)同過濾,加入時間維度)。例如:在什么時間購買了什么藥品,可得出在這一時間段內該用戶易的某種疾病的推測。
日志信息的篩選:對于用戶行為序列中只存在一個事件的情況可考慮忽略不計。對于分析用戶的習慣無用。
獲取到指定信息后,需要將其存入數(shù)據(jù)庫中。數(shù)據(jù)表內容如下:
1.靜態(tài)屬性表(lab_static_attribute)
表名:lab_static_attribute
主鍵:uid,login_time,out_time,last_time
字段名
中文名
類型
備注
uid
用戶ID
Varchar(11)
uid
login_time
登陸時間
Varchar(1)
0 ??24:00-1:00
1 ??1:00-2:00
2 ??2:00-3:00
.
.
23 ?23:00-24:00
out_time
登出時間
Varchar(1)
0 ??24:00-1:00
1 ??1:00-2:00
2 ??2:00-3:00
.
.
23 ?23:00-24:00
last_time
在線時長
Int(3)
以秒為單位
2.動態(tài)序列表(lab_dynamic_order)
表名:lab_dynamic_order
主鍵:uid,tid,t_next
字段名
中文名
類型
備注
uid
用戶ID
Varchar(11)
uid
tid
事務ID
Varchar(4)
ti
輸入?yún)?shù)
Varchar(50)
tout
輸出結果
Varchar(50)
t_next
路由下一跳
Varchar(4)
下一個可執(zhí)行路由
weight
路由權重
Int(3)
每條路由之間的權重
t_time
交易時間
Varchar(19)
接下來的工作就是建立數(shù)據(jù)庫,并實現(xiàn)數(shù)據(jù)庫的操作。
好長時間不涉及到數(shù)據(jù)庫的操作了,發(fā)覺自己已經(jīng)變得生疏了。還得拾起來啊。
PS:中間出了點問題,令自己很是頭痛。由于數(shù)據(jù)庫的操作包括肯定會涉及到增刪改查,所以自己的方法得更改一下了,但是直接使用“立馬送藥”項目的數(shù)據(jù)庫操作方法時,卻出現(xiàn)了數(shù)據(jù)表只能讀,不能寫的狀況。自己需要一步步的排查問題,看看使用lmapp的數(shù)據(jù)表是否可以使用。
經(jīng)過閱讀“立馬送藥”中數(shù)據(jù)庫操作的有關代碼,自己還是發(fā)現(xiàn)了一些端倪。MyDatabase.commit();這句意味深長。在操作之后添加這句后,居然就可以往數(shù)據(jù)庫中寫數(shù)據(jù)了。
通過實際操作,實現(xiàn)了數(shù)據(jù)庫的連接及新增Demo操作。接下來就需要將提取到的真實數(shù)據(jù)寫進數(shù)據(jù)庫存儲。
關于數(shù)據(jù)表lab_dynamic_order中ti與tout的存儲內容問題探討
首先注意到各交易的輸入、輸出參數(shù)的鍵是不同的,所以不可能在數(shù)據(jù)表中以字段形式展現(xiàn),而是應該整體存儲在數(shù)據(jù)表內。結合以下用戶日志信息分析。
可得相應信息如下表所示,時間因素已在數(shù)據(jù)表中記錄,故輸入?yún)?shù)ti中不再體現(xiàn)。
tid
ti
tout
9015
{“stat”:“1”}
{“cnt”:0}
9101
{null}
{"data":[{"advid":"2","url":"AngularJSunny.jpg"},...,{"advid":"5","url":"VIP.jpg"}]}
9104
{“version”:“1.2”}
{"errtext":"當前已是最新版本"}
receiver:{"old_billid":"","addrid":"6","shopid":"S18853883587","msg":"","yhhdid":"YH00000019","yhhdamt":2,"yhqid":"","yhqcnt":0,"yhqamt":0,"cnt":1,"meddata":[{"medid":"TH20013063","medcnt":1,"cfid":""}],"version":"1.0","fore_time":"2016-03-18 15:53:06","uid":"18353102068","tx_code":"3002"}
剛才在手機端模擬了用戶操作,明天記得將2016-05-16的日志提取出來。
通過再一次分析日志,發(fā)現(xiàn)自己的篩選方法存在問題。應該以“receiver:”開頭的字符串作為輸入?yún)?shù)的提取點。
以用戶軌跡為線索,用戶軌跡行為如下:
登錄(1002)-->搜索藥品(9002)-->選擇地址(1004)-->提交訂單(3002)
tid
ti
tout
1002
{“phone”:“18353102068”}
{“result”:登陸結果}
9002
{“classid”:分類編號}
{“pcnt”:返回數(shù)量}
9005
{“shopid”:藥店編號}
{“pcnt”:返回數(shù)量}
9101
{null}
{“data”:廣告詳情}
9103
{“advid”:廣告編號}
{“url”:廣告鏈接}
1004
{null}
{"addrs":[{"receiver":"孫華強","tel":"18853883586","addr":"北京市北京市朝陽區(qū)112號","addrid":1}]}
3002
{"old_billid":"","addrid":"1","shopid":"S18853883587","msg":"","yhhdid":"YH00000019","yhhdamt":2,"yhqid":"","yhqcnt":0,"yhqamt":0,"cnt":4,"meddata":[{"medid":"TH20013063","medcnt":1,"cfid":""},{"medid":"TZ44021940","medcnt":1,"cfid":""},{"medid":"TH10940251","medcnt":1,"cfid":""},{"medid":"TB20020918","medcnt":1,"cfid":""}]
{"billid":"LM201605163586476"}
注意其中的輸入輸出參數(shù)是經(jīng)過篩選之后提取出來的。為此需要寫一個工具類,用來提取特定的輸入輸出參數(shù)。
測試情景1:
輸入:整理后的單用戶日志
18353102068:1002-->9002-->9002-->9002-->9005-->1004-->3002
輸出:靜態(tài)統(tǒng)計表、動態(tài)統(tǒng)計表
測試情景2:
輸入:整理后的多用戶日志
18353102068:1002-->9002-->9002-->9002-->9005-->1004-->3002
18353102066:1002-->9002-->9005-->1004-->3002
輸出:靜態(tài)統(tǒng)計表、動態(tài)統(tǒng)計表
測試情景3:
輸入:整理后的包含匿名用戶日志
18353102068:1002-->9002-->9002-->9002-->9005-->1004-->3002
18353102066:1002-->9002-->9005-->1004-->3002
$tempuser:9002-->9005-->9101-->9103
輸出:靜態(tài)統(tǒng)計表、動態(tài)統(tǒng)計表
測試情景4:
輸入:整理后的交叉請求案例日志
輸出:靜態(tài)統(tǒng)計表、動態(tài)統(tǒng)計表
測試情景5:
輸入:整理后的單用戶多階段日志
注:測試需在case長度至少為2的情況下進行。
18353102068:1002-->9002-->9002
18353102068:1002
輸出:靜態(tài)統(tǒng)計表、動態(tài)統(tǒng)計表
測試情景6:
輸入:整理后的多用戶多階段日志
注:測試需在case長度至少為2的情況下進行。
18353102068:1002(2016-05-16 11:27:45)-->9002-->9002(2016-05-16 11:27:47)
18353102066:1002(2016-05-16 12:27:45)-->1004-->3002(2016-05-16 12:37:54)
18353102068:1002(2016-05-17 11:27:45)
-->9002-->9002-->9002-->9005-->1004-->3002(2016-05-17 11:27:54)
18353102066:1002(2016-05-17 11:27:45)
-->9002->9005-->1004-->3002(2016-05-17 11:27:54)
輸出:靜態(tài)統(tǒng)計表、動態(tài)統(tǒng)計表
測試情景7:
輸入:整理后的包含匿名用戶多階段日志
注:測試需在case長度至少為2的情況下進行。
1.18353102068:1002(2016-05-16 11:27:45)-->9002-->9002(2016-05-16 11:27:47)
2.18353102066:1002(2016-05-16 12:27:45)-->1004-->3002(2016-05-16 12:37:54)
3.18353102068:1002(2016-05-17 11:27:45)
-->9002-->9002-->9002-->9005-->1004-->3002(2016-05-17 11:27:54)
4.18353102066:1002(2016-05-17 11:27:45)
-->9002->9005-->1004-->3002(2016-05-17 11:27:54)
5.$tempuser:9002(2016-05-17 11:35:54)-->9005-->9101-->9103(2016-05-17 11:39:54)
6.18353102066:1002(2016-05-17 12:27:45)-->1004-->3002(2016-05-17 12:37:54)
7.$tempuser:9002(2016-05-17 12:35:54)-->9101-->9103(2016-05-17 12:39:54)
輸出:靜態(tài)統(tǒng)計表、動態(tài)統(tǒng)計表
測試情景8:
輸入:實際用戶日志
問題
查看日志內容:
receiver:{"version":"1.0","fore_time":"2016-05-16 20:21:04","uid":"$tempuser","tx_code":"1001"}
receiver:{"version":"1.0","fore_time":"2016-05-16 20:21:22","uid":"$tempuser","tx_code":"1002"}
實際日志中居然出現(xiàn)了上面的請求信息。1001為注冊交易應該對應參數(shù)“phone”和“passwd”,但請求中并未包含,這是什么原因?
交易1001(注冊)、1002(登錄)均涉及到加密傳輸,在邏輯上可以解釋以上現(xiàn)象。移動端1001(注冊交易)代碼如下:
var data = {};
appCallServer($http, "1001", data, function(data) {
$ionicLoading.hide();
var key = data.publickey;
// 在此調用測試加密
var passwd = password; // 用戶密碼提交至此
data = {
"phone": phonenum, // 用戶名提交至此
"passwd": MyRsaEncrypt(key, passwd)
};
appCallServer($http, "1001", data, function(data) {
if (data.result == "0000") {
$ionicLoading.show({
template: "注冊成功"
});
$timeout(function() {
$ionicLoading.hide();
$scope.gotoLogin(phonenum, password);
}, 1000);
}
});
}, function(data) {
$ionicLoading.show({
template: data.errtext
});
$timeout(function() {
$ionicLoading.hide();
}, 1000);
});
客戶端實現(xiàn)的業(yè)務邏輯是首先調用一次1001(此次請求參數(shù)為空),獲取到服務端返回的公鑰后,利用此公鑰對用戶所輸入的密碼進行加密操作。再次調用1001(此次請求參數(shù)為phone,passwd),完成用戶的注冊。1002邏輯同此。至此,以上問題得到了解釋。
為此,通過更改服務端邏輯:在1001,1002調用之前使用0000獲取公鑰,這樣就符合了自己的篩選規(guī)則:去除0000。
if(b.contains("result") && !"0000".equals(tx_code)){....}
整理后的日志中不會再出現(xiàn)1001、1002均不會存在不存在“phone”參數(shù)的現(xiàn)象。
注:在進行實際日志測試的時候遇到了瓶頸,交易紊亂,輸入輸出紊亂問題尤為突出。難道是生成日志方式有問題?
$tempuser:1001(2016-05-16 20:21:04)-->9101-->9103(2016-05-17 12:39:54)
18353102068:9104(2016-05-16 11:27:10)-->9101-->9002(2016-05-16 11:27:47)
輸出:靜態(tài)統(tǒng)計表、動態(tài)統(tǒng)計表
未完待續(xù).....
參考文獻
1.
http://blog.csdn.net/sunhuaqiang1/article/details/47169913
2.
http://www.bejson.com/
美文美圖
JSON 數(shù)據(jù)庫
版權聲明:本文內容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內刪除侵權內容。
版權聲明:本文內容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內刪除侵權內容。