整个系统分为三部分:
agent:采集tracing(调用链数据)和metric(指标)信息并上报
OAP:收集tracing和metric信息通过analysis core模块将数据放入持久化容器中(ES,H2(内存数据库),mysql等等),并进行二次统计和监控告警
webapp(UI):前后端分离,前端负责呈现,并将查询请求封装为graphQL提交给后端,后端通过ribbon做负载均衡转发给OAP集群,再将查询结果渲染展示.
搭建Skywalking环境,一共需要四个步骤:
1、搭建持久化环境;
2、配置Skywalking服务;
3、搭建Skywalking可视化平台;
4、在对于的客户端中配置Agent;
一、数据持久化
持久化方案,官方主要使用免费开源的数据库,主要有以下几种:
H2
OpenSearch
ElasticSearch 6, 7, 8
MySQL
TiDB
PostgreSQL
BanyanDB
官方默认推荐使用ES做持久化方案,不过鉴于技术架构,本文主要使用MySql做持久化工具。

1、使用MySql
可以使用集群模式,这里用单节点举例。
docker run -d --name=sw_mysql -p 3306:3306-e MYSQL_ROOT_PASSWORD=pwd@123 mysql:5.7
二、安装 Skywalking OAP 服务
skywalking共有两个服务协议,分别是http(提供可视化接口)和grpc(提供agent数据传输)。
直接执行容器命令:
docker run --name skywalking-oap --restart always \-p 11800:11800 -p 12800:12800 -d \--link elasticsearch:elasticsearch \-e SW_STORAGE=mysql \-e SW_JDBC_URL="jdbc:mysql://ip:3306/swtest?rewriteBatchedStatements=true" \-e SW_DATA_SOURCE_USER=root \-e SW_DATA_SOURCE_PASSWORD=pwd@123 \-v /oap-libs/mysql-connector-java-5.1.47.jar:/skywalking/oap-libs/mysql-connector-java-5.1.47.jar \apache/skywalking-oap-server
NOTE: 需要自己拷贝mysql连接的驱动到 oap-libs 文件夹下。
Mysql可参考的全部参数配置:
storage:selector: ${SW_STORAGE:mysql}mysql:properties:jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/swtest?rewriteBatchedStatements=true"}dataSource.user: ${SW_DATA_SOURCE_USER:root}dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root@1234}dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}maxSizeOfBatchSql: ${SW_STORAGE_MAX_SIZE_OF_BATCH_SQL:2000}asyncBatchPersistentPoolSize: ${SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE:4}
这里如果直接访问11800/12800可能会没效果或者报错,忽略它,直接按照UI来看看效果。

三、安装 Skywalking-UI 可视化平台
一个可视化平台,执行安装命令:
docker run --name skywalking-ui --restart always \-p 8080:8080 \--link skywalking-oap:skywalking-oap \-e SW_OAP_ADDRESS=skywalking-oap:12800 \-d apache/skywalking-ui
同样要注意几点:
需要配置上skywalking的容器名,就是第三行。
ui的版本也尽量和oap的版本统一。
最后的效果如图:

目前还没有任何数据,接下来需要在Client客户端中配置代理探针。
四、配置客户端探针
1、ASP.NET Core
1、安装nuget包,提供探针
<PackageReference Include="SkyAPM.Agent.AspNetCore" Version="1.3.0" />2、设置skyapm.json
说明:skyapm.json需要设置属性——始终复制
{"SkyWalking": {"ServiceName": "bg::op::gateway",//服务名"Namespace": "","HeaderVersions": ["sw8"],"Sampling": {"SamplePer3Secs": -1,"Percentage": -1.0,"IgnorePaths": ["**/nacos/**"]//忽略路径},"Logging": {"Level": "Debug","FilePath": "logs/skyapm-{Date}.log"//日志地址},"Transport": {"Interval": 3000,"ProtocolVersion": "v8","QueueSize": 30000,"BatchSize": 3000,"gRPC": {"Servers": "bg-oap:11800",//skywalking-oap的grpc地址,需要自己配置"Timeout": 10000,"ConnectTimeout": 10000,"ReportTimeout": 600000}}}}
3、配置K8s环境变量
ASPNETCORE_HOSTINGSTARTUPASSEMBLIES = SkyAPM.Agent.AspNetCore4、问题排查
在容器内,会生成skyapm-2022xxxx.log文件,会有详细的连接信息和推送信息。
同时要检查下是否包含skyapm.json文件。
2、SpringBoot
1、修改Dockerfile
FROM apache/skywalking-java-agent:8.8.0-java11 AS bg-baseWORKDIR /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:11800SW_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@Componentpublic 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,userid