SkyWalking

简介

分布式链路跟踪是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s)架构而设计;

也就是说Skywalking是用于微服务的“跟踪" ;

对于一个大型的几十个、几百个微服务构成的微服务架构系统,通常会遇到下面一些问题,比如:

如何串联整个调用链路,快速定位问题?

如何理清各个微服务之间的依赖关系?

如何进行各个微服务接口的性能分折?

如何跟踪整个业务流程的调用处理顺序?

Skywalking提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案;

Skywalking是国人采用Java开发的,现在已经是apache下的一个等级项目;


主要功能和特征

1、多种监控手段,可以通过语言探针和service mesh获得监控的数据;

2、支持多种语言自动探针,包括 Java,.NET Core 和 Node.JS;

3、轻量高效,无需大数据平台和大量的服务器资源;

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

5、支持告警;

6、优秀的可视化解决方案;

官网:http://skywalking.apache.org/

下载:http://skywalking.apache.org/downloads/

Github:https://github.com/apache/skywalking

使用公司:(国内非常多)


整体架构

整个架构分成四部分:

1、上部分Agent :负责从应用中,收集链路信息,发送给 SkyWalking OAP 服务器;

2、下部分 SkyWalking OAP :负责接收Agent发送的Tracing数据信息,然后进行分析(Analysis Core),存储到外部存储器(Storage),最终提供查询(Query)功能;

3、右部分Storage:Tracing数据存储,目前支持ES、MySQL、Sharding Sphere、TiDB、H2多种存储器,目前采用较多的是ES,主要考虑是SkyWalking开发团队自己的生产环境采用ES为主;

4、左部分SkyWalking UI:负责提供控台,查看链路等等;


环境部署

1,下载 SkyWalking 软件包;

2,搭建一个 SkyWalking OAP 和SkyWalking UI服务;

3,启动一个Spring Boot应用,并配置SkyWalking Agent;

数据存储暂时先使用它默认的H2数据库存储,后续我们再使用其他存储;

1、下载 SkyWalking 软件包

对于 SkyWalking 的软件包,有两种方式获取:

手动编译

官方包

一般情况下,我们建议使用官方包,手动编译也可以;

从这里下载:http://skywalking.apache.org/downloads/

2、SkyWalking OAP 搭建

解压:tar -zxvf apache-skywalking-apm-8.1.0.tar.gz

解压后即完成了安装,不需要做其他操作;

切换:cd apache-skywalking-apm-bin

目录说明:

agent #SkyWalking Agent

bin #执行脚本

config #SkyWalking OAP Server 配置文件

LICENSE

licenses

NOTICE

oap-libs #SkyWalking OAP Server

README.txt

tools

webapp #SkyWalking UI

3、启动 SkyWalking OAP 服务

切换到bin目录:./startup.sh

启动后会启动两个服务,一个是skywalking-oap-server,一个是skywalking-web-ui;

查看安装目录下的 ./logs 下的日志文件,检查两个服务的日志文件是否启动成功;

skywalking-oap-server服务启动后会占用:11800 和 12800 两个端口;

skywalking-web-ui服务会占用 8080 端口;

如果想要修改SkyWalking UI服务的参数,可以编辑webapp/webapp.yml 配置文件,比如:

server.port:SkyWalking UI服务端口,默认是8080;

collector.ribbon.listOfServers:SkyWalking OAP服务地址数组,SkyWalking UI界面的数据是通过请求SkyWalking OAP服务来获得;

访问SkyWalking UI界面:http://192.168.172.128:8080/

页面的右下角可以中英文切换,可以切换选择要展示的时间区间的跟踪数据;


SkyWalking Agent跟踪微服务

案例一:

准备一个springboot程序,打成可执行jar包,写一个shell脚本,在启动项目的Shell脚本上,通过 -javaagent 参数进行配置SkyWalking Agent来跟踪微服务;

#!/bin/sh

\# SkyWalking Agent配置

export SW_AGENT_NAME=11-springboot #Agent名字,一般使用`spring.application.name` 

export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 #配置 Collector 地址。

export SW_AGENT_SPAN_LIMIT=2000 #配置链路的最大Span数量,默认为 300。

export JAVA_AGENT=-javaagent:/usr/local/apache-skywalking-apm-bin/agent/skywalking-agent.jar

java ***\*$JAVA_AGENT\**** -jar 11-springboot-1.0.0.jar #jar启动

在启动程序前加一个-javaagent 参数即可完成对程序的跟踪;

案例二:

在tomcat中部署war包配置SkyWalking Agent来跟踪微服务;

