【Go研究】Go语言脚本化的可行性——yaegi项目体验

0x01 背景——云计算中脚本化困境

作为云基础设施管理中,大量需要跟文件系统、容器等相关的操作,这些操作实现通常用脚本来实现。
现在探讨下,这些脚本为什么一定要用脚本语言来实现,以及目前实现中的常见的问题。

常见的两个场景:安装与升级。
安装过程的特点是,涉及大量的文件拷贝、服务启停、配置文件更新。升级的过程也类似,升级过程还要考虑热升级过程中对业务的影响,相对更加复杂。

另外一个特点是对内的,这两种运维性质的操作是一种通用的机制类活动,所有参与到一个产品中的团队和服务都要考虑,但各种业务服务可能有不同的操作,所以要求这种机制具备足够的扩展性和灵活性。

所以这种特点要求此类活动,有通用机制+扩展插件组成。通用机制有专门的团队提供和维护,扩展性插件由各业务自己负责。

而扩展性的插件可以如下的实现方式:

  1. 直接使用脚本,也是目前大规模使用的。
  2. 使用某种DSL实现。
  3. 使用二进制,即各业务提供自己的二进制,由框架在合适的时机调用。

先分析下第3种的问题。第3种一般来说没什么可挑剔的。但对使用的语言的要求,要求它足够高效率,而且容易移植到其他的Linux环境中。如果放在云环境下,似乎很难找到合适的。大家一开始想到的就是Go语言,但Go编译后的二进制体积过大。升级又通常要求多个版本共存,对存储有很大的压力,直接使用Go语言有点尴尬。

使用脚本呢?目前在用的,但也有一些问题。最常用的脚本语言是Bash Shell,这种语言少量的代码还可以维护,代码量大了之后,就会遇到很问题。

  1. 语法过于灵活,跟常用的Go这种语言相比,上手容易,写出稳健的代码比较难。
  2. 坑很多。即使用了shellcheck工具,也很难发现所有问题。
  3. 处理yaml/json/ini这种配置文件比较麻烦,需要借助jq/yq这种工具。

那么自然想到使用Python语言。但Python也有自己的问题。

  1. pypi上的软件包需要rpm化,才能统一管理,依赖某个库,就要先把库打到整包中才能使用,打包比较繁琐。
  2. rpm包容易产生依赖地狱,可能与OS强相关的一些库冲突。

假如能将Go直接作为一种脚本执行,是不是就可以完美解决其他脚本语言的问题了呢。
一种直接的想法,是将Go直接集成到运行环境中,go run就可以了,但go run有一个编译过程,有时候很慢,这点生产环境下肯定不行。

0x02 Go 脚本化的可能性

从社区中了解到了https://github.com/traefik/yaegi这个项目。基本的使用方法可以从官方文档中看到,不用额外的实验也知道初步看是具备以下能力:

  1. 可以直接解释执行一个只引用了标准库的.go文件。
  2. 也可以作为module引用到一个项目中,动态解释了执行Go语句。

先不说项目本身的稳定性,但距离一个真正可用的脚本化语言还有以下疑问:

  1. 能否快捷的引用其他的第三方库,比如yaml的读写。
  2. 能否建立一个定制化的公共库,如日志、事务等。

它是通过如下方式引用的引用标准库:

  1. 将所有标准库的代码中导出的函数整理在了stdlib目录下。
  2. 然后将通过Symbols map保存这些导出函数、类型的反射对象。
