專案背景
Sentry 照著官網搭建好以後,想要看到效果,需要業務接入。盤了一下手裡專案,決定以X專案為切入點開刀。本想按照 官方API 接入即可,誰料道路之曲折有點出乎想象。
本文記錄實戰過程中的思路,以及遇到的實際問題,拿出來跟大家分享。
思路梳理
以上兩張圖描述的是sentry工作原理以及雲上部署方案。
具體問題
多機器部署
-
Docker的確可以實現快速搭建sentry服務,但是忽略一個大前提,這一切都是在一臺臺機器部署一個sentry!
- 實際專案中如果網站訪問量很大,一臺機器肯定是不夠的,萬一掛了,沒有備份機器會很尷尬;
- 即使一臺機器,如果只部署一個sentry例項,機器不能充分利用,資源浪費。
-
DSN 是sentry 的一個重要概念,可以理解是服務准入的標記
A value which we call a DSN ... it’s actually just a representation of the configuration required by the Sentry SDKs
-
AUTH TOKEN 是sentry的另一個重要概念,可以理解是```sentry-cli``命令列呼叫的鑰匙。
-
考慮到上面的顧慮,申請了兩臺機器,但隨之問題就來了。
- 一臺機器 複製多個
onpremise
目錄,不同目錄中啟動service,達到單臺機器多個例項的效果。- 現象:服務可執行,DSN 和 AUTH TOKEN 都一致,但是上傳soucemap的時候失敗。分析路徑完全一致
- 分析:引數都一樣,分不出要上傳到哪個例項。
- 兩臺機器,分別執行一個sentry服務
- 現象:服務可執行,DSN 和 AUTH TOKEN 兩個值都不一致;
- 分析:Docker不同機器部署,都會生成新的引數
- 一臺機器 複製多個
-
從官網提供的sentry.io服務來看,只有一個,DSN 和 一個AUTH TOKEN ,所以推測應該還有別的方案。調研中...
如果有相同經歷的朋友,一定留言指導一下啊
Vue專案接入有點不同
- 想當然的認為前端都是JS專案,直接按照官網提供的CDN接入方式接入即可,這可能是最經濟實惠的接入方式。無需業務開發,編譯過程中在模板head裡面找地方塞入這兩行即可。
<script src="https://cdn.ravenjs.com/3.26.4/raven.min.js" crossorigin="anonymous"></script>
<script>Raven.config('https://3042a92815a94e15ae949b717464c470@sentry.io/1401863').install();</script>
複製程式碼
- 按照這麼做的結果是:VUE專案,語法異常控制檯報錯了,沒有上報到sentry。點開報錯看,控制檯的錯誤是vue拋console.error,所以推斷vue已經對專案中的錯誤進行了攔截。又對官網文件進行了查閱,發現vue專案需要藉助vue外掛來上報異常。這個算是接入時候的踩的一個坑,無奈只好改技術方案,抽離公共元件實現上報。
# 當然也可以CDN方式接入,具體可參見官方文件
import Vue from 'vue';
import Raven from 'raven-js';
import RavenVue from 'raven-js/plugins/vue';
Raven
.config('https://9128da56fafa4fd4bb7d3e38e3577395@sentry.io/sentry//1')
.addPlugin(RavenVue, Vue)
.install();
複製程式碼
- VUE踩了坑,別的專案呢?寫Demo調研了一下,
react
和san
專案都是控制檯直接報錯,可採用之前設定的技術方案。
webpack
- 設計整體流程的時候,想借助webpack完成兩個事情:
sourcemap上傳到sentry系統
- sourcemap上傳,利用官方提供的外掛
sentry-webpack-plugin
即可完成(只是可以上傳單個機器,需要一個AUTH TOKEN , 多個機器還未解決)
產出HTML的head位置,打入JS引用及呼叫。
- 希望看到的效果
<html>
<head>
<title>TEST Page</title>
<script src="https://cdn.ravenjs.com/3.26.4/raven.min.js" crossorigin="anonymous"></script>
<script>Raven.config('https://3042a92815a94e15ae949b717464c470@sentry.io/1401863').install();</script>
</head>
...
</html>
複製程式碼
- 寫了插入頁面的外掛,但是webpack3 卻不支援:
compiler.hooks.compilation.tap
報錯:Cannot read property 'compilation' of undefined
// 頁面插入元素外掛
class HTMLinsertPlugin {
constructor(options) {
this.options = options.scripts;
}
apply(compiler) {
compiler.hooks.compilation.tap('HTMLinsertPlugin', compilation => {
// Hook into `htmlWebpackPluginAlterAssetTags`
// !! Careful this will change in the upcoming html webpack plugin version !!
compilation.hooks.htmlWebpackPluginAlterAssetTags.tapAsync('HTMLinsertPlugin',
// You can use either `head` or `body` and either `push` or `unshift`:
(htmlPluginData, callback) => {
this.options.forEach(ele => {
htmlPluginData.head.push(ele);
});
// htmlPluginData.head.push();
callback(null, htmlPluginData);
}
);
});
}
}
複製程式碼
webpack3 用模板變數實現
- 修改webapack
new HtmlWebpackPlugin({
...
sentryCDN: 'https://cdn.ravenjs.com/3.26.4/raven.min.js',
sentryScript:'Raven.config('https://3042a92815a94e15ae949b717464c470@sentry.io/1401863').install();'
})
複製程式碼
- 修改html
<script type="text/javascript" src="<%= htmlWebpackPlugin.options.sentryCDN %>"></script>
<script type="text/javascript">
<%= htmlWebpackPlugin.options.sentryScript %>
</script>
複製程式碼
後續Todo
- 升級webpack4
編譯聯網
就在歡呼官方提供的sentry-webpack-plugin
強大的時候,再次遇到了問題。公司流程提交程式碼後,會指定公機器進行編譯,而這臺機器是無法訪問外網的,導致編譯後上傳sentry服務的時候失敗。好在找到一臺可以訪問外網的機器進行編譯。
ngxin
基本配置說明
-
域名需要通過nginx
proxy_pass
到本機 -
Root URL. sentry建立好之後有一件事是設定root_url,這個將會影響DSN
- Root URL 設定為:
https://sentry.io/sentry
- DSN就會是:
https://9128da56fafa412312312338e3577395@sentry.io/sentry/1
, - 報警傳送請求就會是:
https://sentry.io/sentry/api/1/store/?sentry_version=7
- Root URL 設定為:
-
.sentryclirc
- sentry-webpack-plugin 外掛的檔案中需要設定url
- 此時url只能設定成:
https://sentry.io
-
於是
# /sentry 上報介面
location ^~ /sentry/ {
proxy_pass http://localhost:9000/;
}
# 非 /sentry uri 正常訪問
location / {
proxy_pass http://localhost:9000;
}
複製程式碼
額外配置
- 跨域
- 上傳大小限制
- 安全閒置
- ... 就不單獨列舉了
機器穩定性
- 專案上線過程中,單個機器可以抗住的QPS
- 機器掛了之後的降級方案
- 待補充
總結
Sentry雖然已經開源,但是X專案接入過程中還是遇到了很多問題,希望大家可以交流,互相避免踩坑。讓我們的頁面線上上更加穩定