SkyWalking集成与案例
今天我們通過代碼的形式來了解下,如何在項目中使用Skywalking。
前幾篇文章可以參考:
《學習Skywalking · 搭建篇》
《Skywalking執行效果 · 多圖篇》
《Skywalking的ES索引 · 收藏篇》
今天說說代碼篇。
先說下比較常見的開源 APM 如下:
CAT:由國內美團點評開源的,基于 Java 語言開發,目前提供 Java、C/C++、Node.js、Python、Go 等語言的客戶端,監控數據會全量統計。國內很多公司在用,例如美團點評、攜程、拼多多等。CAT 需要開發人員手動在應用程序中埋點,對代碼侵入性比較強。
Zipkin:由 Twitter 公司開發并開源,Java 語言實現。侵入性相對于 CAT 要低一點,需要對web.xml 等相關配置文件進行修改,但依然對系統有一定的侵入性。Zipkin 可以輕松與 Spring Cloud 進行集成,也是 Spring Cloud 推薦的 APM 系統。
Pinpoint:韓國團隊開源的 APM 產品,運用了字節碼增強技術,只需要在啟動時添加啟動參數即可實現 APM 功能,對代碼無侵入。目前支持 Java 和 PHP 語言,底層采用 HBase 來存儲數據,探針收集的數據粒度非常細,但性能損耗較大,因其出現的時間較長,完成度也很高,文檔也較為豐富,應用的公司較多。
SkyWalking:國人開源的產品,2019 年 4 月 17 日 SkyWalking 從 Apache 基金會的孵化器畢業成為頂級項目。目前 SkyWalking 支持 Java、.Net、Node.js 等探針,數據存儲支持MySQL、ElasticSearch等。SkyWalking 與 Pinpoint 相同,Java 探針采用字節碼增強技術實現,對業務代碼無侵入。探針采集數據粒度相較于 Pinpoint 來說略粗,但性能表現優秀。目前,SkyWalking 增長勢頭強勁,社區活躍,中文文檔齊全,沒有語言障礙,支持多語言探針,這些都是 SkyWalking 的優勢所在,還有就是 SkyWalking 支持很多框架,包括很多國產框架,例如,Dubbo、gRPC、SOFARPC 等等,也有很多開發者正在不斷向社區提供更多插件以支持更多組件無縫接入 SkyWalking。還有很多不開源的 APM 系統,例如,淘寶鷹眼、Google Dapper 等等,不再展開介紹了。
SkyWalking 的核心功能
服務、服務實例、端點指標分析。
服務拓撲圖分析
服務、服務實例和端點(Endpoint)SLA 分析
慢查詢檢測
告警
多語言自動探針,支持 Java、.NET Code 等多種語言。
為多種開源項目提供了插件,為 Tomcat、 HttpClient、Spring、RabbitMQ、MySQL 等常見基礎設施和組件提供了自動探針。
SkyWalking 三個核心部分
Agent(探針):Agent 運行在各個服務實例中,負責采集服務實例的 Trace 、Metrics 等數據,然后通過 gRPC 方式上報給 SkyWalking 后端。
OAP(后端服務):SkyWalking 的后端服務,其主要責任有兩個。
一個是負責接收 Agent 上報上來的 Trace、Metrics 等數據,交給 Analysis Core (涉及 SkyWalking OAP 中的多個模塊)進行流式分析,最終將分析得到的結果寫入持久化存儲中。SkyWalking 可以使用 ElasticSearch、H2、MySQL 等作為其持久化存儲,一般線上使用 ElasticSearch 集群作為其后端存儲。
另一個是負責響應 SkyWalking UI 界面發送來的查詢請求,將前面持久化的數據查詢出來,組成正確的響應結果返回給 UI 界面進行展示。UI(展示界面 ):SkyWalking 前后端進行分離,該 UI 界面負責將用戶的查詢操作封裝為 GraphQL 請求提交給 OAP 后端觸發后續的查詢操作,待拿到查詢結果之后會在前端負責展示。
其他的不多說,直接上代碼!
基礎依賴安裝
1、安裝ES
docker run --name elasticsearch \ -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e ES_JAVA_OPTS="-Xms512m -Xmx512m" \ -d elasticsearch:6.8.192、安裝Kibana
docker run -d --name kibana \ -p 5601:5601 \ -v D:/Code/k8s/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml kibana:6.8.0項目遷移案例展示:
1、設置SKYWALKING-OAP 收集服務
docker run -p 11800:11800 -d \ -e SW_NAMESPACE=bg\ -e SW_STORAGE=elasticsearch \ -e SW_STORAGE_ES_CLUSTER_NODES=xxxxxx \ -e SW_ES_USER=xxx \ -e SW_ES_PASSWORD=xxx \ apache/skywalking-oap-server:8.9.02、設置SKYWALKING-OAP API服務
docker run -p 12800:12800 -d \ -e SW_NAMESPACE=bg \ -e SW_STORAGE=elasticsearch \ -e SW_STORAGE_ES_CLUSTER_NODES=xxxxx \ -e SW_ES_USER=xxx \ -e SW_ES_PASSWORD=xxx \ -e SW_SEARCHABLE_TAG_KEYS=http.method,status_code,db.type,db.instance,mq.queue,mq.topic,mq.broker,input,output,userId,account,number,systemid \ apache/skywalking-oap-server:8.9.03、設置SKYWALKING-UI
docker run -p 8080:8080 -d \ -e SW_OAP_ADDRESS=http://xxxx:12800 \ apache/skywalking-ui:8.9.0以上環境變量均可配置到k8s中。
4、配置CLIENT(ASP.NET Core)
1、安裝nuget包,提供探針
<PackageReference Include="SkyAPM.Agent.AspNetCore" Version="1.3.0" />2、設置skyapm.json(可配置configmap)
說明
ps:skyapm.json需要設置屬性——始終復制
3、配置K8s環境變量
ASPNETCORE_HOSTINGSTARTUPASSEMBLIES = SkyAPM.Agent.AspNetCore4、問題排查
在容器內,會生成skyapm-2022xxxx.log文件,會有詳細的連接信息和推送信息。
同時要檢查下是否包含skyapm.json文件。
5、配置CLIENT(Java)
1、修改Dockerfile
FROM apache/skywalking-java-agent:8.8.0-java11 AS bg-base
WORKDIR /app// ...COPY --from=bg-base /skywalking/agent/optional-plugins/apm-trace-ignore-plugin-8.8.0.jar /skywalking/agent/plugins/apm-trace-ignore-plugin-8.8.0.jarENTRYPOINT ["sh","-c","exec java -Xmx1024m -Xms1024m -Dproject.name=app-bg -Dskywalking.trace.ignore_path='**/nacos/**,**/JDBI/**' -Duser.language=zh -Duser.country=CN -jar /app/app.jar"]2、配置k8s環境變量
SW_AGENT_COLLECTOR_BACKEND_SERVICES=bg-oap:11800 SW_AGENT_NAME="bg::op::svc"3、配置Tag標記(可選項)
1、添加依賴包
<dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>8.7.0</version><scope>provided</scope> </dependency>2、設計過濾器
@Slf4j @Component public class ApmHttpInfoFilter extends HttpFilter {private static final ImmutableSet<String> IGNORED_HEADERS;static {Set<String> ignoredHeaders = ImmutableSet.of("Content-Type","User-Agent","Accept","Cache-Control","Postman-Token","Host","Accept-Encoding","Connection","Content-Length").stream().map(String::toUpperCase).collect(Collectors.toSet());IGNORED_HEADERS = ImmutableSet.copyOf(ignoredHeaders);}@Overridepublic void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);try {filterChain.doFilter(requestWrapper, responseWrapper);} finally {try {//構造請求信息: 比如 curl -X GET http://localhost:18080/getPerson?id=1 -H 'token: me-token' -d '{ "name": "hello" }'//構造請求的方法&URL&參數StringBuilder sb = new StringBuilder("curl").append(" -X ").append(request.getMethod()).append(" ").append(request.getRequestURL().toString());if (StringUtils.hasLength(request.getQueryString())) {sb.append("?").append(request.getQueryString());}//構造headerEnumeration<String> headerNames = request.getHeaderNames();while (headerNames.hasMoreElements()) {String headerName = headerNames.nextElement();if (!IGNORED_HEADERS.contains(headerName.toUpperCase())) {sb.append(" -H '").append(headerName).append(": ").append(request.getHeader(headerName)).append("'");}}//獲取bodyString body = new String(requestWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);if (StringUtils.hasLength(body)) {sb.append(" -d '").append(body).append("'");}//輸出到inputActiveSpan.tag("input", sb.toString());//輸出到userIdActiveSpan.tag("userid", BaseMethodUtil.getUserIdByHeader(request)+"");//獲取返回值bodyString responseBody = new String(responseWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);//輸出到outputActiveSpan.tag("output", responseBody);} catch (Exception e) {log.warn("fail to build http log", e);} finally {//這一行必須添加,否則就一直不返回responseWrapper.copyBodyToResponse();}}} }3、容器啟動配置tag
-e SW_NAMESPACE=bg-e SW_SEARCHABLE_TAG_KEYS=http.method,status_code,db.type,db.instance,mq.queue,mq.topic,mq.broker,input,output,userid4、掛載告警配置(可選項)
需要企業微信機器人
-v?D:\Code\k8s\kibana\alarm-settings.yml:/skywalking/config/alarm-settings.yml6、配置CLIENT(Vue.js)
1、安裝npm
npm install skywalking-client-js --save2、注冊服務
import ClientMonitor from 'skywalking-client-js';ClientMonitor.register({collector: process.env.VUE_APP_PERMISSION_URL + '/ui',service:?process.env.VUE_APP_SW_NAME?||?'op::ui',pagePath: location.href,serviceVersion: 'v1.0.0',vue: Vue,useFmp: true,enableSPA: false,traceTimeInterval: 10000,apiErrors: true,})3、攔截器
// 異常攔截器 Vue.config.errorHandler = (error) => {console.error(error)error.message += window.location.hrefconst _roles = store.state.user.rolesif (_roles) {error.message += (_roles.name || '') + ' ' + _roles.number}ClientMonitor.reportFrameErrors({collector: process.env.VUE_APP_PERMISSION_URL + '/ui',service:?process.env.VUE_APP_SW_NAME?||?'op::ui',pagePath: window.location.href,vue: Vue,serviceVersion: 'v1.0.0'}, error) }// 路由攔截器 import ClientMonitor from 'skywalking-client-js'ClientMonitor.customOptions.pagePath = location.origin + location.pathname + '#' + to.fullPath4、配置nginx代理收集器
server {listen 80;listen [::]:80;server_name localhost;#charset koi8-r;#access_log /var/log/nginx/host.access.log main;location / {root /usr/share/nginx/html-test;index index.html index.htm;}location /ui/browser/ {rewrite ^.+ui/?(.*)$ /$1 break;include uwsgi_params;proxy_pass xxxxxx;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;}location /ui/v3/ {rewrite ^.+ui/?(.*)$ /$1 break;include uwsgi_params;proxy_pass xxxxxxx;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;}location /ui {try_files $uri $uri/ /index.html;alias /usr/share/nginx/html-test/ui;index index.html index.htm;}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html #error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;}}其他問題記錄:
1、 刪除索引后,記得刪除對應的ES模板;
2、 VUE項目要根據實際情況,做sw服務的nginx的反向代理配置;
3、 skywalking如果遇到問題,可以優先升級最新版本;
最后打個廣告,歡迎觀看與分享。
總結
以上是生活随笔為你收集整理的SkyWalking集成与案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的技术回顾那些与ABP框架有关的故事-
- 下一篇: Natasha 4.0 探索之路系列(四