Skywalking安裝和使用


安裝

下載地址:https://skywalking.apache.org/downloads/

由於本地的ES是7.15.1版本 所有需要選擇對應版本的
image

本地需要啟動ES。ES安裝可查看之前的博客:ES安裝

配置ES啟動

  1. 進入解壓后的skywalking目錄:
cd apache-skywalking-apm-bin-es7
# 修改config里面的 
  1. 修改config目錄下的 application.yml 文件
    image

默認使用的是h2存儲數據,修改為es7

selector: $

  1. 進入bin目錄啟動
nohup nice sh startup.sh &
  1. 打開 webapp/webapp.yml文件 查看UI訪問端口
    image

  2. 訪問 http://localhost:8080/
    image

Agent

agent探針可以讓我們不修改代碼的情況下,對java應用上使用到的組件進行動態監控,獲取運行數據發送到OAP上進行統計和存儲。agent探針在java中是使用java agent技術實現的,不需要更改任何代碼,java agent會通過虛擬機(VM)接口來在運行期更改代碼。

進入 agent 目錄

cd ~/tools/apache-skywalking-apm-bin-es7/agent/

image

目錄 作用
config 配置文件
plugins 使用的插件
optional-plugins 可選的插件 如果需要使用,放入到plugins就會生效

項目集成

可查看官方文檔: https://skywalking.apache.org/docs/main/v8.7.0/en/setup/service-agent/java-agent/readme/

修改應用名:打開agent/config目錄,編輯agent_config文件

# The service name in UI
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}

Tomcat

編輯 apache-tomcat-8.5.47/bin/catalina.sh 文件,在文件頂部添加

CATALINA_OPTS="$CATALINA_OPTS -javaagent:/usr/local/skywalking/apache- skywalking-apm-bin/agent/skywalking-agent.jar"; export CATALINA_OPTS

SpringBoot

IDEA配置VM參數

-javaagent:/Users/mpy/tools/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar

或者jar命令啟動

java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar -jar yourApp.jar

需要等待一下才能看到數據

image

image

常用插件

配置覆蓋

本地多個項目 如何都使用同一份agent配置不同的項目名稱呢?
可以使用Skywalking提供的配置覆蓋功能通過啟動命令動態指定服務名,這樣agent只需要部署一份即可。Skywalking支持的幾種配置方式:

  1. 系統配置(System properties)
    使用 skywalking. + 配置文件中的配置名作為系統配置項來進行覆蓋.

-Dskywalking.agent.service_name=skywalking_mysql

  1. 探針配置(Agent options)

-javaagent:/path/to/skywalking-agent.jar=[option1]=[value1],[option2]=[value2]

案例:

-javaagent:/path/to/skywalking-agent.jar=agent.service_name=skywalking_mysql

特殊字符
如果配置中包含分隔符( , 或者 = ) , 就必須使用引號包裹起來

-javaagent:/path/to/skywalking-agent.jar=agent.ignore_suffix='.jpg,.jpeg'

  1. 系統環境變量(System environment variables)
    由於agent.service_name配置項如下所示:

agent.service_name=$

可以在環境變量中設置SW_AGENT_NAME的值來指定服務名。

覆蓋優先級

探針配置 > 系統配置 >系統環境變量 > 配置文件中的值

所以啟動命令可以修改為:

java -javaagent:/usr/local/skywalking/apache-skywalking-apm- bin/agent_mysql/skywalking-agent.jar - Dskywalking.agent.service_name=skywalking_mysql -jar skywalking_mysql.jar &

獲取追蹤ID

  1. 添加Jar包 和本地skywalking版本保持一致
<dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-trace</artifactId>
            <version>8.7.0</version>
        </dependency>
  1. 編寫測試類
//獲取trace id,可以在RocketBot追蹤中進行查詢
    @GetMapping("/getTraceId")
    public String getTraceId() {
        //使當前鏈路報錯,並且提示報錯信息
        ActiveSpan.error(new RuntimeException("Test-Error-Throwable"));
        //打印info信息
        ActiveSpan.info("Test-Info-Msg");
        //打印debug信息
        ActiveSpan.debug("Test-debug-Msg");
        return TraceContext.traceId();
    }
  1. 測試
    image

image

過濾指定的端點

項目中的一些接口是不需要監控指標的,比如Swagger相關的端點,需要進行過濾

  1. 添加可選插件 apm-trace-ignore-plugin-8.7.0.jar 到 plugins目錄中

  2. 編寫測試類