func init() {Symbols["runtime/runtime"] = map[string]reflect.Value{// function, constant and variable definitions"BlockProfile":            reflect.ValueOf(runtime.BlockProfile),...}
}

不难猜出,它是通过这样的方式实现脚本中的动态调用标准库函数。

先来实验下yaml读写。demo示例见https://github.com/go-yaml/yaml/tree/v3,由于提前看了下yaegi的实验,看起来它是支持加载其他库的,只要它能在GOPATH下找到这些源码。

将readme中的demo保存下,直接使用yaegi运行。

run: demo.go:7:2: import "gopkg.in/yaml.v3" error: package location /mnt/data/code/lean/go not in GOPATH

直接报了错。

按照要求的路径,将yaml.v3 git clone到指定的路径 $GOPATH/src/gopkg.in/yaml.v3下,再次运行,成功了,跟直接使用go运行它没区别。

$ yaegi run demo.go
--- t:
{Easy {2 [3 4]}}...

同时也尝试了将go可执行文件重命名,unset掉GOROOT,也能正常地运行这个demo.go文件,说明真的可以完全无go工具链执行.go文件了。

0x03 初步的分析结论

yaegi的能力非常强大,可以满足基本的脚本化要求。而且可以引入第3方库,当然前提是这些三方库没有过于复杂的依赖关系。有了这样基本的能力,其他的规范化的日志、文件事务这些都不是问题。

当然考虑实际工程化的需求,yaegi还有一些可优化和不确定的地方:

  1. 支持将那些三方库预编译到yaegi中。yaegi本身就具备的能力,稍微扩展下就行了。
  2. 能支持指定多个源码文件,执行其中的main函数。这个不支持问题也不大,强制使用方把其他依赖的放到GOPATH下就行了。
  3. 不确定复杂一些的脚本在运行的时候解析过程是否耗时较长。

yaegi本身的稳定性应该不错,大概看了下,基本上利用Go本身的ast解析能力,主要部分是实现了一个interpeter,具体的分析还结合实现和项目的issue进行分析。

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

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

相关文章

基于氢氧燃料电池的分布式三相电力系统Simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于氢氧燃料电池的分布式三相电力系统Simulink建模与仿真,仿真输出燃料电池中氢氧元素含量变化以及生成的H2O变化情况。 2.系统仿真结果 3.核心程序与模型 版本…

3218. 切蛋糕的最小总开销 I

3218. 切蛋糕的最小总开销 I 题目链接&#xff1a;3218. 切蛋糕的最小总开销 I 代码如下&#xff1a; class Solution { public:int minimumCost(int m, int n, vector<int>& horizontalCut, vector<int>& verticalCut){ranges::sort(horizontalCut);ra…

洛谷 P3205 [HNOI2010] 合唱队

思路 先设 d p [ i ] [ j ] dp[i][j] dp[i][j] 为区间 [ i , j ] [i, j] [i,j] 的队形方案数。 考虑如何转移&#xff1a;对于区间 [ i , j ] [i, j] [i,j] 来说&#xff0c;最后一个入队的要么是 i i i&#xff0c;要么是 j j j。 所以分类讨论&#xff1a; 当 j j j …

UE5.3 虚幻引擎 Windows插件开发打包(带源码插件打包、无源码插件打包)

0 引言 随着项目体量的增大&#xff0c;所有代码功能都放一起很难管理。所以有什么办法可以将大模块划分成一个个小模块吗。当然有&#xff0c;因为虚幻引擎本身就遇到过这个问题&#xff0c;他的解决办法就是使用插件的形式开发。 例如&#xff0c;一个团队开发了文件I/O模块插…

MySQL 的事务与多版本并发控制(MVCC)的那些事

什么是事务原子性:一致性隔离性 问题1: 为什么MySQL要使用mvcc实现隔离性而不使用 锁 解决并发问题?持久性 问题2: MySQL 不是磁盘数据库吗,持久化为什么是 redo log 保证的?问题 3: redo log 储存了什么东西,持久化(崩溃恢复是怎么做的?)问题 4 : MySQL 的 bing log (二进制…

27.Java 线程间通信(synchronized 实现线程间通信、Lock 实现线程间通信)

一、线程间通信 1、概述 线程间通信的模型有两种&#xff1a;共享内存和消息传递 2、多线程编程步骤&#xff08;中&#xff09; 创建资源类&#xff0c;在资源类中创建属性和操作方法 在资源类操作方法进行判断、操作、通知 创建多个线程&#xff0c;调用资源类中的操作方…

多模态论文笔记——U-ViT

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍U-ViT的模型架构和实验细节&#xff0c;虽然没有后续的DiT在AIGC领域火爆&#xff0c;但为后来的研究奠定了基础&#xff0c;但其开创性的探索值得学习…

SpringBoot的6种API请求参数读取方式

RequestParam 用来加载URL中?之后的参数 比如: 这个请求/user?namedidspace 就可以如下面这样&#xff0c;使用RequestParam 来加载URL 中的name 参数 GetMapping("/user") ResponseBody() public User findUserByName(RequestParam("name") String n…

node.js内置模块之---http 和 https 模块

http 和 https 模块的作用 在 Node.js 中&#xff0c;http 和 https 模块用于创建和处理 HTTP 和 HTTPS 请求/响应 http模块 http 模块提供了用于实现 HTTP 协议的功能。它可以用来创建 HTTP 服务器&#xff0c;处理 HTTP 请求&#xff0c;发送 HTTP 响应&#xff0c;同时也可以…

Image和Video在同一个Dataloader中交错加载联合训练

单卡实现 本文主要从两个方面进行展开&#xff1a; &#xff11;&#xff0e;将两个或多个dataset组合成pytorch中的一个ConcatDataset&#xff0e;这个dataset将会作为pytorch中Dataloader的输入。 &#xff12;&#xff0e;覆盖重写RandomSampler修改batch产生过程&#xff…

rpm包详解

一、rpm包 1、过滤系统rpm包&#xff0c;查询已安装的包 rpm -qa | grep htop2、rpm包导出 yumdownnloader htop-2.2.0.33、查看rpm包信息 rpm -qi 包名二、rpm包列表 1、查看软件包列表 yum list available *docker*2、查看软件包依赖 # rpl仓库 yum install epel-rel…

【Adobe Acrobat PDF】Acrobat failed to connect to a DDE server.是怎么回事?

【Adobe Acrobat PDF】Acrobat failed to connect to a DDE server.是怎么回事&#xff1f; 【Adobe Acrobat PDF】Acrobat failed to connect to a DDE server.是怎么回事&#xff1f; 文章目录 【Adobe Acrobat PDF】Acrobat failed to connect to a DDE server.是怎么回事&…

Rabbitmq 业务异常与未手动确认场景及解决方案

消费端消费异常&#xff0c;业务异常 与 未手动确认是不是一个场景&#xff0c;因为执行完业务逻辑&#xff0c;再确认。解决方案就一个&#xff0c;就是重试一定次数&#xff0c;然后加入死信队列。还有就是消费重新放入队列&#xff0c;然后重新投递给其他消费者&#xff0c;…

每日一题 380. O(1) 时间插入、删除和获取随机元素

380. O(1) 时间插入、删除和获取随机元素 最复杂的部分最简单来思考&#xff0c;其他的部分来弥补 class RandomizedSet { public:vector<int> nums;unordered_map<int,int> mp;RandomizedSet() {}bool insert(int val) {if(mp.count(val)){return false;}else{m…

MongoDB-文章目录

MongoDB学习总结1&#xff08;服务安装&#xff09; MongoDB学习总结2&#xff08;常用命令&#xff09; MongoDB学习总结3&#xff08;js文件中写命令&#xff09; MongoDB学习总结4&#xff08;数据插入、修改&#xff09; MongoDB学习总结5&#xff08;数据查询1&#x…

HBase Cassandra的部署和操作

目录 一&#xff0e;数据库的部署与配置 二&#xff0e;使用命令访问数据库 三&#xff0e;数据库的设计 四&#xff0e;编程实现数据库的访问 一&#xff0e;数据库的部署与配置 1.在单个节点上对进行数据库的单机部署 &#xff08;1&#xff09;下载apache-cassandra-4.1.7-…

springboot实战纪实-课程介绍

教程介绍 Spring Boot是由Pivotal团队提供的一套开源框架&#xff0c;可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持&#xff0c;可以帮助开发者更轻松快捷地构建出企业级应用。 Spring Boot通过自动配置功能&#xff0c;降低了复杂性&#xff0c;同时支持…

BBP飞控板中的坐标系变换

一般飞控板中至少存在以下坐标系&#xff1a; 陀螺Gyro坐标系加速度计Acc坐标系磁强计Mag坐标系飞控板坐标系 在BBP飞控板采用的IMU为同时包含了陀螺&#xff08;Gyro&#xff09;及加速度计&#xff08;Acc&#xff09;的6轴传感器&#xff0c;故Gyro及Acc为同一坐标系。同时…

数据表中的索引详解

文章目录 一、索引概述二、普通索引三、唯一索引四、全文索引五、多列索引六、索引的设计原则七、隐藏和删除索引 一、索引概述 日常生活中&#xff0c;我们经常会在电话号码簿中查阅“某人”的电话号码&#xff0c;按姓查询或者按字母排序查询&#xff1b;在字典中查阅“某个…

大模型系列17-RAGFlow搭建本地知识库

大模型系列17-RAGFlow搭建本地知识库 安装ollama安装open-wehui安装并运行ragflowRAG&#xff08;检索、增强、生成&#xff09;RAG是什么RAG三过程RAG问答系统构建步骤向量库构建检索模块生成模块 RAG解决LLM的痛点 使用ragflow访问ragflow配置ollama模型添加Embedding模型添加…