基于Skywalking的全链路跟踪实现

在前文“分布式应用全链路跟踪实现”中介绍了分布式应用全链路跟踪的几种实现方法,本文将重点介绍基于Skywalking的全链路实现,包括Skywalking的整体架构和基本概念原理、Skywalking环境部署、SpringBoot和Python集成Skywalking监控实现等。


1、Skywalking基本介绍
1.1 Skywalking整体架构

在这里插入图片描述
Skywalking 8.x版本架构图

SkyWalking整体架构在逻辑上分为四部分:探针Agent、平台后端OAP、存储和UI界面

  • 探针Agent:负责从应用中收集链路信息,并发送给SkyWalking的OAP服务器。它会收集Tracing和Metrics数据,将数据格式化为SkyWalking适用的格式。探针安装在服务所在的服务器上,以方便数据的获取。
  • 平台后端OAP:接收探针发送的数据,并在内存中使用分析引擎进行数据的整合运算,然后将数据存储到对应的存储介质上。OAP支持数据聚合、数据分析以及驱动数据流从探针到用户界面的流程。分析包括Skywalking原生链路跟踪和性能指标以及第三方来源,包括Istio及 Envoy telemetry、Zipkin链路跟踪格式化等。
  • 存储:通过开放的插件化的接口存放SkyWalking数据,目前支持的存储器有Elasticsearch、MySQL、ShardingSphere、TiDB、H2等。
  • 用户界面UI:负责提供控制台,查看链路、服务指标等。UI是一个基于接口高度定制化的Web系统,用户可以可视化查看和管理SkyWalking数据。
1.2 Skywalking基本概念
1.2.1 Skywalking中的核心概念

与Prometheus不同,SkyWalking的度量机制是围绕以下具有层次结构的核心概念构建的:

  • 层(Layer):表示计算机科学中的一个抽象框架,如 Operating System(OS_LINUX 层)、Kubernetes(k8s层)。该层将是从不同技术检测到的不同服务的所有者。
  • 服务:表示一组或一组工作负载,它为传入请求提供相同的行为。
  • 服务实例(Service Instance):服务组中的单个工作负载。
  • 端点(Endpoint):传入请求的服务路径。
  • 进程:操作系统进程。在某些场景下,service instance不是一个进程,比如一个 Kubernetes Pod可能包含多个进程。
1.2.2 Skywalking中的指标流

Metric名称和属性(标签)由SkyWalking OAP服务器根据数据源以及OAL和MAL配置。SkyWalking 提供了对时间序列指标进行下采样(down-sampling),并生成不同时间段数据(分钟、小时、天)的能力。SkyWalking指标流如下:

在这里插入图片描述

2、Skywalking原理解析
2.1 Skywalking中Trace实现

Skywalking中实现了OpenTracing中的Trace、Span、Tags、Logs等核心概念,不同之处是在Trace级别和Span级别之间加了一个Segment概念,用于表示一个服务实例内的Span集合。

2.1.1 Trace ID

在Skywalking中,全局ID由三个 long 类型的字段(part1、part2、part3)构成,分别记录了ServiceInstanceId、Thread ID和Context生成序列,格式如下所示:

${ServiceInstanceId}.${Thread ID}.(${时间戳} * 10000 + 线程自增序列([0, 9999]))
2.1.2 TraceSegment

在SkyWalking中,TraceSegment是一个介于Trace与Span之间的概念,它是一条Trace的一段,可以包含多个Span。在微服务架构中,一个请求基本都会涉及跨进程(以及跨线程)的操作,例如,RPC调用、通过MQ异步执行、HTTP请求远端资源等,处理一个请求就需要涉及到多个服务的多个线程。TraceSegment记录了一个请求在一个线程中的执行流程(即Trace信息)。将该请求关联的TraceSegment串联起来,就能得到该请求对应的完整Trace。

在这里插入图片描述

TraceSegment的核心结构如图所示,包括以下核心字段:

  • traceSegmentId(ID类型):TraceSegment的全局唯一标识
  • refs(List 类型):它指向父TraceSegment
  • relatedGlobalTraces(DistributedTraceIds类型):记录当前TraceSegment所属Trace的Trace ID。
  • spans(List类型):当前TraceSegment包含的所有Span。
  • ignore(boolean类型):ignore字段表示当前TraceSegment是否被忽略。
2.1.3 Context

SkyWalking中的每个TraceSegment都与一个Context上下文对象一对一绑定,Context上下文不仅记录了TraceSegment的上下文信息,还提供了管理TraceSegment生命周期、创建Span以及跨进程(跨线程)传播相关的功能。

2.2 Trace的收集和发送
2.2.1 Context的生成与采样

应用访问时,如果不做任何限制,每个请求都会生成一条完整的Trace。在面对海量的业务请求时会同步产生海量的Trace数据,对网络和存储都带来巨大的压力,因此几乎所有的Trace系统都支持采样功能。在Skywalking Agent中是通过SamplingService服务实现的,SamplingService的trySampling()方法递增samplingFactorHolder字段,当增加到阈值(默认值为3,可以通过agent.sample_n_per_3_secs配置进行修改)时会返回false,表示采样失,这时就会生成IgnoredTracerContext,IgnoredTracerContext是个空Context实现,不会记录Trace信息。

在这里插入图片描述

2.2.2 Trace的收集

当TracingContext通过stopSpan()方法关闭最后一个Span时,会调用finish()方法关闭相应的TraceSegment,与此同时,还会通知所有监听TracingContext关闭事件的监听器TracingContextListener。TraceSegmentServiceClient主要功能就是在TraceSegment结束时对其进行收集,并发送到后端的OAP集群。

在这里插入图片描述

2.3 Skywalking OAP内核架构

Skywalking OAP采用微内核架构,使用ModuleManager(组件管理器)管理多个Module(组件),一个Module可以对应多个ModuleProvider(组件服务提供者),ModuleProvider是Module底层真正的实现。

在这里插入图片描述

在OAP服务启动时,一个Module只能选择使用一个ModuleProvider对外提供服务。一个ModuleProvider可能支撑了一个非常复杂的大功能,在一个ModuleProvider中,可以包含多个Service,一个Service实现了一个ModuleProvider中的一部分功能,通过将多个Service进行组装集成,可以得到ModuleProvider的完整功能。

3、Skywalking环境部署

Skywalking测试demo环境如下所示,分别测试SpringBoot应用和Python程序的监控实现。

在这里插入图片描述

1)解压安装包,使用9.3.0版本

# tar -xzvf apache-skywalking-apm-9.3.0.tar.gz
# mv apache-skywalking-apm-bin/ /usr/local/skywalking

2)修改OAP配置文件,指定存储类型为MySQL

# vi config/application.yml
cluster:selector: ${SW_CLUSTER:standalone}
storage:selector: ${SW_STORAGE:mysql}mysql:properties:jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://192.168.112.121:3306/swtest?rewriteBatchedStatements=true&allowMultiQueries=true"}dataSource.user: ${SW_DATA_SOURCE_USER:root}dataSource.password: ${SW_DATA_SOURCE_PASSWORD:123456}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}

3)对Webapp进行配置

# vi webapp/application.yml
serverPort: ${SW_SERVER_PORT:-18080}
# Comma seperated list of OAP addresses.
oapServices: ${SW_OAP_ADDRESS:-http://192.168.112.121:12800}

默认使用8080端口访问,修改为18080

4)下载MySQL连接jar并拷贝到oap-libs

#下载链接:mysql-connector-java-8.0.28.jar
https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar
# cp mysql-connector-java-8.0.28.jar /usr/local/skywalking/oap-libs/

将jar包放在oap-libs目录下即可,如果没有连接jar包,会抛如下异常:

java.lang.RuntimeException: Failed to get driver instance for jdbcUrl=jdbc:mysql://localhost:3306/swtest?rewriteBatchedStatements=true&allowMultiQueries=true

5)连接mysql创建应用库swtest

# mysql -uroot -p
mysql> create database swtest;

在mysql中创建配置文件中的应用库swtest,否则会提示报错

com.zaxxer.hikari.pool.HikariPool - 574 [main] ERROR [] - HikariPool-1 - Exception during pool initialization.java.sql.SQLSyntaxErrorException: Unknown database 'swtest'

