首页 文章详情

SkyWalking集成与案例

DotNet NB | 630 2022-02-17 23:26 0 0 0
UniSMS (合一短信)



今天我们通过代码的形式来了解下,如何在项目中使用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.19

2、安装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.0


2、设置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.0


3、设置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需要设置属性——始终复制

{  "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",        "Timeout": 10000,        "ConnectTimeout": 10000,        "ReportTimeout": 600000      }    }  }}

3、配置K8s环境变量
ASPNETCORE_HOSTINGSTARTUPASSEMBLIES = SkyAPM.Agent.AspNetCore

4、问题排查

在容器内,会生成skyapm-2022xxxx.log文件,会有详细的连接信息和推送信息。
同时要检查下是否包含skyapm.json文件。


5、配置CLIENT(Java)


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.jar
ENTRYPOINT ["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);    }
@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 { //构造请求信息: 比如 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()); }
//构造header Enumeration<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("'"); } }
//获取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());
//输出到userId ActiveSpan.tag("userid", BaseMethodUtil.getUserIdByHeader(request)+"");
//获取返回值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(); } } }}

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


4、挂载告警配置(可选项)

需要企业微信机器人

-v D:\Code\k8s\kibana\alarm-settings.yml:/skywalking/config/alarm-settings.yml


6、配置CLIENT(Vue.js)


1、安装npm
npm install skywalking-client-js --save

2、注册服务
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.href const _roles = store.state.user.roles if (_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.fullPath


4、配置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如果遇到问题,可以优先升级最新版本;


推荐阅读:
Kubernetes全栈架构师(Kubeadm高可用安装k8s集群)--学习笔记
.NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记
.NET Core开发实战(第1课:课程介绍)--学习笔记

点击下方卡片关注DotNet NB

一起交流学习

▲ 点击上方卡片关注DotNet NB,一起交流学习

请在公众号后台


回复 【路线图】获取.NET 2021开发者路线图
回复 【原创内容】获取公众号原创内容
回复 【峰会视频】获取.NET Conf开发者大会视频
回复 【个人简介】获取作者个人简介
回复 【年终总结】获取作者年终总结
回复 加群加入DotNet NB 交流学习群

长按识别下方二维码,或点击阅读原文。和我一起,交流学习,分享心得。


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter