【字节青训营-7】:初探 Kitex 字节微服务框架(使用ETCD进行服务注册与发现)
本文目录
- 一、Kitex概述
- 二、第一个Kitex应用
- 三、IDL
- 四、服务注册与发现
一、Kitex概述
长话短说,就是字节跳动内部的 Golang 微服务 RPC 框架,具有高性能、强可扩展的特点,在字节内部已广泛使用。
如果对微服务性能有要求,又希望定制扩展融入自己的治理体系,Kitex 会是一个不错的选择。
可以看到下面是Kitex的架构设计。
这个框架有一些特点,比如:
- 高性能
使用自研的高性能网络库 Netpoll,性能相较 go net 具有显著优势。
- 扩展性
提供了较多的扩展接口以及默认扩展实现,使用者也可以根据需要自行定制扩展,具体见下面的框架扩展。
- 多消息协议
RPC 消息协议默认支持 Thrift、Kitex Protobuf、gRPC。Thrift 支持 Buffered 和 Framed 二进制协议,与支持原生 Thrift 协议的多语言框架都能互通; Kitex Protobuf 是 Kitex 自定义的 Protobuf 消息协议,协议格式类似 Thrift;gRPC 是对 gRPC 消息协议的支持,可以与 gRPC 互通。除此之外,使用者也可以扩展自己的消息协议,目前社区也提供了 Dubbo 协议的支持,可以与 Dubbo 互通。
- 多传输协议
传输协议封装消息协议进行 RPC 互通,传输协议可以额外透传元信息,用于服务治理,Kitex 支持的传输协议有 TTHeader、HTTP2。TTHeader 可以和 Thrift、Kitex Protobuf 结合使用;HTTP2 目前主要是结合 gRPC 协议使用,后续也会支持 Thrift。
- 多种消息类型
支持 PingPong、Oneway、双向 Streaming。其中 Oneway 目前只对 Thrift 协议支持,双向 Streaming 只对 gRPC 支持,后续会考虑支持 Thrift 的双向 Streaming。
- 服务治理
支持服务注册/发现、负载均衡、熔断、限流、重试、监控、链路跟踪、日志、诊断等服务治理模块,大部分均已提供默认扩展,使用者可选择集成。
- 代码生成
Kitex 内置代码生成工具,可支持生成 Thrift、Protobuf 以及脚手架代码。
二、第一个Kitex应用
首先我们创建一个新的Go项目,然后安装对应的插件:kitex
和thriftgo
。
然后在终端输入对应的安装命令:
go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
go install github.com/cloudwego/thriftgo@latest
然后等待对应的安装即可。
在项目路径下安装新建thrift文件,然后输入如下代码:
namespace go apistruct Request{1:string message
}struct Response{1:string message
}service Echo{Response echo(1:Request req)
}
简单来说,这段代码定义一个简单的服务 Echo,它包含一个方法 echo。这个方法接收一个 Request 类型的对象作为输入,处理后返回一个 Response 类型的对象。Request 和 Response 都包含一个字符串字段 message,分别用于传递请求消息和响应消息。这种定义方式使得 Thrift 可以生成不同语言的代码(例如 Go、Java、Python 等),方便跨语言的服务调用。
然后在命令行输入命令:
kitex -module exampleKitex -service exampleKitex echo.thrift
来生成基本的代码。
等待一会后,可以看到目录已经更新了。
在main.go
中输入如下代码:
package mainimport (api "exampleKitex/kitex_gen/api/echo""log"
)
/*api.NewServer 是一个函数,用于创建一个新的服务实例。new(EchoImpl) 创建了一个 EchoImpl 类型的实例,并将其传递给 api.NewServer。调用 svr.Run() 方法启动服务。
*/
func main() {svr := api.NewServer(new(EchoImpl))err := svr.Run()if err != nil {log.Println(err.Error())}
}
如果有报错,可以输入go mod tidy
来补充对应需要的库。
然后在handler.go
中来输入逻辑代码。
(s *EchoImpl):这是方法的接收者,表示这个方法属于 EchoImpl 类型的指针 s。
EchoImpl 是一个结构体类型,通常是由 Thrift 生成的接口的具体实现。
echo是方法名称,对应 Thrift 定义中的 echo 方法。
ctx context.Context:这是方法的第一个参数,类型为 context.Context。
context 是 Go 标准库中的一个包,用于在程序中传递上下文信息,例如超时、取消信号等。
req *api.Request:这是方法的第二个参数,类型为 *api.Request,表示这是一个指向 api.Request 类型的指针。
api.Request 是 Thrift 定义的 Request 结构体,通过 Thrift 生成的 Go 代码中的 api 包来访问。&api.Response{}:创建了一个 api.Response 类型的实例,并取其地址(返回一个指针)。
Message: req.Message:将 req 参数中的 Message 字段值赋给新创建的 Response 实例的 Message 字段。这是一个简单的回显服务,即客户端发送一个消息,服务端原样返回这个消息。
package mainimport ("context"api "exampleKitex/kitex_gen/api"
)// EchoImpl implements the last service interface defined in the IDL.
type EchoImpl struct{}// Echo implements the EchoImpl interface.
func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {// TODO: Your code here...return &api.Response{Message: req.Message}, nil
}
然后我们来启动main.go和handler.go. 启动之后会默认在监听端口进行对应的监听。
然后我们新建一个客户端,并且写入对应的客户端代码。
package mainimport ("context""github.com/cloudwego/kitex/client/callopt""log""exampleKitex/kitex_gen/api""exampleKitex/kitex_gen/api/echo""time"
)import "github.com/cloudwego/kitex/client"func main() {//下面的destService对应服务名称是我们在启动kitex代码生成工具命令中的service名称// kitex -moudle exampleKitex -service exampleKitex(服务名称) echo.thriftc, err := echo.NewClient("exampleKitex", client.WithHostPorts("0.0.0.0:8888"))if err != nil {log.Fatal(err)}req := &api.Request{Message: "my request"}resp, err := c.Echo(context.Background(), req, callopt.WithRPCTimeout(3*time.Second))if err != nil {log.Fatal(err)}log.Println(resp)
}
然后运行客户端,新开一个终端,输入命令go run .\client.go
即可。
然后可以看到返回的Response如下:
所以总结一下,就是,先在echo.thrift
中编写接口,定义发送什么样的请求,请求里边有什么样的一个信息,然后就是继续定义一个响应,以及服务的逻辑。
三、IDL
IDL(Interface Definition Language,接口定义语言)是一种用于定义软件组件之间交互接口的规范语言。它允许开发者以一种语言无关的方式描述服务接口、数据结构和通信协议,从而实现不同编程语言之间的互操作性。IDL 的核心目的是提供一种标准化的方式来定义服务的接口和数据结构,使得这些接口和数据结构可以在多种编程语言中被实现和使用。
IDL就是我们刚刚定义的这个thrift文件。
如果进行PRC,那么就需要知道对方的接口是什么,需要传什么参数,也需要知道返回值是什么样子的。这个时候就需要通过IDL来约定双方的协议。就像调用某个函数,需要知道函数签名一样。
定义好thrift文件之后,就可以使用命令生成代码了。
kitex -module example -service example echo.thrift
生成代码。
服务是默认监听8888端口的。
四、服务注册与发现
目前Kitex的服务注册与发现已经对接了主流的服务注册与发现中心,如ETCD、Nacos、zookeeper、Eureka等。
接下来我们进行一个简单的实战。
首先我们下载etcd:https://github.com/etcd-io/etcd/releases
,找到对应的电脑的版本。
下载好之后找个文件夹进行解压缩,然后打开,双击打开即可。
运行起来之后可以看到对应的2380和2379两个端口。
到这一步,服务器已经启用成功了。
接下来我们需要把服务注册到etcd注册中心去
。修改handler.go
的相关代码。
简单说明下作用:实现一个 Kitex 服务端程序,通过 ETCD 注册中心将自身注册为一个可发现的服务,并提供了一个简单的 Echo 方法。程序的主要功能包括:
package mainimport ("context"api "exampleKitex/kitex_gen/api""exampleKitex/kitex_gen/api/echo""github.com/cloudwego/kitex/pkg/rpcinfo""github.com/cloudwego/kitex/server"etcd "github.com/kitex-contrib/registry-etcd""log"
)// EchoImpl implements the last service interface defined in the IDL.EchoImpl:定义了一个结构体,用于实现服务接口。
type EchoImpl struct{}// Echo implements the EchoImpl interface.
// ctx context.Context:上下文对象,用于传递超时和取消信号。
// req *api.Request:请求对象,包含客户端发送的数据。
func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {// TODO: Your code here...return &api.Response{Message: req.Message}, nil}func main() {//etcd.NewEtcdRegistry:创建一个 ETCD 注册中心实例。//参数 []string{"127.0.0.1:2379"} 指定了 ETCD 服务的地址。r, err := etcd.NewEtcdRegistry([]string{"127.0.0.1:2379"})if err != nil {log.Fatal(err)}//echo.NewServer:创建一个服务实例。//new(EchoImpl):创建一个 EchoImpl 实例,作为服务的具体实现。//server.WithRegistry(r):指定使用 ETCD 注册中心实例 r,将服务注册到 ETCD 中。//server.WithServerBasicInfo:设置服务的基本信息,例如服务名称。ServiceName: "Hello":将服务名称设置为 "Hello",客户端可以通过这个名称找到服务。server := echo.NewServer(new(EchoImpl), server.WithRegistry(r), server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "Hello",}))err = server.Run()if err != nil {log.Fatal(err)}}
同时我们修改client.go
的代码如下:
一句话概括下作用,就是:使用 Kitex 框架的客户端程序,通过 ETCD 注册中心动态发现服务,并调用名为 Hello 的服务的 Echo 方法。代码的主要功能是定期发送请求到服务端,并打印响应结果。
package mainimport ("context""exampleKitex/kitex_gen/api""exampleKitex/kitex_gen/api/echo""github.com/cloudwego/kitex/client"etcd "github.com/kitex-contrib/registry-etcd""log""time"
)func main() {//etcd.NewEtcdResolver:创建一个 ETCD 解析器实例,用于从 ETCD 服务注册中心获取服务实例的地址。//参数 []string{"127.0.0.1:2379"} 指定了 ETCD 服务的地址。r, err := etcd.NewEtcdResolver([]string{"127.0.0.1:2379"})if err != nil {log.Fatal(err)}//echo.MustNewClient:创建一个服务客户端实例。//"Hello" 是服务名称,与服务端在 ETCD 中注册的名称一致。//client.WithResolver(r):指定使用 ETCD 解析器 r 来动态发现服务实例。这意味着客户端会从 ETCD 中获取服务实例的地址,而不是直接指定服务地址。client := echo.MustNewClient("Hello", client.WithResolver(r))//创建一个带有超时时间的上下文,超时时间为 3 秒。for {ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)//调用服务端的 Echo 方法,传递一个请求对象,其中 Message 字段为 "hello"。resp, err := client.Echo(ctx, &api.Request{Message: "hello"})cancel() //调用 cancel() 释放上下文资源。if err != nil {log.Fatal(err)}log.Println(resp)time.Sleep(time.Second)}
}
来捋顺一下步骤:
实现一个 Kitex 客户端程序,通过 ETCD 注册中心动态发现服务,并调用名为 Hello 的服务的 Echo 方法:
创建 ETCD 解析器实例,用于从 ETCD 注册中心获取服务实例的地址。然后创建服务客户端实例,指定使用 ETCD 解析器。并且在一个无限循环中,每隔 1 秒调用一次服务的 Echo 方法。打印服务端返回的响应。
这种设计适用于微服务架构,其中服务实例可能动态变化,通过 ETCD 注册中心可以实现服务发现和负载均衡。
通过命令 go run .\handler.go
来启动服务端,会将我们的服务注册到etcd里面去。
然后运行client,会看到如下的消息。
相关文章:
【字节青训营-7】:初探 Kitex 字节微服务框架(使用ETCD进行服务注册与发现)
本文目录 一、Kitex概述二、第一个Kitex应用三、IDL四、服务注册与发现 一、Kitex概述 长话短说,就是字节跳动内部的 Golang 微服务 RPC 框架,具有高性能、强可扩展的特点,在字节内部已广泛使用。 如果对微服务性能有要求,又希望…...
Docker技术相关学习三
一、Docker镜像仓库管理 1.docker仓库:用于存储和分发docker镜像的集中式存储库,开发者可以将自己创建的镜像推送到仓库中也可以从仓库中拉取所需要的镜像。 2.docker仓库: 公有仓库(docker hub):任何人都可…...
浏览器查询所有的存储信息,以及清除的语法
要在浏览器的控制台中查看所有的存储(例如 localStorage、sessionStorage 和 cookies),你可以使用浏览器开发者工具的 "Application" 标签页。以下是操作步骤: 1. 打开开发者工具 在 Chrome 或 Edge 浏览器中…...
生成式AI安全最佳实践 - 抵御OWASP Top 10攻击 (上)
今天小李哥将开启全新的技术分享系列,为大家介绍生成式AI的安全解决方案设计方法和最佳实践。近年来,生成式 AI 安全市场正迅速发展。据 IDC 预测,到 2025 年全球 AI 安全解决方案市场规模将突破 200 亿美元,年复合增长率超过 30%…...
mysql 学习8 函数,字符串函数,数值函数,日期函数,流程函数
函数 一 字符串函数 二 数值函数 三 日期函数 四 流程函数...
WSL2中安装的ubuntu搭建tftp服务器uboot通过tftp下载
Windows中安装wsl2,wsl2里安装ubuntu。 1. Wsl启动后 1)Windows下ip ipconfig 以太网适配器 vEthernet (WSL (Hyper-V firewall)): 连接特定的 DNS 后缀 . . . . . . . : IPv4 地址 . . . . . . . . . . . . : 172.19.32.1 子网掩码 . . . . . . . .…...
7.2.背包DP
背包DP 在C中,背包动态规划(Knapsack DP) 是解决资源分配类问题的核心算法范式,尤其在处理物品选择与容量限制的组合优化问题时表现优异。以下是针对不同背包类型的详细解析与代码实现: 一、背包DP问题分类 类型特点…...
芝法酱学习笔记(2.6)——flink-cdc监听mysql binlog并同步数据至elastic-search和更新redis缓存
一、需求背景 在有的项目中,尤其是进销存类的saas软件,一开始为了快速把产品做出来,并没有考虑缓存问题。而这类软件,有着复杂的业务逻辑。如果想在原先的代码中,添加redis缓存,改动面将非常大,…...
pandas习题 071:字典元素列表构造 DataFrame
(编码题)以下有一个列表嵌套字典 data,列表中的每个字典 fields 中的列表为每行数据的值,另有一个 col 为列名,利用这两个数据构造一个 DataFrame。 data = [{fields: [2024-10-07T21:22:01, USER-A, 21, 0,...
FFmpeg rtmp推流直播
文章目录 rtmp协议RTMP协议组成RTMP的握手过程RTMP流的创建RTMP消息格式Chunking(Message 分块) rtmp服务器搭建Nginx服务器配置Nginx服务器 librtmp库编译推流 rtmp协议 RTMP(Real Time Messaging Protocol)是由Adobe公司基于Flash Player播放器对应的…...
北京门头沟区房屋轮廓shp的arcgis数据建筑物轮廓无偏移坐标测评
在IT行业中,地理信息系统(GIS)是用于处理、分析和展示地理空间数据的重要工具,而ArcGIS则是GIS领域中的一款知名软件。本文将详细解析标题和描述中提及的知识点,并结合“门头沟区建筑物数据”这一标签,深入…...
Verilog基础(一):基础元素
verilog基础 我先说,看了肯定会忘,但是重要的是这个过程,我们知道了概念,知道了以后在哪里查询。语法都是术,通用的概念是术。所以如果你有相关的软件编程经验,那么其实开启这个学习之旅,你会感…...
Games104——游戏引擎Gameplay玩法系统:基础AI
这里写目录标题 寻路/导航系统NavigationWalkable AreaWaypoint NetworkGridNavigation Mesh(寻路网格)Sparse Voxel Octree Path FindingDijkstra Algorithm迪杰斯特拉算法A Star(A*算法) Path Smoothing Steering系统Crowd Simu…...
vue生命周期及其作用
vue生命周期及其作用 1. 生命周期总览 2. beforeCreate 我们在new Vue()时,初始化一个Vue空的实例对象,此时对象身上只有默认的声明周期函数和事件,此时data,methods都未被初始化 3. created 此时,已经完成数据观测࿰…...
数据分析师使用Kutools for Excel 插件
数据分析师使用Kutools for Excel 插件 Kutools for Excel 是一款功能强大的 Excel 插件,旨在提高 Excel 用户的工作效率,简化复杂的操作。它提供了超过 300 个增强功能,帮助用户快速完成数据管理、格式化、排序、分析等任务,特别…...
毫秒级响应的VoIP中的系统组合推荐
在高并发、低延迟、毫秒级响应的 VoIP 场景中,选择合适的操作系统组合至关重要。以下是针对 Ubuntu linux-lowlatency、CentOS Stream kernel-rt 和 Debian 自定义 PREEMPT_RT 的详细对比及推荐: 1. 系统组合对比 特性Ubuntu linux-lowlatencyCentO…...
unordered_map/set的哈希封装
【C笔记】unordered_map/set的哈希封装 🔥个人主页:大白的编程日记 🔥专栏:C笔记 文章目录 【C笔记】unordered_map/set的哈希封装前言一. 源码及框架分析二.迭代器三.operator[]四.使用哈希表封装unordered_map/set后言 前言 哈…...
表格标签的使用
一.表格标签 1.1表格标签的作用 用来显示和展示数据,不是用来布局页面的。 1.2表格的基本语法 <table> //用于定义表格标签 <tr> // table row 用于定义表格中的行,必须嵌套在<table> </table>标签中 <td>单元格内的文…...
python算法和数据结构刷题[5]:动态规划
动态规划(Dynamic Programming, DP)是一种算法思想,用于解决具有最优子结构的问题。它通过将大问题分解为小问题,并找到这些小问题的最优解,从而得到整个问题的最优解。动态规划与分治法相似,但区别在于动态…...
【cocos creator】【模拟经营】餐厅经营demo
下载:【cocos creator】模拟经营餐厅经营...
编程AI深度实战:给vim装上AI
系列文章: 编程AI深度实战:私有模型deep seek r1,必会ollama-CSDN博客 编程AI深度实战:自己的AI,必会LangChain-CSDN博客 编程AI深度实战:给vim装上AI-CSDN博客 编程AI深度实战:火的编程AI&…...
信息学奥赛一本通 2088:【22CSPJ普及组】逻辑表达式(expr) | 洛谷 P8815 [CSP-J 2022] 逻辑表达式
【题目链接】 ybt 2088:【22CSPJ普及组】逻辑表达式(expr) 洛谷 P8815 [CSP-J 2022] 逻辑表达式 【题目考点】 1. 表达式树:中缀表达式建树 可以看该问题信息学奥赛一本通 1356:计算(calc) 了解中缀表达式建树过程。 【解题思路】 解法…...
Linux系统管理
文章目录 一、进程与服务二、systemctl基本语法操作 三、系统运行级别Linux进程运行级别查看当前运行级别修改当前运行级别 四、关机重启命令 一、进程与服务 守护进程与服务是一个东西。 二、systemctl 基本语法 systemctl start|stop|restart|status 服务名查看服务的方法…...
CTFSHOW-WEB入门-命令执行71-77
题目:web 71 题目:解题思路:分析可知highlight_file() 函数被禁了,先想办法看看根目录:cvar_export(scandir(dirname(‘/’))); 尝试一下发现很惊奇:(全是?)这种情况我也…...
[MRCTF2020]Ez_bypass1(md5绕过)
[MRCTF2020]Ez_bypass1(md5绕过) 这道题就是要绕过md5强类型比较,但是本身又不相等: md5无法处理数组,如果传入的是数组进行md5加密,会直接放回NULL,两个NuLL相比较会等于true; 所以?id[]1&gg…...
PPT演示设置:插入音频同步切换播放时长计算
PPT中插入音频&同步切换&放时长计算 一、 插入音频及音频设置二、设置页面切换和音频同步三、播放时长计算四、使用宏设置设置页面切换和音频同步一、 插入音频及音频设置 1.插入音频:点击菜单栏插入-音频-选择PC上的音频(已存在的音频)或者录制音频(现场录制) …...
Modbus Slave RTU 在 AVP28335(兼容德州仪器TMS 320 28335) 上实现含源码及注释。
今天先把题目先给出来, 在近两天会把源码 (含详细注释 )及部署、测试结果给出来, 希望能给大家帮助。(原来这个程序在CSDN中,有小伙伴已经写了一些,但是发现里面埋了很多坑,例如&…...
git-secret 使用教程
以下是一份详细的 git-secret 使用教程,包含常见场景的 Bash 代码示例: 1. 安装 git-secret # Ubuntu/Debian sudo apt-get install git-secret# macOS (Homebrew) brew install git-secret# 其他 Linux (Snap) sudo snap install git-secret# 验证安装…...
防火墙安全策略
目录 一.拓扑及需求 二.需求分析 三.配置详细信息 防火墙: OA server: Web Server: PC1: 编辑PC2: PC3: 配置安全区域: 交换机: 四.需求实现以及测试: 1.…...
蓝桥杯python基础算法(2-2)——基础算法(D)——进制转换*
目录 五、进制转换 十进制转任意进制,任意进制转十进制 例题 P1230 进制转换 作业 P2095 进制转化 作业 P2489 进制 五、进制转换 十进制转任意进制,任意进制转十进制 int_to_char "0123456789ABCDEF" def Ten_to_K(k, x):answer "…...
VSCode源码分析参考资料
VSCode Architecture Analysis - Electron Project Cross-Platform Best Practices 中文版 VSCode 架构分析 - Electron 项目跨平台最佳实践 Sihan Li博客上的vscode源码分析系列:分析了微服务架构、事件体系、资源管理、配置系统等 文召博客上的vscode 源码解析…...
深入理解 Rust 模块中的路径与公开性:绝对路径、相对路径和 `pub` 的应用
1. 路径的两种形式:绝对路径与相对路径 在 Rust 中,路径类似于文件系统中的目录路径,用来告诉编译器去哪里查找某个项。路径主要有两种形式: 绝对路径 绝对路径从 crate 的根开始。对于当前 crate 的代码,绝对路径以关…...
DeepSeek R1 大模型本地部署指南
以下是部署DeepSeek R1大模型的详细Markdown指南,可直接保存为.md文件并分享: # DeepSeek R1 大模型本地部署指南**适用系统**:Windows 10/11 & Linux (Ubuntu 20.04)---## 目录 1. [硬件要求](#硬件要求) 2. [准备工作](#准备工作) 3. […...
从Proxmox VE开始:安装与配置指南
前言 Proxmox Virtual Environment (Proxmox VE) 是一个开源的虚拟化平台,基于Debian Linux,支持KVM虚拟机和LXC容器。它提供了一个强大的Web管理界面,方便用户管理虚拟机、存储、网络等资源。Proxmox VE广泛应用于企业级虚拟化、云计算和开…...
Docker 安装详细教程(适用于CentOS 7 系统)
目录 步骤如下: 1. 卸载旧版 Docker 2. 配置 Docker 的 YUM 仓库 3. 安装 Docker 4. 启动 Docker 并验证安装 5. 配置 Docker 镜像加速 总结 前言 Docker 分为 CE 和 EE 两大版本。CE即社区版(免费,支持周期7个月)…...
前端 | 浅拷贝深拷贝
在前端开发中,我们经常需要复制对象或数组,但不同的复制方式可能会影响数据的完整性和应用的稳定性。本文将深入探讨浅拷贝(Shallow Copy)和深拷贝(Deep Copy)的区别、实现方式及适用场景。 1. 浅拷贝 1.…...
巧用 Cursor+Coze,轻松简化小程序开发
一、为啥要用 Cursor+Coze 简化小程序开发 家人们,如今小程序简直火出圈啦!不管你是电商从业者,还是服务行业的工作者,又或是自媒体运营者,拥有一个小程序,就相当于给业务插上了腾飞的翅膀,能带来更多的流量和机会。但是,小程序开发的过程,那可真是充满了挑战。从最开…...
Spring Boot常用注解深度解析:从入门到精通
今天,这篇文章带你将深入理解Spring Boot中30常用注解,通过代码示例和关系图,帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解: SpringBootApplication Confi…...
解决Mac安装软件的“已损坏,无法打开。 您应该将它移到废纸篓”问题
mac安装软件时,如果出现这个问题,其实很简单 首先打开终端,输入下面的命令 sudo xattr -r -d com.apple.quarantine 输入完成后,先不要回车,点击访达--应用程序--找到你无法打开的app图标,拖到终端窗口中…...
爱普生L3153打印机无线连接配置流程
家里使用的是移动宽带中兴路由器,有WPS功能,进入192.168.1.1管理员页面,用户名user,密码在路由器背面(可以登录后修改密码)。在网络-WLAN网络配置-WPS中,点击push button,激活路由器…...
第二十章 存储函数
目录 一、概述 二、语法 三、示例 一、概述 前面章节中,我们详细讲解了MySQL中的存储过程,掌握了存储过程之后,学习存储函数则肥仓简单,存储函数其实是一种特殊的存储过程,也就是有返回值的存储过程。存储函数的参数…...
pytorch实现门控循环单元 (GRU)
人工智能例子汇总:AI常见的算法和例子-CSDN博客 特性GRULSTM计算效率更快,参数更少相对较慢,参数更多结构复杂度只有两个门(更新门和重置门)三个门(输入门、遗忘门、输出门)处理长时依赖一般适…...
unity报错不存在类型或者命名空间
导入资源或者打开项目时,突然发现多了一堆报错,如 Assets\2DGamekit\Utilities\DefaultPlayables\ScreenFader\ScreenFaderBehaviour.cs(5,19): error CS0234: The type or namespace name UI does not exist in the namespace UnityEngine (are you mi…...
Qt展厅播放器/多媒体播放器/中控播放器/帧同步播放器/硬解播放器/监控播放器
一、前言说明 音视频开发除了应用在安防监控、视频网站、各种流媒体app开发之外,还有一个小众的市场,那就是多媒体展厅场景,这个场景目前处于垄断地位的软件是HirenderS3,做的非常早而且非常全面,都是通用的需求&…...
Spring Bean 的生命周期介绍
Spring Bean 的生命周期涉及多个阶段,从实例化到销毁,在开发中我们可以通过各种接口和注解介入这些阶段来定制化自己的功能。以下是详细的生命周期流程: 1. Bean 的实例化(Instantiation) 方式:通过构造函…...
奥卡姆剃刀原理:用简单的力量,解锁复杂的世界
奥卡姆剃刀原理 大名鼎鼎的奥卡姆剃刀原理(Occam’s Razor),其含义很简单,就一句话:“如无必要,勿增实体”。 这句看似简单却蕴含着深刻智慧的话,是由14世纪的英格兰逻辑学家、圣方济各会修士…...
STM32 串口发送与接收
接线图 代码配置 根据上一章发送的代码配置,在GPIO配置的基础上需要再配置PA10引脚做RX接收,引脚模式可以选择浮空输入或者上拉输入,在USART配置串口模式里加上RX模式。 配置中断 //配置中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE…...
如何生成强密码:提高网络安全性的全面指南
引言 在数字化时代,密码的安全性至关重要。随着我们在社交媒体、电子邮件、在线银行等平台上储存越来越多的个人信息,强密码的使用变得更加关键。强密码能有效防止暴力破解、字典攻击等安全威胁。因此,在本文中,我们将深入探讨如…...
如何不更新application.yml而更新spring的配置
更改应用程序外部属性的位置 默认情况下,来自不同来源的属性会按定义的顺序添加到 Spring 中(有关确切顺序,请参阅“Spring Boot 功能”部分中的“外部化配置”)。Environment 您还可以提供以下系统属性(或环境变量&…...
【Unity踩坑】Unity项目管理员权限问题(Unity is running as administrator )
问题描述: 使用Unity Hub打开或新建项目时会有下面的提示。 解决方法: 打开“本地安全策略”: 在Windows搜索栏中输入secpol.msc并回车,或者从“运行”对话框(Win R,然后输入secpol.msc)启…...