修改/usr/local/apache-tomcat-9.0.31/bin/catalina.sh 文件,在顶部第一行加上:

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

export CATALINA_OPTS;

如果tomcat端口与skywalking ui端口冲突的话,修改一下tomcat端口;

测试,访问一下项目,然后进入 SkyWalking UI 界面查看跟踪情况,由于上传数据是异步的,访问完项目后,可能需要等几秒才能看到跟踪数据;


SkyWalking三个概念

*服务(Service)* *:*表示对请求提供相同行为的一系列或一组工作负载,在使用Agent时,可以定义服务的名字,我们可以看到 Spring Boot 应用服务为 "11-springboot",就是我们在环境变量 SW_AGENT_NAME 中所定义的;

*服务实例(Service Instance) :*上述的一组工作负载中的每一个工作负载称为一个实例, 一个服务实例实际就是操作系统上的一个真实进程;

这里我们可以看到 Spring Boot 应用的服务为 {agent_name}-pid:{pid}@{hostname},由 Agent 自动生成;

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

我们可以看到 Spring Boot 应用的一个端点,为API接口 /index;


IDEA中使用SkyWalking

在运行的程序配置jvm参数和环境变量参数,如下图所示:

-javaagent:E:\software\JAVA\springcloud-alibaba\package\skywalking\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800;SW_AGENT_NAME=sharding

SkyWalking告警

告警设置:./config/alarm-setting.yml

skywalking告警的核心由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中,告警规则的定义分为三部分;

1、告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件;

2、网络钩子(Webhook}:当警告触发时,哪些服务终端需要被通知;

3、gRPC钩子:远程gRPC方法的主机和端口,告警触发后调用;

为了方便,skywalking发行版中提供了默认的alarm-setting.yml文件,包括一些规则,每个规则有英文注释,可以根据注释得知每个规则的作用;

比如service_resp_time_rule规则:

service_resp_time_rule:

  metrics-name: service_resp_time

  op: ">"

  threshold: 1000

  period: 10

  count: 3

  silence-period: 5

  message: Response time of service {name} is more than 1000ms in 3 minutes of last 10 minutes.

该规则表示服务{name}的响应时间在最近10分钟的3分钟内超过1000ms;

只有我们的服务请求符合alarm-setting.yml文件中的某一条规则就会触发告警;

*Webhook回调通知*

SkyWalking告警Webhook回调要求接收方是一个Web容器(比如tomcat服务),告警的消息会通过HTTP请求进行发送, 请求方法为POST, Content-Type为application/json, JSON格式基于

List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>的集合对象数据, 集合中的每个AlarmMessage包含以下信息:

1、scopeId. 所有可用的Scope请查阅:

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

2、name. 目标 Scope 的实体名称;

3、id0. Scope 实体的 ID;

4、id1. 未使用;

5、ruleName. 您在 alarm-settings.yml 中配置的规则名;

6、alarmMessage. 报警消息内容;

7、startTime. 告警时间, 位于当前时间与 UTC 1970/1/1 之间;

AlarmMessage类的代码:


SkyWalking数据mysql持久化

在./config/application.yml文件中将数据存储那一项变更为mysql

在MySQL下,变更连接url,更改连接数据库的用户名和密码。在oap-libs文件夹下导入mysql驱动。启动skywalking即可。


SkyWalking数据Elasticsearch持久化

Skywalking跟踪数据默认是存放在内嵌式数据库H2中的,重启skywalking,跟踪数据就丢失了,我们可以把跟踪数据持久化到mysql或者elasticsearch中,上一次课我们介绍了如何将跟踪数据持久化到mysql,此次我们介绍一些如何将跟踪数据持久化到elasticsearch中;

需要解压另一个专门针对elasticsearch版本的Skywalking:

1、tar -zxvf apache-skywalking-apm-es7-8.1.0.tar.gz

2、cd apache-skywalking-apm-es7-8.1.0

3、修改application.yml配置文件:

storage:

 selector: ${SW_STORAGE:elasticsearch7}

4、启动elasticsearch7

./elasticsearch -d

​ 后台运行 (es不能用root启动)

注:Elasticsearch的jvm内存不能配置太小,至少512m,小了会出现错误:

配置文件:./config/jvm.options

status line [HTTP/1.1 429 Too Many Requests] <------错误信息

5、启动elasticsearch-head插件:npm run start 便于查看elasticsearch数据;

6、启动skywalking

./startup.sh

启动时会向elasticsearch中创建大量的index索引用于持久化数据,每天会产生一个新的索引文件;

7、启动应用程序,查看跟踪数据是否已经持久化到elasticsearch的索引中;

8、然后重启skywalking,验证跟踪数据会不会丢失;


Skywalking跨多个微服务跟踪

Skywalking跨多个微服务跟踪,只需要每个微服务启动时添加javaagent参数即可;

-javaagent:D:/dev/apache-skywalking-apm-bin/agent/skywalking-agent.jar

SW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.172.128:11800;SW_AGENT_NAME=11-springboot-idea

自定义SkyWalking链路追踪

如果我们希望对项目中的业务方法,实现链路追踪,方便我们排查问题,可以使用如下的代码;

1、添加依赖;

<!-- SkyWalking 工具类-->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.6.0</version>
</dependency>

2、在业务代码中使用如下方法:

TraceContext.putCorrelation("myKey", "myValue");
Optional<String> op = TraceContext.getCorrelation("myKey");
log.info("myValue = {} ", op.get()); String traceId = TraceContext.traceId();
log.info("traceId = {} ", traceId);

这样就可以拿到跟踪的traceId,便于根据traceId去ui界面搜索整个跟踪链路;

另外如果一个业务方法想在ui界面的跟踪链路上显示出来,只需要在业务方法上加上@Trace注解即可;


SkyWalking集成日志框架

1、添加如下依赖;

<!-- apm-toolkit-logback-1.x -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.6.0</version>
</dependency>

2、添加logback-spring.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration> <!-- 引入 Spring Boot 默认的 logback XML 配置文件 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/> <!-- 控制台 Appender -->
<property name="CONSOLE_LOG_PATTERN" value="%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}"/> <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志的格式化 -->
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
</layout>
</encoder>
</appender> <!-- 从 Spring Boot 配置文件中,读取 spring.application.name 应用名 -->
<springProperty name="applicationName" scope="context" source="spring.application.name" /> <property name="FILE_LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } %tid --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> <!-- 日志文件的路径 -->
<property name="LOG_FILE" value="/logs/${applicationName}.log"/> <!-- 日志文件 Appender -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<!--滚动策略,基于时间 + 大小的分包策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<maxHistory>7</maxHistory>
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!-- 日志的格式化 -->
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>${FILE_LOG_PATTERN}</Pattern>
</layout>
</encoder>
</appender> <!-- 设置 Appender -->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root> </configuration>

3、在代码中记录日志:

log.info("/goods --> getAllGoods --> ......" ); //自定义log输出

4、访问controller测试,查看日志输出,就可以在日志中看到跟踪的traceId;


SkyWalking-UI介绍

仪表盘:查看被监控服务的运行状态;

拓扑图:以拓扑图的方式展现服务之间的关系,并以此为入口查看相关信息;

追踪:以接口列表的方式展现,追踪接口内部调用过程;

性能剖析:对端点进行采样分析,并可查看堆栈信息;

告警:触发告警的告警列表,包括服务失败率,请求超时等;

自动刷新:刷新当前页面数据内容;

控制栏

第一栏:不同内容主题的监控面板,应用性能管理/数据库/容器等;

第二栏:操作,包括 编辑/导出当前数据/倒入展示数据/不同服务端点筛选展示;

第三栏:不同纬度展示,全局/服务/实例/端点;

展示栏

Global全局维度

第一栏:Global、Service、Instance、Endpoint不同展示面板;

Services load:服务每分钟请求数;

Slow Services:慢响应服务,单位ms;

Un-Health services(Apdex): Apdex性能指标,1为满分;

Slow Endpoint:慢响应端点,单位ms;

Global Response Latency:百分比响应延时,不同百分比的延时时间,单位ms;

Global Heatmap:服务响应时间热力分布图,根据时间段内不同响应时间的数量显示颜色深度;

底部栏:展示数据的时间区间,点击可以调整;

Service服务维度

Service Apdex(数字):当前服务的评分;

Service Apdex(折线图):不同时间的Apdex评分;

Service Avg Response Times:平均响应延时,单位ms;

Global Response Time Percentile:百分比响应延时;

Successful Rate(数字):请求成功率;

Successful Rate(折线图):不同时间的请求成功率;

Servce Load(数字):每分钟请求数;

Servce Load(折线图):不同时间的每分钟请求数;

Servce Instances Load:每个服务实例的每分钟请求数;

Show Service Instance:每个服务实例的最大延时;

Service Instance Successful Rate:每个服务实例的请求成功率;

Instance实例维度

Service Instance Load:当前实例的每分钟请求数;

Service Instance Successful Rate:当前实例的请求成功率;

Service Instance Latency:当前实例的响应延时;

JVM CPU:jvm占用CPU的百分比;

JVM Memory:JVM内存占用大小,单位m;

JVM GC Time:JVM垃圾回收时间,包含YGC和OGC;

JVM GC Count:JVM垃圾回收次数,包含YGC和OGC;

JVM Thread Count:JVM线程数;

还有几个是.NET的,类似于JVM虚拟机,暂时不做说明;

Endpoint端点(API)维度

Endpoint Load in Current Service:每个端点的每分钟请求数;

Slow Endpoints in Current Service:每个端点的最慢请求时间,单位ms;

Successful Rate in Current Service:每个端点的请求成功率;

Endpoint Load:当前端点每个时间段的请求数据;

Endpoint Avg Response Time:当前端点每个时间段的请求行响应时间;

Endpoint Response Time Percentile:当前端点每个时间段的响应时间占比;

Endpoint Successful Rate:当前端点每个时间段的请求成功率;

拓扑图

1:选择不同的服务关联拓扑;

2:查看单个服务相关内容;

3:服务间连接情况;

4:分组展示服务拓扑;

追踪

左侧:api接口列表,红色-异常请求,蓝色-正常请求;

右侧:api追踪列表,api请求连接各端点的先后顺序和时间;

性能剖析

服务:需要分析的服务;

端点:链路监控中端点的名称,可以在链路追踪中查看端点名称;

监控时间:采集数据的开始时间;

监控持续时间:监控采集多长时间;

起始监控时间:多少秒后进行采集;

监控间隔:多少秒采集一次;

最大采集数:最大采集多少样本;

告警

不同维度告警列表,可分为服务、端点和实例;


SkyWalking集群-Nacos

生产中不搭集群也是可以的,因为这个只是调用链路跟踪,skywalking oap跟踪服务如果宕机了,完全不会影响正常业务;

Skywalking集群是将skywalking oap作为一个服务注册到nacos上,只要skywalking oap服务没有全部宕机,保证有一个skywalking oap在运行,就能进行跟踪;

搭建一个skywalking oap集群需要:

(1)至少一个Nacos(也可以nacos集群)

(2)至少一个ElasticSearch(也可以es集群)

(3)至少2个skywalking oap服务;

(4)至少1个UI(UI也可以集群多个,用Nginx代理统一入口)

具体步骤:

1、解压两份apache-skywalking-apm-es7-8.1.0.tar.gz

2、修改配置application.yml文件

/config/application.yml

cluster:
selector: ${SW_CLUSTER:nacos}
nacos:
serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}

注意:nacos配置中的命名空间是否正确

第一台

restHost: ${SW_CORE_REST_HOST:0.0.0.0}
restPort: ${SW_CORE_REST_PORT:12801}
gRPCPort: ${SW_CORE_GRPC_PORT:11801}
gRPCHost: ${SW_CORE_GRPC_HOST:0.0.0.0}

第二台

restHost: ${SW_CORE_REST_HOST:0.0.0.0}
restPort: ${SW_CORE_REST_PORT:12802}
gRPCPort: ${SW_CORE_GRPC_PORT:11802}
gRPCHost: ${SW_CORE_GRPC_HOST:0.0.0.0}

使用elasticsearch作为storage

storage:
selector: ${SW_STORAGE:elasticsearch7}
storage:
elasticsearch7:
nameSpace: ${SW_NAMESPACE:""}
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}

3、配置ui服务webapp.yml文件的listOfServers,写两个地址

listOfServers: 127.0.0.1:12801,127.0.0.1:12802

4、启动测试

启动一个skywalking-webapp.jar使用脚本webappService.sh;

启动两个OAPServerStartUp使用脚本oapService.sh;

5、启动应用程序进行测试,如果是jar包启动:

java -javaagent:xxxxx/agent/skywalking-agent.jar
-Dskywalking.agent.service_name=gateway
-Dskywalking.collector.backend_service=192.168.172.128:11801,192.168.172.128:11802
-jar 11-springboot-idea-1.0.0.jar

如果是idea启动应用程序:(注意配置两个连接地址)

SW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.172.128:11801,192.168.172.128:11802;SW_AGENT_NAME=11-springboot-idea

Spring Cloud Alibaba - SkyWalking的更多相关文章

  1. 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...

  2. Spring Cloud Alibaba 介绍及工程准备

    简介 SpringCloud Alibaba是阿里巴巴集团开源的一套微服务架构解决方案. 微服务架构是为了更好的分布式系统开发,将一个应用拆分成多个子应用,每一个服务都是可以独立运行的子工程.其中涵盖 ...

  3. Spring Cloud Alibaba微服务一站式解决方案-开篇v2.2.1.RELEASE

    学习路线 **本人博客网站 **IT小神 www.itxiaoshen.com 生态概述 架构演进 什么是微服务 https://martinfowler.com/microservices/ Mic ...

  4. 主流微服务一站式解决方案Spring Cloud Alibaba入门看这篇就足够了

    学习路线 **本人博客网站 **IT小神 www.itxiaoshen.com 生态概述 架构演进 什么是微服务 https://martinfowler.com/microservices/ Mic ...

  5. Spring Cloud Alibaba基础教程:Nacos的集群部署

    继续说说生产环境的Nacos搭建,通过上一篇<Spring Cloud Alibaba基础教程:Nacos的数据持久化>的介绍,我们已经知道Nacos对配置信息的存储原理,在集群搭建的时候 ...

  6. Spring Cloud Alibaba 新版本发布:众多期待内容整合打包加入!

    在Nacos 1.0.0 Release之后,Spring Cloud Alibaba也终于发布了最新的版本.该版本距离上一次发布,过去了整整4个月!下面就随我一起看看,这个大家期待已久的版本都有哪些 ...

  7. Spring Cloud Alibaba基础教程:Sentinel使用Apollo存储规则

    上一篇我们介绍了如何通过Nacos的配置功能来存储限流规则.Apollo是国内用户非常多的配置中心,所以,今天我们继续说说Spring Cloud Alibaba Sentinel中如何将流控规则存储 ...

  8. Spring Cloud Alibaba基础教程:Sentinel使用Nacos存储规则

    通过上一篇<使用Sentinel实现接口限流>的介绍,相信大家对Sentinel已经有了初步的认识.在Spring Cloud Alibaba的整合封装之下,接口限流这件事情可以非常轻易的 ...

  9. Spring Cloud Alibaba基础教程:使用Sentinel实现接口限流

    最近管点闲事浪费了不少时间,感谢网友libinwalan的留言提醒.及时纠正路线,继续跟大家一起学习Spring Cloud Alibaba. Nacos作为注册中心和配置中心的基础教程,到这里先告一 ...

随机推荐

  1. 5、SpringBoot整合之SpringBoot整合MybatisPlus

    SpringBoot整合MybatisPlus 目录(可点击直接跳转,但还是建议按照顺序观看,四部分具有一定的关联性): 实现基础的增删改查 实现自动填充功能 实现逻辑删除 实现分页 首先给出四部分完 ...

  2. LeetCode解题记录(贪心算法)(一)

    1. 前言 目前得到一本不错的算法书籍,页数不多,挺符合我的需要,于是正好借这个机会来好好的系统的刷一下算法题,一来呢,是可以给部分同学提供解题思路,和一些自己的思考,二来呢,我也可以在需要复习的时候 ...

  3. Spring官方发布新成员:Spring GraphQL

    近日,在GraphQL Java诞生6周年的时候,Spring社区通过博客宣布正式创建全新项目:Spring GraphQL,同时还发布了这个新项目的里程碑1.0版本. 博客原文:https://sp ...

  4. css实现文字过度变色效果

    html: <div class="news text-center"> <a href="#"> <span>新</ ...

  5. APDU:APDU常用指令

    APDU= ApplicationProtocol data unit, 是智能卡与智能卡读卡器之间传送的信息单元, (给智能卡发送的命令)指令(ISO 7816-4规范有定义) CLA INS P1 ...

  6. 注解+AOP实现redis遍历缓存

    1.注解 package com.yun.smart.annotation; import java.lang.annotation.ElementType; import java.lang.ann ...

  7. ReadyAPI 测试工具和创建管理

    通过测试加速API质量APIs 和微服务正在改变组织在数字世界中开展业务的方式,对它们进行测试 比以往任何时候都更加重要 ReadyAPI测试工具是创建.管理.并运行自动化测试REST.SOAP.Gr ...

  8. 使用Hugo框架搭建博客的过程 - 功能拓展

    前言 本文介绍一些拓展功能,如文章页面功能增加二级菜单,相关文章推荐和赞赏.另外,使用脚本会大大简化写作后的上传流程. 文章页面功能 这部分功能的拓展主要是用前端的JS和CSS,如果对前端不了解,可以 ...

  9. Linux | 通配符 & 转义符

    通配符 我们在查看文件的时候,可能会出现只记得开头几个字母的情况,并且相似名称的文件还非常多的情况.还有小编想要删除一些开头一样的文件,这种情况下都可以使用通配符号: # 查找vcs文件 ls /de ...

  10. [Qt]-打包程序为Debian的deb格式的安装包

    参考:https://segmentfault.com/a/1190000005029385 参考:UnityLaunchersAndDesktopFiles deb是Debian Linux的软件包 ...