【阿里云MVP月度分享】SaaS服务商如何通过数加平台统计业务流量
摘要: 一、概述 因為自家公司是做B2B類Saas服務的,難免會產生精準計費的問題,所以在通過多套方案的選型及對比以后,我們最終確定了以下的方式進行自有業務平臺的流量計算方案。因為涉及到具體的操作,所以閱讀本文的前提是我默認您已經具備了阿里云相關產品的使用經驗。
一、概述
因為自家公司是做B2B類Saas服務的,難免會產生精準計費的問題,所以在通過多套方案的選型及對比以后,我們最終確定了以下的方式進行自有業務平臺的流量計算方案。因為涉及到具體的操作,所以閱讀本文的前提是我默認您已經具備了阿里云相關產品的使用經驗。
目前的流量構成主要為:
1.用戶訪問業務平臺產品的頁面響應流量,即http返回頁面的大小。
2.用戶訪問業務平臺中圖片所產品的流量,所有的圖片存放在OSS中,通過CDN暴露在公網訪問。
3.用戶的API請求產生的響應流量,即Json返回值頁面的大小。
我們的目標:
1.我們的計費顆粒為按天計算,所以我們只需要確保第二天能得到前一天的流量數據即可。對實時性的要求不是那么的高。
2.需要所有的數據都參與運算,并且能支持多渠道的日志來源。
3.需要支持重新計算,有些時候因為一些特定原因,需要重新獲取某個時間段的流量數據,需要得到和之前一致的數據結果(前提是原始日志相同的情況下)。
4.不能產生大量成本,最好是不要購買服務器,不要進行太大的支出。
5.所有流量計算出的結果,按年、月、日、時存入Mysql數據庫,便于實時查表顯示給客戶。
二、流量統計流程
三、獲取訪問日志
目前所有的訪問都基于HTTP展開,那么無論是apache還是nginx都是自帶訪問日志功能的,只需要把這些文本日志清洗一下存到數據庫就行了,或者有更簡單的方式,將這些日志通過阿里云的日志服務收集起來,然后定時投遞到數加的ODPS表里即可。
這里給一個日志服務的傳送門:https://www.aliyun.com/product/sls
相對于自己收集日志并清洗,我還是更加建議使用阿里云的日志服務,查詢快且穩定、收費也低、客戶支持力度很棒、迭代速度很快。
值得一提的是,數加平臺支持一鍵導入CDN日志,如果你的業務恰恰好是全CDN加速的,那么你只需要收集CDN日志就可以進行較為精準的流量統計了。
我們收集到的訪問日志格式大概是這樣的:
[12/Nov/2017:00:09:15 +0800] 112.28.172.8 - 0 “http://www.xxx.com/Article/86892.html” “GET http://www.xxx.com/Public/css/style.css” 200 393 21427 HIT “Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36” “text/css”
分割后按順序分別是:時間,訪問IP,代理IP,responsetime,referer,method,訪問URL,httpcode,requestsize,responsesize,cache命中狀態,UA頭,文件類型。
其中最重要的就是2個字段:URL、responsesize。
URL字段是整個訪問的URL路徑,可以用于分析文件類型和客戶平臺。
Responsesize是指整個請求響應的數據大小。
你也可以結合httpcode和緩存命中來進行更精準的計算,我下面的介紹不涉及這一塊內容,一通百通,明白后自己調整一下ODPS的SQL語句就行了。
日志導入ODPS
如果我們需要將日志數據導入到ODPS中,那么需要完成ODPS表的創建,這一塊進入到數加平臺即可完成,與我們平時開發中創建MYSQL、MSSQL表的方式差不多,只是有些數據類型上的差異。同時ODPS表也支持了一個很重要也很有用的概念——分區。
你可以在創建ODPS表的時候,指定一個或多個字段來對某一些數據進行分區,常見的就是按時間分區,比如日志時間格式化到小時級別用作分區,這樣就能把某個小時的數據置入特定分區。設置分區的目的主要是在后期運算、覆寫、重跑時更便利。
那么日志導入到ODPS的方式有幾種:
1.如果你的日志在阿里云日志服務中,直接配置一下ODPS投遞即可,具體查詢文檔還是比較簡單的,就不啰嗦了。
2.如果你的日志數據在自建系統中,那么可以考慮使用“數加平臺的-數據集成”功能來完成數據的導入和同步,支持的數據庫種類超級多,具體請看文檔:https://help.aliyun.com/document_detail/53008.html ,市面上90%的數據庫都支持的。
此處我們得到一個ODPS數據表名為:cdn_logs,里面存放的是所有的cdn訪問日志,名字只是演示,你可以自定義。我的建表語句是這樣的:
CREATE TABLE cdn_logs (
station_node STRING COMMENT ‘節點’,
unix_time BIGINT COMMENT ‘訪問時間’,
method STRING COMMENT ‘請求方法’,
procotol STRING COMMENT ‘請求協議’,
domain STRING COMMENT ‘域名’,
uri STRING COMMENT ‘請求的uri’,
uri_parameter STRING COMMENT ‘請求參數’,
imgsrc_type BIGINT COMMENT ‘圖片壓縮類型ID’,
return_code BIGINT COMMENT ‘返回碼’,
rt BIGINT COMMENT ‘延時’,
request_size BIGINT COMMENT ‘請求大小’,
response_size BIGINT COMMENT ‘響應大小’,
hit_info STRING COMMENT ‘命中信息’,
client_ip BIGINT COMMENT ‘真實用戶IP’,
proxy_ip STRING COMMENT ‘中間代理ip’,
remote_address BIGINT COMMENT ‘客戶端IP’,
bacend_server STRING COMMENT ‘回源IP’,
refer_procotol STRING COMMENT ‘引用協議’,
refer_domain STRING COMMENT ‘引用域名’,
refer_uri STRING COMMENT ‘引用uri’,
refer_parameter STRING COMMENT ‘引用參數’,
content_type STRING COMMENT ‘請求返回類型’,
user_agent STRING COMMENT ‘UA’,
port BIGINT COMMENT ‘客戶端口’,
transfer_success BIGINT COMMENT ‘傳輸是否成功’,
last_modify STRING COMMENT ‘服務器上文件的最后修改時間’,
user_info STRING COMMENT ‘用戶信息’,
traceid STRING COMMENT ‘訪問錯誤排查跟蹤id’,
sent_http_via STRING COMMENT ‘http via頭’,
reserve_1 STRING COMMENT ‘保留字段1’,
reserve_2 STRING COMMENT ‘保留字段2’,
reserve_3 STRING COMMENT ‘保留字段3’
)
PARTITIONED BY (
log_date STRING COMMENT ‘日期分區’,
domain_id BIGINT COMMENT ‘ID分區’
)
LIFECYCLE 100000;
四、進行離線計算任務配置
我們已經擁有了一個基礎數據表:cdn_logs,在此之外我們還需要創建2個表,分別為:
cdn_logs_format表——對cdn_logs表進行格式化后得到的進一步清洗數據,此處需要貼近業務進行各種DIY操作,這個表的生命周期建議是參考自己的日志量來規劃,如果日志少,就設為永久,否則設置成周期。建表語句如下:
CREATE TABLE cdn_logs_format (
unix_time BIGINT COMMENT ‘訪問時間’,
uri_parent STRING COMMENT ‘首層目錄名’,
method STRING COMMENT ‘請求方法’,
procotol STRING COMMENT ‘請求協議’,
domain STRING COMMENT ‘域名’,
uri STRING COMMENT ‘請求的uri’,
return_code BIGINT COMMENT ‘返回碼’,
rt BIGINT COMMENT ‘延時’,
response_size BIGINT COMMENT ‘響應大小’,
client_ip BIGINT COMMENT ‘真實用戶ip’,
remote_address BIGINT COMMENT ‘客戶端ip’,
bacend_server STRING COMMENT ‘回源ip’,
refer_domain STRING COMMENT ‘引用域名’,
refer_uri STRING COMMENT ‘引用uri’,
content_type STRING COMMENT ‘請求返回類型’,
user_agent STRING COMMENT ‘ua’
)
PARTITIONED BY (
log_date STRING COMMENT ‘日期分區’
)
LIFECYCLE 100000;
aggr_product_traffic表——最終的流量統計結果表,這個表結果少,建議生命周期永久,建表語句:
CREATE TABLE aggr_product_traffic (
clientcode STRING COMMENT ‘客戶端代碼’,
year BIGINT COMMENT ‘年’,
month BIGINT COMMENT ‘月’,
day BIGINT COMMENT ‘日’,
hour BIGINT COMMENT ‘小時’,
mi BIGINT COMMENT ‘分鐘’,
traffic BIGINT COMMENT ‘流量’,
create_at BIGINT COMMENT ‘創建匯總時的時間戳’,
targetdate STRING COMMENT ‘匯總結果時間’
)
COMMENT ‘產品流量匯總表’
PARTITIONED BY (
aggr_date STRING COMMENT ‘分區時間’,
product STRING COMMENT ‘產品代碼’
)
LIFECYCLE 100000;
把準備工作準備完成后,我們需要在數加里配置對應的離線任務,在配置離線任務之前可以使用數加的“數據開發IDE”進行試驗,這里需要注意,試驗是有成本的,但是很便宜,一瓶可樂錢大概可以玩一天。
開始之前,我們需要明白幾個關鍵詞:
虛節點:沒意義的節點,沒實際功能,虛擬出來便于理解整體邏輯關系的,可建可不建。
任務節點:說白了就是一個具體的操作,比如跑SQL語句或同步數據。
調度周期:這個很重要,關系到了你的任務顆粒細度,可以設置為分鐘、小時、天、周、月,大部分是夠用的。
離線任務:我們一定要明白一個概念,所有在數加平臺運行的離線任務都是非實時的,所有的ODPS表查詢也都是非實時的,雖然SQL語句查詢的方式很像實時數據庫,但是你不能直接連接到ODPS進行業務數據實時展示,所以在流程的最后,我們一般需要放一個數據同步的節點,用來將運算完成的ODPS數據同步到自己的數據庫中,進了自己數據庫還不是任你揉捏~
進入到數加平臺的“數據開發”模塊,在左側創建任務,此處我們選擇工作流任務,便于理解整體的邏輯,以下是我的實現邏輯,不一定適合所有人,請自行調整(圖片看不清請放大看):
格式化cdn日志,我是通過SQL語句結合一些小技巧來完成的,因為我們是一家to B的Saas服務商,所以在文件的存儲上有自己的規律,比如:
http://www.xxx.com/client123/logo.png
http://www.xxx.com/client999/logo.png
分別代表了兩個客戶的文件URL,我們需要通過字符串切割,把客戶標識找出來,也就是連接中 client123和client999 這一部分。
以下是我的SQL語句:
ALTER TABLE cdn_logs_format DROP if exists PARTITION (log_date=’bdp.system.bizdate′);INSERTintoTABLEcdnlogsformatPARTITION(logdate=′{bdp.system.bizdate}’)
SELECT unix_time
, TOLOWER(split_part(uri, ‘/’, 2)) AS uri_parent
, method, procotol, domain, uri, return_code
, rt, response_size, client_ip, remote_address, bacend_server
, refer_domain, refer_uri, content_type, user_agent
FROM cdn_logs
WHERE log_date = ‘${bdp.system.bizdate}’
上面的語句中,最核心的其實就3個部分。
第一部分是維護cdn_logs_format表的特定分區,判斷是否存在臟數據,如果存在,刪除掉這個分區的內容。${bdp.system.bizdate}這個是內置變量,最終運行時會被替換為日期。
第二部分是通過split_part方法切割出url中的第一級目錄,也就是我們業務中的客戶標識部分。
第三部分是把查詢到的內容INSERT into到cdn_logs_format表中。
在完成了基礎日志的格式化之后,我們需要對同一個客戶的訪問請求進行合并匯總,需要用到下面的SQL語句:
ALTER TABLE aggr_product_traffic DROP IF EXISTS PARTITION (product = ‘emp’, aggr_date = ‘${bdp.system.bizdate}’);
INSERT INTO TABLE aggr_product_traffic PARTITION (product = ‘emp’, aggr_date = ‘bdp.system.bizdate′)SELECTuriparentASclientcode,datepart(TODATE(logdate,‘yyyymmdd′),‘yyyy′)ASyear,datepart(TODATE(logdate,‘yyyymmdd′),‘mm′)ASmonth,datepart(TODATE(logdate,‘yyyymmdd′),‘dd′)ASday,datepart(TODATE(logdate,‘yyyymmdd′),‘hh′)AShour,datepart(TODATE(logdate,‘yyyymmdd′),‘mi′)ASmi,SUM(responsesize)AStraffic,UNIXTIMESTAMP(TODATE(‘{bdp.system.bizdate}’, ‘yyyymmdd’)) AS create_at
, to_char(TO_DATE(‘bdp.system.bizdate′,‘yyyymmdd′),‘yyyy?mm?dd′)AStargetdateFROMcdnlogsformatWHERElogdate=‘{bdp.system.bizdate}’
GROUP BY uri_parent,log_date
上面的語句中,核心其實就是group by + sum方法,做過關系型數據庫開發的同學一定很熟悉,我也就不贅述了。
至此我們就通過2個任務分別完成了基礎日志的處理及流量數據的合并匯總。
五、運算結果同步到自有數據庫
這一步就不截圖展示了,很簡單,配置好數據源,一一對應數據庫字段即可,傻瓜操作,so easy!然后找你的開發同學做個好看的圖表,出來后,你的客戶看到的就是這個效果:
六、后記
因為只是偏場景方向的某一個側重點展示,所以對經常使用數加平臺的同學來說這個可能太淺了,幫助不大。但是對未接觸過數加產品的同學來說,其實數加有好多產品都挺有意思的,只不過因為大數據這一塊因為大家領域、場景重疊的少導致分享的東西很難產生共鳴。
總結
以上是生活随笔為你收集整理的【阿里云MVP月度分享】SaaS服务商如何通过数加平台统计业务流量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 调研邀请:我们到底需要什么样的低代码平台
- 下一篇: 如何基于OSS和MTS,快速搭建音视频文