链路追踪Skywalking应用实战

news2024/11/20 12:32:34

目录

  • 1 Skywalking应用
  • 2 agent下载
  • 3 agent应用
    • 3.1 应用名配置
    • 3.2 IDEA集成使用agent
    • 3.3 生产环境使用agent
  • 4 Rocketbot
    • 4.1 Rocketbot-仪表盘
    • 4.2 Rocketbot-拓扑图
    • 4.3 追踪
    • 4.4 性能分析
    • 4.5 告警
      • 4.5.1 警告规则详解
      • 4.5.2 Webhook规则
      • 4.5.3 自定义Webhook消息接收


1 Skywalking应用

在这里插入图片描述

相关术语:

skywalking-collector:链路数据归集器,数据可以落地ElasticSearch/H2
skywalking-ui:web可视化平台,用来展示落地的数据
skywalking-agent:探针,用来收集和发送数据到归集器

2 agent下载

Skywalking-agent,它简称探针,用来收集和发送数据到归集器,我们先来学习下探针使用,探针对应的jar包在Skywalking源码中,我们需要先下载源码。

Skywalking源码下载地址: https://archive.apache.org/dist/skywalking/ ,我们当前使用的版本是8.3.0,选择下载对应版本。

file

agent目录结构如下:

agent
    ├── activations
    │   ├── apm-toolkit-kafka-activation-8.3.0.jar
    │   ├── ...
    │   └── apm-toolkit-trace-activation-8.3.0.jar
    ├── config # Agent 配置文件
    │   └── agent.config
    ├── logs # 日志文件
    ├── optional-plugins # 可选插件
    │   ├── apm-customize-enhance-plugin-8.3.0.jar
    │   ├── apm-gson-2.x-plugin-8.3.0.jar
    │   └── ... ...
    ├── bootstrap-plugins # jdk插件
    │   ├── apm-jdk-http-plugin-8.3.0.jar
    │   └── apm-jdk-threading-plugin-8.3.0.jar
    ├── plugins # 当前生效插件
    │   ├── apm-activemq-5.x-plugin-8.3.0.jar
    │   ├── apm-armeria-0.84.x-plugin-8.3.0.jar
    │   ├── apm-armeria-0.85.x-plugin-8.3.0.jar
    │   └── ... ...
    ├── optional-reporter-plugins
    │   └── kafka-reporter-plugin-8.3.0.jar
    └── skywalking-agent.jar【应用的jar包】

目录结构说明:

activations 当前skywalking正在使用的功能组件。

agent.config 文件是 SkyWalking Agent 的唯一配置文件。

plugins 目录存储了当前 Agent 生效的插件。

optional-plugins 目录存储了一些可选的插件(这些插件可能会影响整个系统的性能或是有版权问题),如果需要使用这些插件,需将相应 jar 包移动到 plugins 目录下。

skywalking-agent.jar 是 Agent 的核心 jar 包,由它负责读取 agent.config 配置文件,加载上述插件 jar 包,运行时收集到 的 Trace 和 Metrics 数据也是由它发送到 OAP 集群的。

我们在使用Skywalking的时候,整个过程中都会用到skywalking-agent.jar,而无论是RPC还是HTTP开发的项目,用法都一样,因此我们讲解当前主流的SpringBoot项目对agent的使用即可。

3 agent应用

项目使用agent,如果是开发环境,可以使用IDEA集成,如果是生产环境,需要将项目打包上传到服务器。为了使用agent,我们同时需要将下载的apache-skywalking-apm-bin文件包上传到服务器上去。不过无论是开发环境还是生产环境使用agent,对项目都是无侵入式的。

3.1 应用名配置

我们需要用到agent,此时需要将agent/config/agent.config配置文件拷贝到每个需要集成Skywalking工程的resource目录下,我们将agent.config拷贝到工程\hailtaxi-parent的每个子工程目录下,并修改其中的 agent.service_name,修改如下:

hailtaxi-gateway:	agent.service_name=${SW_AGENT_NAME:hailtaxi-gateway}
hailtaxi-driver:	agent.service_name=${SW_AGENT_NAME:hailtaxi-driver}
hailtaxi-order:		agent.service_name=${SW_AGENT_NAME:hailtaxi-order}

agent.config 是一个 KV 结构的配置文件,类似于 properties 文件,value 部分使用 “${}” 包裹,其中使用冒号(":")分为两部分,前半部分是可以覆盖该配置项的系统环境变量名称,后半部分为默认值。例如这里的 agent.service_name 配置项,如果系统环境变量中指定了 SW_AGENT_NAME 值(注意,全是大写),则优先使用环境变量中指定的值,如果环境变量未指定,则使用 hailtaxi-driver 这个默认值。

直接把配置修改好后放到项目的resource目录下(或者其他路径)是最不容易才出错的一种方式,同时我们可以采用其他方式覆盖默认值:

1)JVM覆盖配置

例如这里的 agent.service_name 配置项,如果在 JVM 启动之前,明确中指定了下面的 JVM 配置:

# "skywalking."是 Skywalking环境变量的默认前缀
-Dskywalking.agent.service_name = hailtaxi-driver

2)探针配置覆盖

将 Java Agent 配置为如下:

# 默认格式是 -javaagent:agent.jar=[option1]=[value1],[option2]=[value2]
-javaagent:/path/skywalking-agent.jar=agent.service_name=hailtaxi-driver

此时会使用该 Java Agent 配置值覆盖 agent.config 配置文件中 agent.service_name 默认值。

但是这些配置都有不同优先级,优先级如下:

探针配置 > JVM配置 > 系统环境变量配置 > agent.config文件默认值

3.2 IDEA集成使用agent

1、修改agent中数据收集服务的地址:agent/config/agent.confg

collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:192.168.200.129:11800}

当然也可以同构JVM参数配置

2、使用探针配置为3个项目分别配置agent:

1)hailtaxi-driver:

-javaagent:C:\developer\skywalking\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=hailtaxi-driver

将上面配置赋值到IDEA中:

file

2)hailtaxi-order

-javaagent:C:\developer\skywalking\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=hailtaxi-order

将上面配置赋值到IDEA中:

file

3)hailtaxi-gateway

-javaagent:C:\developer\skywalking\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=hailtaxi-gateway

将上面配置赋值到IDEA中:

file

此时启动IDEA,并访问:http://192.168.200.129:8080 效果如下:

file

如果你要追踪Gateway的话,你会发现:无法通过gateway发现路由的服务链路?

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

方案:将agent/optional-plugins下的两个插件 复制到 agent/plugins目录下

3.3 生产环境使用agent

生产环境使用,因此我们需要将agent和每个项目的jar包上传到服务器上,上传apache-skywalking-apm-bin/usr/local/server/skywalking,再将工程\hailtaxi-parent中的项目打包,并分别上传到服务器上,如下三个工程:

hailtaxi-order-1.0-SNAPSHOT.jar
hailtaxi-gateway-1.0-SNAPSHOT.jar
hailtaxi-driver-1.0-SNAPSHOT.jar

1)启动hailtaxi-gateway

java -javaagent:/usr/local/server/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar -Dskywalking.agent.service_name=hailtaxi-gateway -jar hailtaxi-gateway-1.0-SNAPSHOT.jar &

2)启动hailtaxi-driver

java -javaagent:/usr/local/server/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar -Dskywalking.agent.service_name=hailtaxi-driver -jar hailtaxi-driver-1.0-SNAPSHOT.jar &

3)启动hailtaxi-order

java -javaagent:/usr/local/server/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar -Dskywalking.agent.service_name=hailtaxi-order -jar hailtaxi-order-1.0-SNAPSHOT.jar &

4 Rocketbot

前面我们已经完成了SkyWalking环境搭建和项目应用agent使用,我们来看如何使用 SkyWalking 提供的 UI 界面—— Skywalking Rocketbot。

OAP服务和Rocket(其实就是个web项目)均已启动

file

4.1 Rocketbot-仪表盘

具体细则可参考资料:Skywalking仪表盘使用

file

Rocketbot从多个方面展示了服务信息,我们分别从多个方面进行讲解。

上图中的【仪表盘】、【拓扑图】、【追踪】、【性能剖析】、【日志】、【警告】属于功能菜单。

仪表盘属于数据统计功能,分别从服务热度、响应水平、服务个数、节点信息等展示统计数据。

  • Global Heatmap 面板:热力图,从全局展示了某段时间请求的热度。
  • Global Percent Response 面板 :展示了全局请求响应时间的 P99、P95、P75 等分位数。
  • Global Brief 面板:展示了 SkyWalking 能感知到的 Service、Endpoint 的个数。
  • Global Top Troughput 面板:展示了吞吐量前几名的服务。
  • Global Top Slow Endpoint 面板:展示了耗时前几名的 Endpoint。
  • Service (Avg) ResponseTime 面板:展示了指定服务的(平均)耗时。
  • Service (Avg) Throughput 面板:展示了指定服务的(平均)吞吐量。
  • Service (Avg) SLA 面板:展示了指定服务的(平均)SLA(Service Level Agreement,服务等级协议)。
  • Service Percent Response 面板:展示了指定服务响应时间的分位数。
  • Service Slow Endpoint 面板:展示了指定服务中耗时比较长的 Endpoint 信息。
  • Running ServiceInstance 面板:展示了指定服务下的实例信息。

除了 SkyWalking Rocketbot 默认提供的这些面板,我们还可以点击锁型按钮,自定义 Global 面板。在 ServiceInstance 面板中展示了很多 ServiceInstance 相关的监控信息,例如,JVM 内存使用情况、GC 次数、GC 耗时、CPU 使用率、ServiceInstance SLA 等等信息。

4.2 Rocketbot-拓扑图

file

【拓扑图】展示当前整个业务服务的拓扑图。点击拓扑图中的任意节点,可以看到服务相应的状态信息,其中包括响应的平均耗时、SLA 等监控信息。点击拓扑图中任意一条边,还可以看到一条调用链路的监控信息,其中会分别从客户端(上游调用方)和服务端(下游接收方)来观测这条调用链路的状态,其中展示了该条链路的耗时、吞吐量、SLA 等信息。

4.3 追踪

file

【追踪】主要用来查询 Trace 信息,如下图所示。在①处可以选择 Trace 的查询条件,其中可以指定 Trace 涉及到的 Service、ServiceInstance、Endpoint 以及Trace 的状态继续模糊查询,还可以指定 TraceId 和时间范围进行精确查询。在②处可以直接根据请求连接查找调用链路信息。在③处展示了 Trace 的简略信息。在④处可以选择不同的方式展示追踪信息。

在这里,我们不仅能看到调用链路信息,还能看到MySQL操作监控,如下图:

file

错误异常信息也能追踪,如下图:

file

4.4 性能分析

在传统的监控系统中,我们如果想要得知系统中的业务是否正常,会采用进程监控、日志收集分析等方式来对系统进行监控。当机器或者服务出现问题时,则会触发告警及时通知负责人。通过这种方式,我们可以得知具体哪些服务出现了问题。但是这时我们并不能得知具体的错误原因出在了哪里,开发人员或者运维人员需要到日志系统里面查看错误日志,甚至需要到真实的业务服务器上查看执行情况来解决问题。

如此一来,仅仅是发现问题的阶段,可能就会耗费相当长的时间;另外,发现问题但是并不能追溯到问题产生具体原因的情况,也常有发生。这样反反复复极其耗费时间和精力,为此我们便有了基于分布式追踪的APM系统。

通过将业务系统接入分布式追踪中,我们就像是给程序增加了一个放大镜功能,可以清晰看到真实业务请求的整体链路,包括请求时间、请求路径,甚至是操作数据库的语句都可以看得一清二楚。通过这种方式,我们结合告警便可以快速追踪到真实用户请求的完整链路信息,并且这些数据信息完全是持久化的,可以随时进行查询,复盘错误的原因。

然而随着我们对服务监控理解的加深,我们发现事情并没有那么简单。在分布式链路追踪中我们有这样的两个流派:代码埋点和字节码增强。无论使用哪种方式,底层逻辑一定都逃不过面向切面这个基础逻辑。因为只有这样才可以做到大面积的使用。这也就决定了它只能做到框架级别和RPC粒度的监控。这时我们可能依旧会遇到程序执行缓慢或者响应时间不稳定等情况,但无法具体查询到原因。这时候,大家很自然的会考虑到增加埋点粒度,比如对所有的Spring Bean方法、甚至主要的业务层方法都加上埋点。但是这种思路会遇到不小的挑战:

第一,增加埋点时系统开销大,埋点覆盖不够全面。通过这种方式我们确实可以做到具体业务场景具体分析。但随着业务不断迭代上线,弊端也很明显:大量的埋点无疑会加大系统资源的开销,造成CPU、内存使用率增加,更有可能拖慢整个链路的执行效率。虽然每个埋点消耗的性能很小,在微秒级别,但是因为数量的增加,甚至因为业务代码重用造成重复埋点或者循环使用,此时的性能开销已经无法忽略。

第二,动态埋点作为一项埋点技术,和手动埋点的性能消耗上十分类似,只是减少的代码修改量,但是因为通用技术的特别,上一个挑战中提到的循环埋点和重复使用的场景甚至更为严重。比如选择所有方法或者特定包下的所有方法埋点,很可能造成系统性能彻底崩溃。

第三,即使我们通过合理设计和埋点,解决了上述问题,但是JDK函数是广泛使用的,我们很难限制对JDK API的使用场景。对JDK过多方法、特别是非RPC方法的监控会造成系统的巨大延迟风险。而且有一些基础类型和底层工具类,是很难通过字节码进行增强的。当我们的SDK使用不当或者出现bug时,我们无法具体得知真实的错误原因。

Skywalking中可以使用性能剖析分析特定端点的性能,我们需要先创建一个监控任务:

file

新建任务后,在右侧可以查看任务性能分析报表,还可以点击分析线程栈信息,如下图:

file

4.5 告警

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

  1. 告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件。
  2. Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知

4.5.1 警告规则详解

Skywalking每隔一段时间根据收集到的链路追踪的数据和配置的告警规则(如服务响应时间、服务响应时间百分比)等,判断如果达到阈值则发送相应的告警信息。发送告警信息是通过调用webhook接口完成,具体的webhook接口可以使用者自行定义,从而开发者可以在指定的webhook接口中编写各种告警方式,比如邮件、短信等。告警的信息也可以在RocketBot中查看到。

我们可以进入到Skywalking容器中,再进入到config文件夹下就可以看到alarm-settings.yml,如下图:

file

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

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Sample alarm rules.
rules:
  # Rule unique name, must be ended with `_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.
  service_sla_rule:
    # Metrics value need to be long, double or int
    metrics-name: service_sla
    op: "<"
    threshold: 8000
    # The length of time to evaluate the metrics
    period: 10
    # How many times after the metrics match the condition, will trigger alarm
    count: 2
    # How many times of checks, the alarm keeps silence after alarm triggered, default as same as period.
    silence-period: 3
    message: Successful rate of service {name} is lower than 80% in 2 minutes of last 10 minutes
  service_resp_time_percentile_rule:
    # Metrics value need to be long, double or int
    metrics-name: service_percentile
    op: ">"
    threshold: 1000,1000,1000,1000,1000
    period: 10
    count: 3
    silence-period: 5
    message: Percentile response time of service {name} alarm in 3 minutes of last 10 minutes, due to more than one condition of p50 > 1000, p75 > 1000, p90 > 1000, p95 > 1000, p99 > 1000
  service_instance_resp_time_rule:
    metrics-name: service_instance_resp_time
    op: ">"
    threshold: 1000
    period: 10
    count: 2
    silence-period: 5
    message: Response time of service instance {name} is more than 1000ms in 2 minutes of last 10 minutes
#  Active endpoint related metrics alarm will cost more memory than service and service instance metrics alarm.
#  Because the number of endpoint is much more than service and instance.
#
#  endpoint_avg_rule:
#    metrics-name: endpoint_avg
#    op: ">"
#    threshold: 1000
#    period: 10
#    count: 2
#    silence-period: 5
#    message: Response time of endpoint {name} is more than 1000ms in 2 minutes of last 10 minutes

webhooks:
#  - http://127.0.0.1/notify/
#  - http://127.0.0.1/go-wechat/

告警规则配置项的说明:

  • **Rule name:**规则名称,也是在告警信息中显示的唯一名称。必须以_rule结尾,前缀可自定义
  • **Metrics name:**度量名称,取值为oal脚本中的度量名,目前只支持longdoubleint类型。
  • **Include names:**该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为全部)
  • **Exclude names:**该规则作不用于哪些实体名称,比如服务名,终端名(可选,默认为空)
  • **Threshold:**阈值
  • OP: 操作符,目前支持 ><=
  • **Period:**多久告警规则需要被核实一下。这是一个时间窗口,与后端部署环境时间相匹配
  • **Count:**在一个Period窗口中,如果values超过Threshold值(按op),达到Count值,需要发送警报
  • **Silence period:**在时间N中触发报警后,在TN -> TN + period这个阶段不告警。 默认情况下,它和Period一样,这意味着相同的告警(在同一个Metrics name拥有相同的Id)在同一个Period内只会触发一次
  • **message:**告警消息

在配置文件中预先定义的告警规则总结如下:

  1. 在过去10分钟内服务平均响应时间超过1秒达3次
  2. 在过去10分钟内服务成功率低于80%达2次
  3. 在过去10分钟内服务90%响应时间低于1秒达3次
  4. 在过去10分钟内服务的响应时间超过1秒达2次
  5. 在过去10分钟内端点的响应时间超过1秒达2次

这些警告信息最终会在Skywalking-UI上展示,效果如下:

file

4.5.2 Webhook规则

Webhook配置其实是警告消息接收回调处理,我们可以在程序中写一个方法接收警告信息,Skywalking会以application/json格式通过http请求发送,消息格式声明为:List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage

字段如下:

  • scopeId, scope: 所有的scope实体在 org.apache.skywalking.oap.server.core.source.DefaultScopeDefine 里面声明。
  • name. 目标scope实体名称。
  • id0: scope实体ID,匹配名称。
  • id1: 不使用。
  • ruleName: 配置在 alarm-settings.yml 里面的规则名称.
  • alarmMessage: 告警信息.
  • startTime:触发告警的时间 示例:
[
  {
    "scopeId": 2,
    "scope": "SERVICE_INSTANCE",
    "name": "c00158f28efc45cd813e21b6b8848a3a@192.168.1.104 of hailtaxi-driver",
    "id0": "aGFpbHpdmVy.1_YzAwMAMTkyLjE2OC4xLjEwNA\u003d\u003d",
    "id1": "",
    "ruleName": "service_instance_resp_time_rule",
    "alarmMessage": "Response time of service instance c00158f28efc45cd813e21b6b8848a3a@192.168.1.104 of hailtaxi-driver is more than 1000ms in 2 minutes of last 10 minutes",
    "startTime": 1611612258056
  }
]

4.5.3 自定义Webhook消息接收

我们按照如下步骤,可以在自己程序中接收警告信息:

1)定义消息接收对象

hailtaxi-api中创建com.itheima.skywalking.model.AlarmMessage,代码如下:

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class AlarmMessage {
    private int scopeId;
    private String name;
    private String id0;
    private String id1;
    private String alarmMessage;
    private long startTime;
    String ruleName;
}

2)接收警告方法创建

hailtaxi-driver中创建com.itheima.driver.controller.AlarmMessageController用于接收警告消息,代码如下:

一般情况下,这种接收告警的api会被放置在比较清闲的后台服务中!!!

@RestController
@RequestMapping(value = "/skywalking")
public class AlarmMessageController {

    /***
     * 接收警告信息
     * @param alarmMessageList
     */
    @PostMapping("/webhook")
    public void webhook(@RequestBody List<AlarmMessage> alarmMessageList) {
        for (AlarmMessage alarmMessage : alarmMessageList) {
            System.out.println("webhook:"+alarmMessage);
        }
    }
}

3)修改Webhook地址

修改alarm-settings.yml中的webhook地址:

webhooks:
#  - http://127.0.0.1/notify/
#  - http://127.0.0.1/go-wechat/
   - http://192.168.200.10:8001/driver/skywalking/webhook

因为skywalking默认有一个告警规则:10分钟内服务成功率低于80%超过2次

所以为了能演示出告警效果,我们在hailtaxi-driver项目中的driver/info接口中添加一个一句话

/****
   * 司机信息
   */
  //@GetMapping(value = "/info/{id}")
  @RequestMapping(value = "/info/{id}")
  public Driver info(@PathVariable(value = "id")String id,HttpServletRequest request){
      int i = 1/ 0; // 产生异常
      Enumeration<String> headerNames = request.getHeaderNames();
      while (headerNames.hasMoreElements()){
          String name = headerNames.nextElement();
          String value = request.getHeader(name);
          System.out.println(name+":"+value);
          System.out.println("--------------------------");
      }
      return driverService.findById(id);
  }

测试时将网关的条件断言给注释一下!!!

此时我们程序中就能接收警告信息了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/971385.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微服务·架构组件之服务注册与发现-Nacos

微服务组件架构之服务注册与发现之Nacos Nacos服务注册与发现流程 服务注册&#xff1a;Nacos 客户端会通过发送REST请求的方式向Nacos Server注册自己的服务&#xff0c;提供自身的元数据&#xff0c;比如ip地址、端口等信息。 Nacos Server接收到注册请求后&#xff0c;就会…

ChatGPT 案例实战趋势分析面积图制作

面积图使用HTML,JS,Echarts 来完成代码可以使用ChatGPT AIGC 来实现代码编写。 完整的代码复制如下: <!DOCTYPE html> <html> <head><meta charset="utf-8"><script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.2.2/echa…

EasyPOI处理excel、CSV导入导出

1 简介 使用POI在导出导出excel、导出csv、word时代码有点过于繁琐&#xff0c;好消息是近两年在开发市场上流行一种简化POI开发的类库&#xff1a;easyPOI。从名称上就能发现就是为了简化开发。 能干什么&#xff1f; Excel的快速导入导出,Excel模板导出,Word模板导出,可以…

【kubernetes】Harbor部署及KubeSphere使用私有仓库Harbor

私有仓库Harbor https://goharbor.io/ 内容学习于马士兵云原生课程 Harbor部署 部署docker及docker-compose 略 获取Harbor安装文件 https://github.com/goharbor/harbor/releases/download/v2.4.1/harbor-offline-installer-v2.4.1.tgz tar -zxvf harbor-offline-installe…

线程安全缓存ConcurrentLinkedHashMap,Kotlin

线程安全缓存ConcurrentLinkedHashMap&#xff0c;Kotlin LinkedHashMap实现LRU缓存cache机制&#xff0c;Kotlin_zhangphil的博客-CSDN博客* * 基于Java LinkedList,实现Android大数据缓存策略 * 作者&#xff1a;Zhang Phil * 原文出处&#xff1a;http://blog.csdn.net/zha…

无法将类型为“Newtonsoft.Json.Linq.JObject”的对象转换为类型“Newtonsoft.Json.Linq.JArray”解决方法

对于“Newtonsoft.Json.Linq.JObject”的对象强制类型转换为类型“Newtonsoft.Json.Linq.JArray”报错 第一的图为对象{“*************”:“********”} 第二个图片为数组[{“…”:“…”}] 在我这里进行强制转换对象转换为类型“Newtonsoft.Json.Linq.JArray”报错. 那我们…

【java】【项目实战】[外卖十一]项目优化(Ngnix)

目录 一、Nginx概述 1、Nginx介绍 2、Nginx下载和安装 3、Nginx目录结构 二、Nginx命令 1、查看版本 2、检查配置文件正确性 3、启动和停止 4、重新加载配置文件 三、Nginx配置文件结构 1、全局块 2、events块 3、http块 四、Nginx具体应用 1、部署静态资源 2、…

mysql基于AES_ENCRYPTAES_DECRYPT实现密码的加密与解密

1.直接使用AES_ENCRYPT&&AES_DECRYPT函数导致的问题。 执行语句 select AES_ENCRYPT(cd123,key) 结果 加密过后的字符串是一串很奇怪的字符。 尝试使用上面加密过后的字符解密。 select AES_DECRYPT(u5£d|#,key) 结果 并未成功的解密 2.解决办法 使用 hex(…

kubernetes——RBAC鉴权

简介 基于角色的访问控制(RBAC)是一种基于组织中各个用户的角色来调节对计算机或网络资源的访问的方法。 目的&#xff1a;防止k8s里的pod&#xff08;会运行程序&#xff09;能随意获取整个集群里的信息和访问集群里的资源 概念 Rule&#xff1a;规则&#xff0c;一组属于…

图解SQL查询之模糊查询技巧:如何使用LIKE对数据进行筛选

模糊查询是一种特殊的条件查询方式&#xff0c;它允许根据模式匹配来查找符合特定条件的数据。在 SQL 中&#xff0c;我们使用 LIKE 关键字来进行模糊查询。在 LIKE 模糊查询中&#xff0c;有两种常用的通配符&#xff1a; 百分号&#xff08;%&#xff09;&#xff1a;表示任…

合宙Air724UG LuatOS-Air LVGL API控件-图片 (Image)

图片 (Image) 图片IMG是用于显示图像的基本对象类型&#xff0c;图像来源可以是文件&#xff0c;或者定义的符号。 示例代码 -- 创建图片控件 img lvgl.img_create(lvgl.scr_act(), nil) -- 设置图片显示的图像 lvgl.img_set_src(img, "/lua/luatos.png") -- 图片…

SpringMVC:从入门到精通

一、SpringMVC是什么 SpringMVC是Spring提供的一个强大而灵活的web框架&#xff0c;借助于注解&#xff0c;Spring MVC提供了几乎是POJO的开发模式【POJO是指简单Java对象&#xff08;Plain Old Java Objects、pure old java object 或者 plain ordinary java object&#xff0…

社区团购新玩法,生鲜蔬菜配货发货小程序商城

在当前的电商市场中&#xff0c;生鲜市场具有巨大的潜力和发展空间。为了满足消费者的需求&#xff0c;许多生鲜店正在寻找创新的方法来提高销售和客户满意度。其中&#xff0c;制作一个个性且功能强大的生鲜小程序商城是一个非常有效的策略。以下是在乔拓云平台上制作生鲜小程…

#systemverilog# 之 event region 和 timeslot 仿真调度(九)assign 赋值 和 always 组合赋值的调度区别

有时候,我们会发现一个问题,举个最简单的例子:比如将两个信号进行简单的异或运算。该逻辑运算,我们可以使用 assign 数据流建模完成,也可以使用always 组合逻辑过程赋值语句实现。那仿真工具在对它进行调度的时候,有什么区别吗? 不慌,今天,我们举个例子,来验证这一点…

2023 最新前端面试题 (HTML 篇)

1. src 和 href 的区别 src 用于替换当前元素&#xff08;引入&#xff09;&#xff0c;href 用于在当前文档和引用资源之间确立联系&#xff08;引用&#xff09; &#xff08;1&#xff09;src&#xff08;source&#xff09; 指向外部资源的位置&#xff0c;指向的内容将会嵌…

Python爬虫——新手使用代理ip详细教程

Python代理IP爬虫是一种可以让爬虫拥有更多网络访问权限的技术。代理IP的作用是可以为爬虫提供多个IP地址&#xff0c;从而加快其爬取数据的速度&#xff0c;同时也可以避免因为访问频率过高而被网站封禁的问题。本文将介绍如何使用Python实现代理IP的爬取和使用。 一、代理IP的…

ArrayList底层实现原理

ArrayList ArrayList最早出现在 JDK 1.2中&#xff0c;底层基于数组实现&#xff0c;它是一个动态数组列表结构的容器。 元素有序&#xff0c;可重复增删元素的速度慢。每次增加删除元素&#xff0c;都需要更改数组长度、拷贝元素及移动元素位置。查询元素的速度快。底层数据…

qt简易网络聊天室 数据库的练习

qt网络聊天室 服务器&#xff1a; 配置文件.pro QT core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exac…

酷派30/锋尚40/大观40S首发解锁BL+完美root权限+去除密码黑砖线刷修复

早前的中华酷联&#xff0c;随着时代的发展&#xff0c;酷派手机虽热发展的并没有其他手机那么快&#xff0c;但也 是坚强的活了下来。目前主打机型为Cool系列&#xff0c;最高为Cool30机型&#xff0c;并且发布酷派锋尚 40酷派大观40S&#xff0c;起头并进。该系列机型&#x…

动手学深度学习(五)Kaggle房价预测

Kaggle房价数据集&#xff0c;前四个为房价特征&#xff0c;最后一个为标签&#xff08;房价&#xff09;。 一、下载数据集 import numpy as np import pandas as pd import torch from torch import nn from d2l import torch as d2l import hashlib import os import tarfi…