龙空技术网

01.分布式服务追踪与调用链系统

sungchungfoor 969

前言:

如今你们对“webservice调用css”都比较讲究,小伙伴们都想要剖析一些“webservice调用css”的相关文章。那么小编同时在网络上收集了一些有关“webservice调用css””的相关知识,希望看官们能喜欢,同学们一起来了解一下吧!

产生背景

在微服务系统中,随着业务的发展,系统会变得越来越大,那么各个服务之间的调用关系也就变得越来越复杂。一个 HTTP 请求会调用多个不同的微服务来处理返回最后的结果,在这个调用过程中,可能会因为某个服务出现网络延迟过高或发送错误导致请求失败,这个时候,对请求调用的监控就显得尤为重要了。Spring Cloud Sleuth 提供了分布式服务链路监控的解决方案。下面介绍 Spring Cloud Sleuth 整合 Zipkin 的解决方案。

分布式服务追踪系统优点

1.RPC远程调用过程中,服务与服务依赖的关系非常复杂,A调用B服务,B服务C服务 如果某个服务出现问题可能会导致整个链响应延迟;

2.如果服务的依赖关系非常复杂,建议改成MQ异步的形式。

服务追踪常用框架

1. Sleuth +Zipkin SpringCloud封装了 Sleuth +Zipkin

2. 阿里的鹰眼系统

3. Skywalking(非常推荐大家使用 功能非常强大)---Skywalking

Sleuth+Zipkin

1.Spring Cloud Sleuth实现了一种分布式的服务链路跟踪解决方案,通过使用Sleuth可以让我们快速定位某个服务的问题。

2.官方文档地址如下:

服务追踪常见名词

1.Sleuth可以结合Zipkin可以实现界面化的形式管理我们接口依赖信息;

2.Sleuth 每一次RPC远程调用请求都会生成一个spanid记录每一次rpc请求的信息,还有一个traceid 全局唯一id;

3.spanid为请求单元ID、traceid 为请求链全局id

构建分布式服务追踪调用链系统ZipkinServer环境搭建

在 Spring Boot 2.0 版本之后,官方已不推荐自己搭建定制了,而是直接提供了编译好的 jar 包。详情可以查看官网:

注意:zipkin官网已经提供定制了,使用官方jar运行即可。

相关依赖下载:

默认端口号启动zipkin服务

java –jar zipkin.jar 默认端口号; 9411

指定端口号启动9411

java -jar zipkin.jar --server.port=8080

客户端整合Zipkin

Maven依赖

<dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-zipkin</artifactId>    <version>2.0.0.RELEASE</version></dependency><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-sleuth</artifactId>    <version>2.0.0.RELEASE</version></dependency>
配置文件中新增
zipkin:  base-url: 全部采集sleuth:   sampler:    probability: 1.0
请求头中获取TraceID

log.info("<X-B3-TraceId>:{}", request.getHeader("X-B3-TraceId"));

log.info("<X-B3-SpanId>:{}", request.getHeader("X-B3-SpanId"));

log.info("<X-B3-ParentSpanId>:{}", request.getHeader("X-B3-ParentSpanId"));

X-B3-TraceId:对应TraceID;

X-B3-SpanId:对应SpanID;

X-B3-ParentSpanId:前面一环的SpanID;

X-B3-Sampled:是否被选中抽样输出;

X-Span-Name:工作单元名称。

微信公众号环境搭建

课程标题:<如何构建分布式 APM 服务监控系统>

1.什么是APM?

2.如何实现服务监控

3.什么是SkyWalking

4.SkyWalking如何实现警告?

5.如何实现告警调用微信公众号接口

6.构建微信公众号服务

7.构建微信公众号微信模板

7.SkyWalking监控服务报错调用微信公众号模板

如果系统发生报错的话 ,可以通过哪些手段拦截?

1.aop的形式 异常通知

2.全局捕获异常

搭建微信公众号环境

1.导入开源的微信公众号框架项目 weixin-java-mp-demo-springboot-master

2. 申请一个测试的微信公众号

3.免费为每个用户分配一个测试的appid和秘钥

appIDwx5c43fde3c9733d9eappsecretb8b217126c33a5fb7074927d5e72a81a

openid: 微信公众号开放的唯一userid-------

4.拷贝 weixin-java-mp-demo-springboot-master 依赖和pom 配置

相关依赖下载:

mayikt-wx-message

对接微信公众号模板接口

对接阿里云短信接口:需要先创建微信模板,通过调用接口传递。

是完全免费的---如果是在生产环境 千万不要去用测试微信公众号。

先申请一个正式公众号“每特教育故障提醒”不需要花费钱 免费。

1.微信公众号创建模板信息

服务名称:{{first.DATA}} IP和端口:{{keyword1.DATA}} 错误内容:{{keyword2.DATA}} 错误时间:{{keyword3.DATA}} 发生了系统错误,请您及登录服务器查看并且解决。

2.模板创建成功之后 会返回一个 模板id:3pG8ePjjcqhxGXh6cb_rQ5JgXP_TGLamqkgs5bmBI54

3.发送微信模板代码

package com.mayikt.api.message;import com.mayikt.api.message.dto.ServiceErrorDto;import com.mayikt.wx.mp.config.WxMpConfiguration;import com.mayikt.wx.mp.config.WxMpProperties;import lombok.extern.slf4j.Slf4j;import me.chanjar.weixin.common.error.WxErrorException;import me.chanjar.weixin.mp.api.WxMpTemplateMsgService;import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;/** * @author 余胜军 * @ClassName WechatTemplateService * @qq 644064779 * @addres  * 微信:yushengjun644 */@RestController@Slf4jpublic class WechatTemplateService {    @Autowired    private WxMpProperties wxMpProperties;    @Value("${mayikt.errorTemplateId}")    private String errorTemplateId;    /**     * 调用该接口发送微信模板错误推送     *     * @param serviceErrorDto     * @return     *///    @RequestMapping("sendWechatTemplateError")//    public String sendWechatTemplateError(ServiceErrorDto serviceErrorDto) {//        WxMpTemplateMsgService wxMpTemplateMsgService = WxMpConfiguration.getMpServices().get("wx5c43fde3c9733d9e").getTemplateMsgService();//        WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();//        wxMpTemplateMessage.setTemplateId("3pG8ePjjcqhxGXh6cb_rQ5JgXP_TGLamqkgs5bmBI54");//        wxMpTemplateMessage.setToUser("okYSmtzp4wWCrDCncMfGSRECVSeM");//        List<WxMpTemplateData> data = new ArrayList<>();//        data.add(new WxMpTemplateData("first", "mayikt-member"));//        data.add(new WxMpTemplateData("keyword1", "192.168.110.1:8080"));//        data.add(new WxMpTemplateData("keyword2", "空指针异常"));//        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd ");//        String format = formatter.format(new Date());//        data.add(new WxMpTemplateData("keyword3", format + " 20:30"));//        wxMpTemplateMessage.setData(data);//        wxMpTemplateMessage.setUrl(";);//        try {//            wxMpTemplateMsgService.sendTemplateMsg(wxMpTemplateMessage);//        } catch (Exception e) {//            e.printStackTrace();////            userMapper.updateByUserIdOpenIdIsNull(openId);////            UpdateWrapper<FollowOpenId> followOpenIdUpdateWrapper = new UpdateWrapper<>();////            followOpenIdUpdateWrapper.eq("open_id", openId);////            followOpenIdMapper.delete(followOpenIdUpdateWrapper);//        }//        return "ok";//    } }

4.优化该代码:

  @Autowired  private WxMpProperties wxMpProperties;  @Value("${mayikt.errorTemplateId}")  private String errorTemplateId; @RequestMapping("sendWechatTemplateError")    public String sendWechatTemplateError(@RequestBody ServiceErrorDto serviceErrorDto) {        WxMpTemplateMsgService wxMpTemplateMsgService = WxMpConfiguration.getMpServices().get(wxMpProperties.getConfigs().get(0).getAppId()).getTemplateMsgService();        WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();        wxMpTemplateMessage.setTemplateId(errorTemplateId);        wxMpTemplateMessage.setToUser(serviceErrorDto.getOpenId());        List<WxMpTemplateData> data = new ArrayList<>();        data.add(new WxMpTemplateData("first", serviceErrorDto.getServiceName()));        data.add(new WxMpTemplateData("keyword1", serviceErrorDto.getIp() + ":" + serviceErrorDto.getPort()));        data.add(new WxMpTemplateData("keyword2", serviceErrorDto.getErrorMsg()));        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String format = formatter.format(serviceErrorDto.getErrorTime());        data.add(new WxMpTemplateData("keyword3", format));        wxMpTemplateMessage.setData(data);        wxMpTemplateMessage.setUrl(";);        try {            wxMpTemplateMsgService.sendTemplateMsg(wxMpTemplateMessage);        } catch (Exception e) {            log.error("<e:>", e);        }        return "ok";    }
import lombok.Data;import java.util.Date;/** * @author 余胜军 * @ClassName ServiceErrorDto * @qq 644064779 * @addres  * 微信:yushengjun644 */@Datapublic class ServiceErrorDto {    /**     * ip地址     */    private String ip;    /**     * 端口号     */    private Integer port;    /**     * 服务的名称     */    private String serviceName;    /**     * 错误内容     */    private String errorMsg;    /**     * 错误时间     */    private Date errorTime;    /**     * 用户的关注微信公众号的 openId     */    private String openId;}

5.测试json数据

{  "ip":"192.168.110.1",  "port":8080,  "serviceName":"mayikt-member",  "errorMsg":"null",  "errorTime":"2021-11-23 00:16:47",  "openId":"okYSmtzp4wWCrDCncMfGSRECVSeM"    }

127.0.0.1:9099/sendWechatTemplateError

创建springboot项目

1.定义一段测试代码:

@RestControllerpublic class MayiktService {    @RequestMapping("/mayikt")    public String mayikt(Long id) {        return "ok" + 1 % id;    }}

2.定义全局捕获异常

import com.alibaba.fastjson.JSONObject;import com.mayikt.service.asyn.AsynSendWechatTemplate;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.http.HttpEntity;import org.springframework.http.HttpHeaders;import org.springframework.http.MediaType;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.client.RestTemplate;import java.net.InetAddress;import java.net.NetworkInterface;import java.net.SocketException;import java.net.UnknownHostException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Enumeration;/** * 全局捕获异常 */@ControllerAdvice@Slf4jpublic class MyExceptionHandler {    @Value("${server.port}")    private String serverPort;    @Value("${spring.application.name}")    private String serviceName;    @Autowired    private AsynSendWechatTemplate asynSendWechatTemplate;    @ExceptionHandler(value = Exception.class)    public String exceptionHandler(Exception e) {        log.error("未知异常!原因是:" + e);        JSONObject data = new JSONObject();        data.put("ip", getIpAddress());        data.put("port", serverPort);        data.put("serviceName", serviceName);        data.put("errorMsg", e.getLocalizedMessage());        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String format = formatter.format(new Date());        data.put("errorTime", format);        data.put("openId", "okYSmtzp4wWCrDCncMfGSRECVSeM");//        HttpHeaders headers = new HttpHeaders();//        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");//        headers.setContentType(type);//        headers.add("Accept", MediaType.APPLICATION_JSON.toString());//        HttpEntity<String> formEntity = new HttpEntity<String>(data.toString(), headers);//        String result = restTemplate.postForEntity(";, formEntity, String.class).getBody();//        log.info("result:" + result);        asynSendWechatTemplate.sendWechatTemplate(data);        return "系统出现错误!";    }    public static String getIpAddress() {        String hostAddress = "";        try {            InetAddress address = InetAddress.getLocalHost();            hostAddress = address.getHostAddress();        } catch (UnknownHostException e) {        }        return hostAddress;    }}

3.注入restTemplate

    @Bean    public RestTemplate restTemplate() {        return new RestTemplate();    }

4.优化代码 改成异步实现

import com.alibaba.fastjson.JSONObject;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpEntity;import org.springframework.http.HttpHeaders;import org.springframework.http.MediaType;import org.springframework.stereotype.Component;import org.springframework.web.client.RestTemplate;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.LinkedBlockingDeque;/** * @author 余胜军 * @ClassName AsynSendWechatTemplate * @qq 644064779 * @addres  * 微信:yushengjun644 */@Component@Slf4jpublic class AsynSendWechatTemplate {    private static ArrayBlockingQueue<JSONObject> arrayBlockingQueue =            new ArrayBlockingQueue<JSONObject>(1024);    @Autowired    private RestTemplate restTemplate;    public AsynSendWechatTemplate() {        new Thread(new ThreadAsynSendWechatTemplate()).start();    }    /**     * 存入到 队列中     *     * @param data     */    public void sendWechatTemplate(JSONObject data) {        arrayBlockingQueue.offer(data);    }    class ThreadAsynSendWechatTemplate implements Runnable {        @Override        public void run() {            while (true) {                JSONObject data = arrayBlockingQueue.poll();                if (data != null) {                    HttpHeaders headers = new HttpHeaders();                    MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");                    headers.setContentType(type);                    headers.add("Accept", MediaType.APPLICATION_JSON.toString());                    HttpEntity<String> formEntity = new HttpEntity<String>(data.toString(), headers);                    String result = restTemplate.postForEntity(";, formEntity, String.class).getBody();                    log.info("result:" + result);                }                try {                    // 避免cpu飙高的问题                    Thread.sleep(100);                } catch (Exception e) {                }            }        }    }    public static String getIpAddress() {        String hostAddress = "";        try {            InetAddress address = InetAddress.getLocalHost();            hostAddress = address.getHostAddress();        } catch (UnknownHostException e) {        }        return hostAddress;    }}

skyWalking

课程标题:<基于skyWalking构建企业级apm服务监控系统>

1.什么是skyWalking

2.skyWalking架构设计原理

3.skyWalking实现服务监控

4.SkyWalking如何实现警告?

5.SkyWalking监控服务报错调用微信公众号模板

6.SkyWalking数据库持久化方案

20点25分准时开始

SkyWalking是一个开源的观测平台,用于从服务和云原生等基础设施中收集、分析、聚合以及可视化数据,SkyWalking 提供了一种简便的方式来清晰地观测分布式系统,甚至可以观测横跨不同云的系统,SkyWalking 更像是一种现代的应用程序性能监控(Application Performance Monitoring,即APM)工具,专为云原生,基于容器以及分布式系统而设计。

监控--分布式追踪调用链 、jvm内存变化、智能报警、cpu飙高、服务器基本配置信息

(图片摘自: )

SkyWalking 无侵入式的收集 不需要引入任何的jar 启动的时候

被我们agent代理拦截即可---jdk提供一种技术 应用程序

对服务器监控(服务堆内存、cpu使用率、服务报错信息)

aop技术

请求前

rpc请求前后

请求后

在我们项目中引入它的jar

1. 探针:基于不同的来源探针可能是不一样的,但作用都是收集数据,将数据格式化为SkyWalking 适用的格式。例如在Java中则是做字节码植入,无侵入式的收集,并通过 HTTP 或者 GRPC 方式发送数据到平台后端 通过Agent技术 代理主函数

SkyWalking Agent 代理主程序 采集日志

Elk+kafka+aop技术采集日志

2.平台后端:是一个支持集群模式运行的后台,用于数据聚合、数据分析以及驱动数据流从探针到用户界面的流程。平台后端还提供了各种可插拔的能力,如不同来源数据(如来自Zipkin)格式化,不同存储系统以及集群管理。你甚至还可以使用观测分析语言来进行自定义聚合分析。

3.存储:是开放式的,可以选择一个既有的存储系统,如ElasticSearch、H2 或 MySQL 集群(Sharding-Sphere 管理),也可以选择自己实现一个存储系统。

用户界面:也就是SkyWalking的可视化界面,UI非常炫酷且强大,同样它也是可定制以匹配你已存在的后端的

4.SkyWalking 为观察和监控分布式系统提供了许多不同场景下的解决方案。例如为Java、C#及Node.js提供语言自动探针,无侵入式的收集。同时也为一些编译型语言C++、GO等提供了手动打点 SDK(目前还未支持)。除此之外,还可以使用服务网格基础探针来收集数据,以帮助了解整个分布式系统。

5.在SkyWalking中也存在服务、服务实例及端点概念,因为SkyWalking就是提供了这些概念的观测能力:

6.服务(Service):表示对请求提供相同行为的一系列或一组工作负载。在使用打点代理或 SDK 的时候,你可以定义服务的名字。如果不定义的话,SkyWalking 将会使用你在平台上定义的名字,如 Istio。

7.服务实例(Service Instance):上述的一组工作负载中的每一个工作负载称为一个实例。就像 Kubernetes 中的 pods 一样,服务实例未必就是操作系统上的一个进程。但当你在使用打点代理的时候, 一个服务实例实际就是操作系统上的一个真实进程。

端点(Endpoint):对于特定服务所接收的请求路径,如 HTTP 的 URI 路径和 gRPC 服务的类名 + 方法签名

综上,SkyWalking 优势如下:

8.多种监控手段,语言探针和服务网格(Service Mesh)

模块化,UI、存储、集群管理多种机制可选

支持告警

优秀的可视化方案:

skywalking架构原理

在整个skywalking的系统中,有四个角色:

1.skywalking agent和业务系统关联在一起,负责收集各种监控数据;

2.oapservice是负责处理监控数据的,比如接受skywalking agent的监控数据,并存储在数据库中(例如elasticsearch、mysql中等);接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。,Skywalking oapservice通常以集群的形式存在;

3.skywalking webapp,前端界面,用于展示数据;

4.用于存储监控数据的数据库,比如mysql、elasticsearch等;

skywalking 底层原理是?

1.springboot项目启动的时候 是不需要引入任何的jar包,

2.启动springboot项目被skywalking skywalking-agent.jar 拦截

3.将rpc请求数据 发送给我们的skywalking oapservice接口项目

4.连接到我们的skywalking webapp项目展示数据

5.数据最终是可以持久化存放在 db或者es中。

skywalking 环境安装

1. 下载apache-skywalking-apm-6.5.0.tar安装包

相关依赖下载:

2. 进入到bin目录(直接双击启动startup.bat)

3. 启动启动oapService和我们的webappService

4. 查看管理界面

agent 里面 skywalking-agent.jar 代理 springboot应用程序

logs ---日历目录

skywalking-oap-server.log

springboot实现监控

1. 创建一个springboot项目

2. 将该springboot项目打成jar包 mvn package

3. java -javaagent:skywalking-agent.jar路径 -jar springboot jar包

范例:

D:\path\cloud\apache-skywalking-apm-6.5.0\apache-skywalking-apm-bin\agent>java -javaagent:D:\path\cloud\apache-skywalking-apm-6.5.0\apache-skywalking-apm-bin\agent\skywalking-agent.jar -jar D:\path\cloud\apache-skywalking-apm-6.5.0\apache-skywalking-apm-bin\agent\mayikt-thymeleaf-1.0-SNAPSHOT.jar

4. 访问接口测试

为了避免skywalking 展示数据延迟问题,建议 将自动刷新改为1-3s

大家在演示效果的过程中,如果没有任何数据 注意:手动点击

5.agent\config\agent.config 修改应用的名称

agent.service_name=${SW_AGENT_NAME:mayiktAppDemo}

6.Idea 相关的配置:

-javaagent:D:\path\cloud\apache-skywalking-apm-6.5.0\apache-skywalking-apm-bin\agent\skywalking-agent.jar

-Dskywalking.agent.service_name=mayikt-member

-Dskywalking.collector.backend_service=127.0.0.1:11800

feign客户端整合SkyWalking

Skywalking(6.5.0) 支持的Rpc框架有以下几种:

Dubbo 2.5.4 -> 2.6.0

Dubbox 2.8.4

Apache Dubbo 2.7.0

Motan 0.2.x -> 1.1.0

gRPC 1.x

Feign客户端

1.启动生产者与消费者服务

2.生产者服务启动

-javaagent:D:\path\cloud\apache-skywalking-apm-6.5.0\apache-skywalking-apm-bin\agent\skywalking-agent.jar-Dskywalking.agent.service_name=mayikt-producer-Dskywalking.collector.backend_service=127.0.0.1:11800

3.消费者服务启动

-javaagent:D:\path\cloud\apache-skywalking-apm-6.5.0\apache-skywalking-apm-bin\agent\skywalking-agent.jar-Dskywalking.agent.service_name=mayikt-consumer-Dskywalking.collector.backend_service=127.0.0.1:11800

4.访问接口

5.演示效果:

SkyWalking获取全局追踪id

maven依赖:

        <dependency>            <groupId>org.apache.skywalking</groupId>            <artifactId>apm-toolkit-trace</artifactId>            <version>6.5.0</version>        </dependency>

生产者接口:

    @RequestMapping("/member")    public String orderToMember(@RequestParam("id") Integer id) {        // 获取request对象        HttpServletRequest request = ((ServletRequestAttributes)                RequestContextHolder.getRequestAttributes()).getRequest();        getHeders(request);        // 获取traceId        String traceId = TraceContext.traceId();        log.info(">>traceId:{}<<", traceId);        Integer j = 1 / id;        return "我是会员服务:" + traceId + "," + j;    }    public static void getHeders(HttpServletRequest request) {        //2.获得所有头的名称        Enumeration<String> headerNames = request.getHeaderNames();        while (headerNames.hasMoreElements()) {//判断是否还有下一个元素            String nextElement = headerNames.nextElement();//获取headerNames集合中的请求头            String header2 = request.getHeader(nextElement);//通过请求头得到请求内容            log.info("请求头=========={}" + nextElement + "VALUE:" + header2);            //System.out.println(nextElement+":"+header2);        }    }
SkyWalking告警

SkyWalking 告警功能

SkyWalking 告警功能是在6.x版本新增的,其核心由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中

SkyWalking 的发行版都会默认提供config/alarm-settings.yml文件,里面预先定义了一些常用的告警规则。如下:

1.过去3分钟内服务平均响应时间超过1秒

2.服务成功率在过去2分钟内低于80%

3.服务90%响应时间在过去3分钟内低于1000毫秒

4.服务实例在过去2分钟内的平均响应时间超过1秒

5.端点平均响应时间过去2分钟超过1秒

1.SkyWalking 调用开发者自己定义 接受报警接口;

2.开发者接受报警内容之后 在去调用微信公众号接口发送模板提醒

接受数据的格式

[{    "scopeId": 1,    "scope": "SERVICE",    "name": "serviceA",    "id0": 12,    "id1": 0,    "ruleName": "service_resp_time_rule",    "alarmMessage": "alarmMessage xxxx",    "startTime": 1560524171000}, {    "scopeId": 1,    "scope": "SERVICE",    "name": "serviceB",    "id0": 23,    "id1": 0,    "ruleName": "service_resp_time_rule",    "alarmMessage": "alarmMessage yyy",    "startTime": 1560524171000}]

scopeId、scope:所有可用的 Scope 详见

org.apache.skywalking.oap.server.core.source.DefaultScopeDefine

name:目标 Scope 的实体名称

id0:Scope 实体的 ID

id1:保留字段,目前暂未使用

ruleName:告警规则名称

alarmMessage:告警消息内容

startTime:告警时间,格式为时间戳

编写告警系统接口

1.封装报警参数的对象

/** * 封装报警参数的对象 */public class AlarmMessageDto {    private int scopeId;    private String name;    private int id0;    private int id1;    private String alarmMessage;    private long startTime;    public int getScopeId() {        return scopeId;    }    public String getName() {        return name;    }    public int getId0() {        return id0;    }    public int getId1() {        return id1;    }    public String getAlarmMessage() {        return alarmMessage;    }    public long getStartTime() {        return startTime;    }    public void setScopeId(int scopeId) {        this.scopeId = scopeId;    }    public void setName(String name) {        this.name = name;    }    public void setId0(int id0) {        this.id0 = id0;    }    public void setId1(int id1) {        this.id1 = id1;    }    public void setAlarmMessage(String alarmMessage) {        this.alarmMessage = alarmMessage;    }    public void setStartTime(long startTime) {        this.startTime = startTime;    }}

2.提供报警接口

import com.mayikt.entity.AlarmMessageDto;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;import java.util.List;/** * 报警接口 */@RestControllerpublic class PoliceService {    private List<List<AlarmMessageDto>> listAlarmMessage = new ArrayList<>();    /**     * 存放告警信息     *     * @param alarmMessageList     */    @RequestMapping(value = "/police", method = RequestMethod.POST)    public void alarm(@RequestBody List<AlarmMessageDto> alarmMessageList) {        listAlarmMessage.add(alarmMessageList);    }    /**     * 打印告警信息     *     * @return     */    @RequestMapping("/getListAlarmMessageDto")    public List<List<AlarmMessageDto>> getListAlarmMessageDto() {        return listAlarmMessage;    }}

3.调用微信接口发送报警模板

4.访问接口压力测试

调用微信模块接口

1.创建微信模板接口

scopeId:{{first.DATA}} 服务名称:{{keyword1.DATA}} 警告内容:{{keyword2.DATA}} 警告时间:{{keyword3.DATA}} 您可以登录企业内部skywalking平台查看,具体错误信息。

2.调用微信接口发送模板信息

  /**     * 存放告警信息     *      *     * @param alarmMessageList     */    @RequestMapping(value = "/police", method = RequestMethod.POST)    public void alarm(@RequestBody List<AlarmMessageDto> alarmMessageList) {        listAlarmMessage.add(alarmMessageList);        WxMpTemplateMsgService wxMpTemplateMsgService = WxMpConfiguration.getMpServices().get("wx5c43fde3c9733d9e").getTemplateMsgService();        alarmMessageList.forEach((alarmMessageDto -> {            WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();            // 改成刚刚创建好的模板id            wxMpTemplateMessage.setTemplateId("vQo2a5gWeY3lhMeRR6ekf8WqtX37z3eIaOwEWM9tLN8");            // 发送关注微信公众号的openid            wxMpTemplateMessage.setToUser("okYSmtzp4wWCrDCncMfGSRECVSeM");            List<WxMpTemplateData> data = new ArrayList<>();            data.add(new WxMpTemplateData("first", alarmMessageDto.getScopeId() + ""));            data.add(new WxMpTemplateData("keyword1", alarmMessageDto.getName()));            data.add(new WxMpTemplateData("keyword2", alarmMessageDto.getAlarmMessage()));            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");            String format = formatter.format(alarmMessageDto.getStartTime());            data.add(new WxMpTemplateData("keyword3", format));            wxMpTemplateMessage.setData(data);            // 点击该模板 访问到            wxMpTemplateMessage.setUrl(";);            try {                wxMpTemplateMsgService.sendTemplateMsg(wxMpTemplateMessage);            } catch (Exception e) {                log.error("<e:{}>", e);            }        }));    }

3.演示效果

SkyWalking数据持久化

SkyWalking 默认是将数据存入在内存中,如果重启SkyWalking 数据则都会丢失。

我们可以选择将数据持久化存放在mysql、es中等。

1.数据可以持久化在mysql、es中等。

  mysql:   properties:     jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/skywalking?serverTimezone=UTC&characterEncoding=utf-8"}     dataSource.user: ${SW_DATA_SOURCE_USER:root}     dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root}     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}

2.需要在oap-libs/ 放入 mysql-connector-java-8.0.16.jar

mysql-connector-java-8.0.16.jar 下载:

3.重启SkyWalking

自动创建表结构

相关依赖下载:

标签: #webservice调用css