skywalking分布式链路追踪

下载地址​​​​​​​Downloads | Apache SkyWalking

SkyWalking APM 9.2.0

Java Agent 8.12.0

linux搭建skywalking

0.安装jdk,配置环境变量

1.安装es,elasticsearch.service,修改内存限制LimitMEMLOCK=infinity # 增加配置

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-x86_64.rpm

2.使用es存储,服务启动默认4g内存

vim /etc/elasticsearch/jvm.options

-Xms1g
-Xmx1g

3.重新加载启动脚本并启动并加入开机自启

systemctl daemon-reload && systemctl start elasticsearch && systemctl enable elasticsearch

systemctl status elasticsearch查看运行状态

systemctl stop elasticsearch停止es

4.skywalking默认采用h2存储

5.curl 127.0.0.1:9200查看cluster.name

skywalking分布式链路追踪_第1张图片

cluster.name: cghes与SW_NAMESPACE对应,启动oapService.sh成功后占用 11800,12800端口(netstat -lntp查看) 

               skywalking分布式链路追踪_第2张图片

1. 链路追踪框架对比

项目 Cat Zipkin SkyWalking
调用链可视化
聚合报表 非常丰富 较丰富
服务依赖图 简单 简单
埋点方式 侵入式 侵入式 非侵入,字节码增强
VM监控指标
支持语言 java/.net 丰富 java/.net/Nodejs/php/go
存储机制 mysql(报表),本地文件/HDFS(调用链) 内存,es,mysql等 H2,es
社区支持 主要国内 国外主流 Apache支持
使用案例 美团,携程,陆金所 京东,阿里定制后不开源 华为,小米,当当,微众银行
APM
是否支持webflux

2.微服务接入SkyWalking,每一个微服务启动加入agent,针对不同的服务开启探针配置agent.conf收集数据的颗粒度

skywalking分布式链路追踪_第3张图片

# skywalking-agent.jar的磁盘路径
-javaagent:所在路径 jar 
# 在skywalking上显示的服务名
-DSW_AGENT_NAME=dev-third

3.探针配置agent.conf

agent/config/agent.config中支持的属性列表

属性名 描述 默认值
agent.namespace 命名空间,用于隔离跨进程传播的header。如果进行了配置,header将为HeaderName:Namespace. 未设置
collector.backend_service 接收skywalking trace数据的后端地址 127.0.0.1:11800
plugin.mysql.trace_sql_parameters 如果设置为 true, SQL 查询 (典型的是 java.sql.PreparedStatement) 的参数也会被采集. false
plugin.tomcat.collect_http_params 这个配置项控制Tomcat插件是否应该收集请求的参数. 同样,在概要追踪中隐式激活. false
plugin.springmvc.collect_http_params 这个配置项控制SpringMVC插件是否应该收集请求的参数, 当您的Spring应用程序基于Tomcat时, 只需要设置 plugin.tomcat.collect_http_params 或 plugin.springmvc.collect_http_params 之一. 同样,在概要追踪中隐式激活. false
plugin.http.http_params_length_threshold 当启用 COLLECT_HTTP_PARAMS时,要保留多少字符并将其发送到OAP后端,请使用负值来保留和发送完整的参数. 添加这个配置项是为了提高性能. 1024
plugin.jedis.trace_redis_parameters 如果设置为 true,redis参数将被采集 false
plugin.mongodb.trace_param 如果为true,记录所有访问MongoDB的参数信息。默认为false,表示仅记录操作名,不记录参数信息。 false
plugin.postgresql.trace_sql_parameters 如果设置为true,将收集sql的参数(通常是 java.sql.PreparedStatement). false
plugin.elasticsearch.trace_dsl 如果为true,记录所有访问ElasticSearch的DSL信息。默认为false false
plugin.springmvc.use_qualified_name_as_endpoint_name 如果为true,endpoint的name为方法的全限定名,而不是请求的URL。默认为false。 false
plugin.solrj.trace_statement 如果为 true, 追踪 Solr 查询请求中的所有查询参数(包括 deleteByIds 和 deleteByQuery) 默认为 false. false
plugin.feign.collect_request_body 如果为 true, fegin调用请求体将打印 false

4.追踪Gateway
Spring Cloud Gateway 是基于 WebFlux 实现,必须搭配上apm-spring-cloud-gateway-2.1.x-plugin 和 apm-spring-webflux-x.x-plugin 两个插件

将agent/optional-plugins下的两个插件 复制到 agent/plugins目录下
5.请求参数上报

pom.xml依赖


    org.apache.skywalking
    apm-toolkit-trace

common工程下新建请求参数filter类extend HttpFilter,微服务工程启动类加扫包

import com.alibaba.nacos.shaded.com.google.common.collect.ImmutableSet;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * skywalking 请求参数封装,通过ActiveSpan,输出到skywalking,如需打印,启动类加入扫包 com.***.***.common.skywalking
 */
@Slf4j
@Component
public class SkyWalkingReqParamFilter extends HttpFilter {
    private static final ImmutableSet IGNORED_HEADERS;
    static {
        Set 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);
    }

    @Override
    public 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 {
                //构造请求的方法&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());
                }
                //构造header
                Enumeration 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("'");
                    }
                }
                //获取body
                String body = new String(requestWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
                if (StringUtils.hasLength(body)) {
                    sb.append(" -d '").append(body).append("'");
                }
                //输出到input
                ActiveSpan.tag("input", sb.toString());
                //获取返回值body
                String responseBody = new String(responseWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
                //输出到output
                ActiveSpan.tag("output", responseBody);
            } catch (Exception e) {
                log.warn("fail to build http log", e);
            } finally {
                responseWrapper.copyBodyToResponse();
            }
        }
    }
}

6.skywalking整合logback

pom依赖

     
            org.apache.skywalking
            apm-toolkit-logback-1.x
        

 logback-spring.xml,区分环境



    
    
    
    
    
        
            ${pattern}
        
    


    
        true
        
            info
        
        ${log.home}/default.log
        
            ${log.home}/%d{yyyy-MM-dd}/default-%i.log.gz
            7
            5GB
            
                
                128 MB
            
        
        
            ${pattern}
        
    

    
        true
        
            error
            ACCEPT
            DENY
        
        ${log.home}/error.log
        
            ${log.home}/error.log.%d{yyyy-MM-dd}
            7
        
        
            ${pattern}
        
    

    
        
        
            
                
                    -%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint}%clr(${LOG_LEVEL_PATTERN:-%5p})
                    %clr(${PID:- }){magenta} [%tid] %clr(---){faint}%clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan}
                    %clr(:){faint}%m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
                

            

        
    

    
    
        
            
                %d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n
            
        
    


    
        
            
        
    

    
        
            
            
            
        
    

    
        
            
            
            
        
    

你可能感兴趣的:(skywalking)