6)启动Skywalking服务
进入bin目录执行startup.sh文件即可启动SkyWalking平台

cd ../bin
./startup.sh

启动成功看log输出日志:

2023-11-04 16:06:18,455 - com.linecorp.armeria.common.util.SystemInfo - 237 [main] INFO  [] - hostname: tango-db01 (from /proc/sys/kernel/hostname)
2023-11-04 16:06:20,036 - com.linecorp.armeria.server.Server - 797 [armeria-boss-http-*:12800] INFO  [] - Serving HTTP at /0:0:0:0:0:0:0:0%0:12800 - http://127.0.0.1:12800/

再查看swtest库中,已经创建了很多表

mysql> show tables;
+--------------------------------------------------------+
| Tables_in_swtest                                       |
+--------------------------------------------------------+
| alarm_record                                           |
| alarm_record_tag                                       |
| browser_app_error_rate                                 |

7)访问UI页面,端口为18080:http://192.168.112.121:18080/

在这里插入图片描述

4、Skywalking全链路监控实现
4.1 SpringBoot应用集成Skywalking监控
4.1.1 环境准备

1)在mysql中创建表并插入数据

mysql> use sw_mysql;
Database changed
mysql> CREATE TABLE `sw_tb` ( -> `id` int(11) NOT NULL AUTO_INCREMENT, -> `username` varchar(50) DEFAULT NULL, -> `password` varchar(50) DEFAULT NULL,-> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8-> ;
Query OK, 0 rows affected, 2 warnings (0.03 sec)mysql> insert into sw_mysql.sw_tb(`username`,`password`) values('张三','AAA'),('李四','BBB'),('王五','CCC');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0mysql> select * from sw_mysql.sw_tb;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | 张三     | AAA      |
|  2 | 李四     | BBB      |
|  3 | 王五     | CCC      |
+----+----------+----------+
3 rows in set (0.00 sec)
4.1.2 在Eclipse中创建SpringBoot项目

1)在pom.xml文件中添加引入Skywalking的依赖包

		<dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>8.3.0</version></dependency><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-log4j-2.x</artifactId><version>8.3.0</version></dependency><dependency> <!-- 引入log4j2依赖 --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency>

2)配置trace

使用apm-toolkit-trace输出traceid信息,并修改log4j2.xml配置日志格式。这样会将traceid信息写入日志,用于后续的日志采集和集中分析。

    <Properties><!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符 %logger{36} 表示 Logger 名字最长36个字符--><!--1.文件输出格式--><property name="file_pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%traceId] [%thread] [%-5level]  %msg %l%n" /><!--2.控制台显示日志格式--><!--[%traceId]:追踪id--><!--[%sw_ctx]:打印为[$serviceName,$instanceName,$traceId,$traceSegmentId,$spanId]:服务名,实例名,追踪id,追踪片段id,跨度id--><property name="console_pattern" value="%red{%d{yyyy-MM-dd HH:mm:ss}} [%traceId] %green{[%thread]} %magenta{[%-5level]} %cyan{%msg} %l%n"/><!--3.skyWalking收集格式--><property name="skyWalking_pattern" value="%msg %l%n"/><!-- 定义日志存储的路径 --><property name="FILE_PATH" value="./log/spring-skywalking/" /><property name="FILE_NAME" value="spring-skywalking" /></Properties>

3)控制程序如下:

package com.tango.skywalking_mysql.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import com.tango.skywalking_mysql.SkywalkingMysqlApplication;import org.apache.logging.log4j.LogManager;  
import org.apache.logging.log4j.Logger;  @RestController
@RequestMapping("/demo")
public class DemoController {private static final Logger logger = LogManager.getLogger(SkywalkingMysqlApplication.class); @Autowiredprivate JdbcTemplate template;@GetMapping("/mysql")public String mysql() {String result="";try {this.selectById(1);System.out.println("skywalking-test!");logger.info("skywalking-test!");result="MySQL查询正常";} catch(Exception e) {System.out.println(e);logger.error(e);result="MySQL查询异常";}return result;}public Object selectById(Integer id) {return template.queryForObject("SELECT id, username, password FROM sw_tb WHERE id = ?",new BeanPropertyRowMapper<>(Object.class), id);}
}

4)在IDE配置中添加如下选项,配置Skywalking agent和服务的地址

-javaagent:D:\Skywalking-demo\skywalking-agent\skywalking-agent.jar
-Dskywalking.agent.service_name=skywalking-demo-service
-Dskywalking.collector.backend_service=192.168.112.121:11800

在这里插入图片描述

4.1.3 运行SpringBoot服务程序

1)运行应用后输出以下信息,表示agent启动成功

INFO 2023-11-04 17:11:44.918 main SkyWalkingAgent : Skywalking agent begin to install transformer ... 
Starting application skywalking_mysql
[31m2023-11-04 17:11:52[m [TID: N/A] [32m[main][m [35m[INFO ][m [36mStarting application skywalking_mysql[m com.tango.skywalking_mysql.SkywalkingMysqlApplication.main(SkywalkingMysqlApplication.java:13)

2)同时能够查看到日志中的traceid信息:

[31m2023-11-04 17:17:43[m [TID: e6978740bf3e41bfa6a53760e2d64b8a.44.16988302617370001] [32m[http-nio-18079-exec-1][m [35m[INFO ][m [36mskywalking-test![m com.tango.skywalking_mysql.controller.DemoController.mysql(DemoController.java:29)
skywalking-test!
[31m2023-11-04 17:20:39[m [TID: e6978740bf3e41bfa6a53760e2d64b8a.47.16988304392400001] [32m[http-nio-18079-exec-4][m [35m[INFO ][m [36mskywalking-test![m com.tango.skywalking_mysql.controller.DemoController.mysql(DemoController.java:29)
skywalking-test!

3)查看服务端的11800端口,已经有服务

[root@tango-DB01 config]# netstat -an|grep 11800
tcp6       0      0 :::11800                :::*                    LISTEN     
tcp6       0      0 192.168.112.121:11800   192.168.112.1:49590     ESTABLISHED

4)访问SpringBoot应用服务

每查询一次发起一笔业务访问:http://192.168.112.1:18079/demo/mysql

4.1.4 登录Skywalking监控服务运行情况

1)在Skywalking界面看到新的Service:skywalking-demo-service

在这里插入图片描述

2)查看服务的运行性能指标情况

在这里插入图片描述

3)查看服务的拓扑结构,这是一个访问mysql数据库的应用

在这里插入图片描述

4)查看trace信息

在这里插入图片描述

5)查看具体的SQL语句执行情况

在这里插入图片描述

4.2 Python应用集成Skywalking监控
4.2.1 Python程序中Agent配置

1)在Python程序中引入Skywalking Agent

from skywalking import agent,config#配置OAP服务信息
config.init(agent_collector_backend_services='192.168.112.121:11800', agent_name='skywalking-demo-python')
agent.start()
4.2.2 运行Python程序,在Skywalking监控服务运行情况

1)拓扑图如下所示,包括服务和mysql数据库

在这里插入图片描述

2)查看Trace信息

在这里插入图片描述

3)查看具体执行的SQL信息

在这里插入图片描述

4.2.3 代码实现

1)完整代码实现如下:

# -*- coding: utf-8 -*-import pymysql
import sys
import time
import codecs
import logging
import base64from skywalking import agent,config # 配置logging模块  
logging.basicConfig(filename='test.log', level=logging.INFO)  def getInfo(sql):ip="192.168.112.121"port=3306user="root"pwd=base64.decodebytes(b"MTIzNDU2Cg==").strip().decode('utf-8')dbname="sw_mysql"info = []conn = pymysql.connect(host=ip,port=port,user=user,passwd=pwd,database=dbname,charset='utf8')cursor = conn.cursor()try:cursor.execute(sql)info = cursor.fetchall()except Exception as e:print(e)conn.commit()cursor.close()conn.close()return infoif __name__ == '__main__':if sys.version[0] == "2":reload(sys)sys.setdefaultcoding("utf8")config.init(agent_collector_backend_services='192.168.112.121:11800', agent_name='skywalking-demo-python')agent.start()exec_sql = "select id,username,password from sw_mysql.sw_tb"while True:get_info = getInfo(exec_sql)if len(get_info) > 0:print(get_info[0])print("Success!")else:print("Error!")        time.sleep(5)agent.stop()

以上是基于Skywalking的全链路跟踪的简单指标采集实现。Skywalking功能强大,还具备拓扑关联分析、分布式跟踪和上下文传播、告警等功能,值得深入研究。


参考资料:

  1. https://github.com/apache/skywalking
  2. https://github.com/SkyAPM/document-cn-translation-of-skywalking
  3. https://skywalking.apache.org/docs/skywalking-python
  4. https://blog.csdn.net/weixin_42073629/article/details/106775584

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

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

相关文章

uni-app学习笔记(二)

目录 一、路由与页面跳转 1、tabar与普通页面跳转例子 2、navigateTo 3、switchTab 二、vue组件 1、传统vue组件的使用 2、easycom 三、uView组件库 1、安装配置 2、引入配置 3、使用 四、Vuex 1、认识 2、state基本使用 3、mapState使用 五、网络请求 1、封装…

网际报文协议ICMP及ICMP重定向实例详解

目录 1、ICMP的概念 2、ICMP重定向 3、利用ICMP重定向进行攻击的原理 4、如何禁止ICMP重定向功能&#xff1f; 4.1、在Linux系统中禁用 4.2、在Windows系统中禁用 5、关于ICMP重定向的问题实例 VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xf…

iOS如何通过在线状态来监听其他设备登录的状态

前提条件 1、完成 3.9.1 或以上版本 SDK 初始化 2、了解环信即时通讯 IM API 的 使用限制。 3、已联系商务开通在线状态订阅功能 实现方法 你可以通过调用 subscribe 方法订阅自己的在线状态&#xff0c;从而可以监听到其他设备在登录和离线时的回调&#xff0c;示例代码如下…

如何在CentOS上安装SQL Server数据库并通过内网穿透工具实现远程访问

文章目录 前言1. 安装sql server2. 局域网测试连接3. 安装cpolar内网穿透4. 将sqlserver映射到公网5. 公网远程连接6.固定连接公网地址7.使用固定公网地址连接 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;…

京东商品详情API,页面信息采集,优惠券信息获取

京东开放平台提供了API接口来访问京东商品详情。通过这个接口&#xff0c;您可以获取到商品的详细信息&#xff0c;如商品名称、价格、库存量、描述等。额外还附加一个优惠券信息接口。代码如下: 京东获得JD商品详情 API 优惠券接口 公共参数 名称类型必须描述keyString是调…

台式电脑怎么无损备份迁移系统到新硬盘(使用傲梅,免费的就可以)

文章目录 前言一、想要将源硬盘上的系统原封不动地迁移到新硬盘上二、准备工作2.具体步骤 总结 前言 半路接手公司一台台式电脑&#xff0c;C盘&#xff08;120g&#xff09;爆红&#xff0c;仅剩几个G&#xff0c;优化了几次&#xff0c;无果后。准备换一个大一点的增到500g。…

SQL 注入漏洞详解

SQL 注入漏洞详解 漏洞描述 sql注入漏洞是指恶意用户在应用与数据库交互的地方利用非法的操作获取数据库内容从以下两点分析: 没有对用户输入的数据进行充分的过滤和验证&#xff0c;导致一些用户利用此漏洞向数据库插入恶意sql语句非法请求数据库从而获得一些敏感数据在与数…

变电站自动化系统中的安全措施分析及应用-安科瑞

安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;阐述变电运行中的问题&#xff0c;电气自动化系统与安全运行措施&#xff0c;包括自动控制设备的投入&#xff0c;电气自动 化与计算机技术相、设备数据的采集与处理、自动化系统的升级、人工智能技术的应用。 关键…

Android 内存泄漏分析思路和案例剖析

分析思路 内存泄漏是指 Android 进程中&#xff0c;某些对象已经不再使用&#xff0c;但被一些生命周期更长的对象引用&#xff0c;导致其占用的内存资源无法被GC回收&#xff0c;内存占用不断增加的一种现象&#xff1b;内存泄漏是导致我们应用性能下降、卡顿的一种常见因素&…

C语言 每日一题 11.9 day15

数组元素循环右移问题 一个数组A中存有N&#xff08; > 0&#xff09;个整数&#xff0c;在不允许使用另外数组的前提下&#xff0c;将每个整数循环向右移M&#xff08;≥0&#xff09;个位置&#xff0c;即将A中的数据由&#xff08;A0​A1⋯AN−1&#xff09;变换为&…

【Mysql】增删改查(基础版)

我使用的工具是Data Grip &#xff08;SQLyog Naivact 都行&#xff09; 使用Data Grip创建student表&#xff0c;具体步骤如下&#xff08;熟悉Data Grip或者使用SQLyog&#xff0c;Naivact可以跳过&#xff09; https://blog.csdn.net/m0_67930426/article/details/13429…

高速信号PCB布局怎么布?(电子硬件)

对于高速信号&#xff0c;pcb的设计要求会更多&#xff0c;因为高速信号很容易收到其他外在因素的干扰&#xff0c;导致实际设计出来的东西和原本预期的效果相差很多。 所以在高速信号pcb设计中&#xff0c;需要提前考虑好整体的布局布线&#xff0c;良好的布局可以很好的决定布…

物联网AI MicroPython学习之语法 ucollections集合和容器类型

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; ucollections 介绍 ucollections 模块用于创建一个新的容器类型&#xff0c;用于保存各种对象。 接口说明 namedtuple - 创建一个新namedtuple容器类型 函数原型&#xff1a; 创建一个具有特定名称和一组…

天津WEB前端培训哪家好?Web机构推荐!

05年以后&#xff0c;互联网已经进入了web2.0时代&#xff0c;同时也标志着网站的前端由此发生了翻天覆地的变化&#xff0c;现在市场上对WEB前端开发工程师岗位有着很大的需求&#xff0c;学习web前端开发的方式有很多种&#xff0c;对于初学者来说&#xff0c;选择自学还是培…

Spring Cloud - 手写 Gateway 源码,实现自定义局部 FilterFactory

目录 一、FilterFactory 分析 1.1、前置知识 1.2、分析源码 1.2.1、整体分析 1.2.2、源码分析 1.3、手写源码 1.3.1、基础框架 1.3.2、实现自定义局部过滤器 1.3.3、加参数的自定义局部过滤器器 一、FilterFactory 分析 1.1、前置知识 前面的学习我们知道&#xff0c…

AI:65-基于机器学习预测股市行情

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

Go基础知识全面总结

文章目录 go基本数据类型bool类型数值型字符字符串 数据类型的转换运算符和表达式1. 算数运算符2.关系运算符3. 逻辑运算符4. 位运算符5. 赋值运算符6. 其他运算符运算符优先级转义符 go基本数据类型 bool类型 布尔型的值只可以是常量 true 或者 false。⼀个简单的例⼦&#…

win10语言切换调整为像win7一样,设置纯英文键盘切换,使用ctrol+shift切换键盘

文章目录 引入键盘布局说明安装美式键盘去掉微软键盘&#xff0c;修改布局切换快捷键最终效果 引入 我们在玩游戏或者写代码的时候&#xff0c;常常需要使用shift键&#xff0c;而输入法的shift键常常是中英切换按键&#xff0c;这就让人非常不爽了&#xff0c;这里仿照在win7…

【Git】快速入门安装及使用git与svn的区别常用命令

一、导言 1、什么是svn&#xff1f; SVN是Subversion的简称&#xff0c;是一个集中式版本控制系统。与Git不同&#xff0c;SVN没有分布式的特性。在SVN中&#xff0c;项目的代码仓库位于服务器上&#xff0c;团队成员通过向服务器提交和获取代码来实现版本控制。SVN记录了每个文…

Android Glide transform旋转rotate圆图CircleCrop,Kotlin

Android Glide transform旋转rotate圆图CircleCrop&#xff0c;Kotlin import android.graphics.Bitmap import android.os.Bundle import android.util.Log import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import com.bumptech.glide.load…