//此接口可以被追蹤
    @GetMapping("/include")
    public String include(){
        return "include";
    }
	
//此接口不可被追蹤
    @GetMapping("/exclude")
    public String exclude(){
        return "exclude";
    }
  1. 添加啟動參數
- Dskywalking.trace.ignore_path=/exclude
  1. 測試 include接口可以被監控,exclude無法被監控

  2. 匹配多路徑
    這里添加-Dskywalking.trace.ignore_path=/exclude參數來標識需要過濾哪些請求,支持 Ant Path 表達式:/path/* , /path/** , /path/?

- ? 匹配任何單字符
- * 匹配0或者任意數量的字符
- ** 匹配0或者更多的目錄

告警功能

Skywalking每隔一段時間根據收集到的鏈路追蹤的數據和配置的告警規則(如服務響應時間、服務響應時間百分比)等,判斷如果達到閾值則發送相應的告警信息。發送告警信息是通過調webhook接口完成,具體的webhook接口可以使用者自行定義,從而開發者可以在指定的webhook接口中編寫各種告警方式,比如郵件、短信等。告警的信息也可以在RocketBot中查看到。

默認的告警規則配置,位於skywalking安裝目錄下的config文件夾下 alarm-settings.yml 文件中
image

規則屬性說明

屬性 含義
metrics-name oal腳本中的度量名稱
threshold 閾值,與metrics-name和下面的比較符號相匹配
op 比較操作符,可以設定>,<,=
period 多久檢查一次當前的指標數據是否符合告警規則,單位分鍾
count 達到多少次后,發送告警消息
silence-period 在多久之內,忽略相同的告警消息
message 告警消息內容
include-names 本規則告警生效的服務列表

webhooks可以配置告警產生時的調用地址。

webhooks:
#  - http://127.0.0.1/notify/
#  - http://127.0.0.1/go-wechat/

具體信息可以查看官方文檔:https://skywalking.apache.org/docs/main/latest/en/setup/backend/backend-alarm/#webhook
image

  1. 配置文件修改
webhooks:
  - http://127.0.0.1:8801/webhook
  1. 接收告警信息 自行處理
    產生告警時會調用webhook接口,該接口必須是Post類型,同時接口參數使用RequestBody。參數格式為
[{
	"scopeId": 1, 
	"scope": "SERVICE",
	"name": "serviceA", 
	"id0": "12",  
	"id1": "",  
    "ruleName": "service_resp_time_rule",
	"alarmMessage": "alarmMessage xxxx",
	"startTime": 1560524171000,
    "tags": [{
        "key": "level",
        "value": "WARNING"
     }]
}]
private List<AlarmMessage> lastList = new ArrayList<>();

    @PostMapping("/webhook")
    public void  webhook(@RequestBody List<AlarmMessage> alarmMessageList){
        lastList = alarmMessageList;
    }

java agent原理

上文中我們知道,要使用Skywalking去監控服務,需要在其 VM 參數中添加 -javaagent:/skywalking-agent.jar 。這里就使用到了java agent技術。

Java agent 是什么

Java agent是java命令的一個參數。參數 javaagent 可以用於指定一個 jar 包。

  1. 這個 jar 包的 MANIFEST.MF 文件必須指定 Premain-Class 項。
  2. Premain-Class 指定的那個類必須實現 premain() 方法。

當Java 虛擬機啟動時,在執行 main 函數之前,JVM 會先運行 -javaagent 所指定 jar 包內PremainClass 這個類的 premain 方法 。

如何使用java agent

使用 java agent 需要幾個步驟:

  1. 定義一個 MANIFEST.MF 文件,必須包含 Premain-Class 選項,通常也會加入Can-RedefineClasses 和 Can-Retransform-Classes 選項。
  2. 創建一個Premain-Class 指定的類,類中包含 premain 方法,方法邏輯由用戶自己確定。
  3. 將 premain 的類和 MANIFEST.MF 文件打成 jar 包。
  4. 使用參數 -javaagent: jar包路徑 啟動要代理的方法。

自定義Agent

Skywalking中對每個調用的時長都進行了統計,我們可以使用ByteBuddyJava agent技術來模擬實現skywalking統計方法的調用時長

  1. 新建maven項目 agent
<dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.9.2</version>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy-agent</artifactId>
            <version>1.9.2</version>
        </dependency>
  1. 編寫PreMain方法
    PreMainAgent類 通過MyInterceptor 插入業務邏輯
public static void premain(String agentArgs, Instrumentation inst) {
        //創建一個轉換器,轉換器可以修改類的實現
        //ByteBuddy對java agent提供了轉換器的實現,直接使用即可
        AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> builder
                // 攔截任意方法
                .method(ElementMatchers.any())
                // 攔截到的方法委托給TimeInterceptor
                .intercept(MethodDelegation.to(MyInterceptor.class));
        new AgentBuilder // Byte Buddy專門有個AgentBuilder來處理Java Agent的場景
                .Default()
                // 根據包名前綴攔截類
                .type(ElementMatchers.nameStartsWith("com.agenttest"))
                // 攔截到的類由transformer處理
                .transform(transformer)
                .installOn(inst);
    }
  1. 編寫攔截方法
@RuntimeType
    public static Object intercept(@Origin Method method,
                                   @SuperCall Callable<?> callable)
            throws Exception {
        long start = System.currentTimeMillis();
        try {
            //執行原方法
            return callable.call();
        } finally {
            //打印調用時長
            System.out.println(method.getName() + ":" + (System.currentTimeMillis() - start)  + "ms");
        }
    }
  1. 指定build方法
<build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <appendAssemblyId>false</appendAssemblyId>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <!--自動添加META-INF/MANIFEST.MF -->
                        <manifest>
                            <addClasspath>true</addClasspath>
                        </manifest>
                        <manifestEntries>
                            <Premain-Class>com.PreMainAgent</Premain-Class>
                            <Agent-Class>com.PreMainAgent</Agent-Class>
                            <Can-Redefine-Classes>true</Can-Redefine-Classes>
                            <Can-Retransform-Classes>true</Can-Retransform-Classes>
                        </manifestEntries>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
  1. 新建測試項目agent-test
public class App 
{
    public static void main( String[] args )
    {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println( "Hello World!" );
    }
}

啟動時指定javaagent為上面的項目打包生成的jar

  1. 測試 可以發現運行時自動執行了agent項目里面的方法
    image

Open Tracing介紹

OpenTracing通過提供平台無關、廠商無關的API,使得開發人員能夠方便的添加(或更換)追蹤系統的實現。OpenTracing中最核心的概念就是Trace

Trace

在廣義上,一個trace代表了一個事務或者流程在(分布式)系統中的執行過程。在OpenTracing標准中,trace是多個span組成的一個有向無環圖(DAG),每一個span代表trace中被命名並計時的連續性的執行片段。
image

圖中每一個色塊其實就是一個span。

Span

一個Span代表系統中具有開始時間和執行時長的邏輯運行單元。span之間通過嵌套或者順序排列建立邏輯因果關系。

Span里面的信息包括:操作的名字,開始時間和結束時間,可以附帶多個 key:value 構成的Tags(key必須是String,value可以是 String, bool 或者數字),還可以附帶 Logs 信息(不一定所有的實現都支持)

一個span可以和一個或者多個span間存在因果關系。OpenTracing定義了兩種關系: ChildOf FollowsFrom 。這兩種引用類型代表了子節點和父節點間的直接因果關系。未來,OpenTracing將支持非因果關系的span引用關系。(例如:多個span被批量處理,span在同一個隊列中,等等)

  • ChildOf 很好理解,就是父親 Span 依賴另一個孩子 Span。比如函數調用,被調者是調用者的孩子,比如說 RPC 調用,服務端那邊的Span,就是 ChildOf 客戶端的。很多並發的調用,然后將結果聚合起來的操作,就構成了 ChildOf 關系。
  • 如果父親 Span 並不依賴於孩子 Span 的返回結果,這時可以說它他構成 FollowsFrom 關系。

如圖所示,左邊的每一條追蹤代表一個Trace,而右邊時序圖中每一個節點就是一個Span。
image

Log的概念

每個span可以進行多次Logs操作,每一次Logs操作,都需要一個帶時間戳的時間名稱,以及可選的任意大小的存儲結構。
image

Tags的概念

每個span可以有多個鍵值對(key:value)形式的Tags,Tags是沒有時間戳的,支持簡單的對span進行注解和補充。
如下圖就是一個Tags的詳細信息,其中記錄了數據庫訪問的SQL語句等內容。
image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM